diff options
| author | Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com> | 2024-04-08 01:26:29 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com> | 2024-04-08 01:26:29 +0200 |
| commit | 5cf92b502d4d2bd026f580dc93ba243f657b0e79 (patch) | |
| tree | ae3afbfb1c4626b1f1e7d14a3658976f47d54c41 | |
| parent | 6300c08cc3677bfca7e23077f634d986ed3658c1 (diff) | |
PowerPC: Add support for li, improving code...
Signed-off-by: Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>
| -rw-r--r-- | .vscode/c_cpp_properties.json | 2 | ||||
| -rw-r--r-- | Examples/ExamplePowerPC.S.pp | 7 | ||||
| -rw-r--r-- | Sources/Detail/Readme.md | 2 | ||||
| -rw-r--r-- | Sources/Detail/asmutils.h | 86 | ||||
| -rw-r--r-- | Sources/Old/Readme.md | 3 | ||||
| -rw-r--r-- | Sources/coff2ae.cc | 19 | ||||
| -rw-r--r-- | Sources/ppcasm.cc | 205 | ||||
| -rw-r--r-- | makefile | 2 |
8 files changed, 144 insertions, 182 deletions
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 113e2dc..8059633 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -4,6 +4,7 @@ "name": "Macintosh (CLang)", "includePath": [ "${workspaceFolder}/Headers/**", + "${workspaceFolder}/Sources/Detail/**", "${workspaceFolder}/**" ], "defines": [], @@ -16,6 +17,7 @@ "name": "Windows (Cygwin)", "includePath": [ "${workspaceFolder}/Headers/**", + "${workspaceFolder}/Sources/Detail/**", "${workspaceFolder}/**" ], "defines": [], diff --git a/Examples/ExamplePowerPC.S.pp b/Examples/ExamplePowerPC.S.pp index 04feb81..bc4d6a1 100644 --- a/Examples/ExamplePowerPC.S.pp +++ b/Examples/ExamplePowerPC.S.pp @@ -1,8 +1,5 @@ -# Path: SDK/PowerPC.inc +# Path: Examples/ExamplePowerPC.S.pp # Language: PowerPC Assembly # Build Date: 2024-6-4 - -mr r1, r31 -mr r1, r20 -sc
\ No newline at end of file +li r2, 0x1055
\ No newline at end of file diff --git a/Sources/Detail/Readme.md b/Sources/Detail/Readme.md new file mode 100644 index 0000000..aba110f --- /dev/null +++ b/Sources/Detail/Readme.md @@ -0,0 +1,2 @@ +# Compiler utilities. + diff --git a/Sources/Detail/asmutils.h b/Sources/Detail/asmutils.h new file mode 100644 index 0000000..06209a5 --- /dev/null +++ b/Sources/Detail/asmutils.h @@ -0,0 +1,86 @@ +#pragma once + +using namespace CompilerKit; + +/// @brief Get Number from line. +/// @param line +/// @param name +/// @return +static NumberCast32 GetNumber32(std::string line, std::string name) { + auto pos = line.find(name) + name.size(); + + if (line.find(",") != std::string::npos) line.erase(line.find(","), 1); + + while (line[pos] == ' ') ++pos; + + switch (line[pos + 1]) { + case 'x': { + if (auto res = strtol(line.substr(pos).c_str(), nullptr, 16); !res) { + if (errno != 0) { + detail::print_error("invalid hex number: " + line, "ppcasm"); + throw std::runtime_error("invalid_hex"); + } + } + + NumberCast32 numOffset(strtol(line.substr(pos).c_str(), nullptr, 16)); + + if (kVerbose) { + kStdOut << "ppcasm: found a base 16 number here:" << line.substr(pos) + << "\n"; + } + + return numOffset; + } + case 'b': { + if (auto res = strtol(line.substr(pos).c_str(), nullptr, 2); !res) { + if (errno != 0) { + detail::print_error("invalid binary number:" + line, "ppcasm"); + throw std::runtime_error("invalid_bin"); + } + } + + NumberCast32 numOffset(strtol(line.substr(pos).c_str(), nullptr, 2)); + + if (kVerbose) { + kStdOut << "ppcasm: found a base 2 number here:" << line.substr(pos) + << "\n"; + } + + return numOffset; + } + case 'o': { + if (auto res = strtol(line.substr(pos).c_str(), nullptr, 7); !res) { + if (errno != 0) { + detail::print_error("invalid octal number: " + line, "ppcasm"); + throw std::runtime_error("invalid_octal"); + } + } + + NumberCast32 numOffset(strtol(line.substr(pos).c_str(), nullptr, 7)); + + if (kVerbose) { + kStdOut << "ppcasm: found a base 8 number here:" << line.substr(pos) + << "\n"; + } + + return numOffset; + } + default: { + if (auto res = strtol(line.substr(pos).c_str(), nullptr, 10); !res) { + if (errno != 0) { + detail::print_error("invalid hex number: " + line, "ppcasm"); + throw std::runtime_error("invalid_hex"); + } + } + + NumberCast32 numOffset(strtol(line.substr(pos).c_str(), nullptr, 10)); + + if (kVerbose) { + kStdOut << "ppcasm: found a base 10 number here:" << line.substr(pos) + << "\n"; + } + + return numOffset; + } + } +}
\ No newline at end of file diff --git a/Sources/Old/Readme.md b/Sources/Old/Readme.md deleted file mode 100644 index f7773cc..0000000 --- a/Sources/Old/Readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# Old modules - -This directory contains old modules excluded from build. diff --git a/Sources/coff2ae.cc b/Sources/coff2ae.cc index ab9b265..1021fed 100644 --- a/Sources/coff2ae.cc +++ b/Sources/coff2ae.cc @@ -2,4 +2,21 @@ Copyright Mahrouss Logic -------------------------------------------- */
\ No newline at end of file +------------------------------------------- */ + +#include <Headers/ParserKit.hpp> +#include <Headers/StdKit/AE.hpp> +#include <Headers/StdKit/PEF.hpp> +#include <filesystem> +#include <fstream> +#include <iostream> +#include <memory> +#include <vector> + +///////////////////////////////////////////////////////////////////////////////////////// + +/// @brief COFF 2 AE entrypoint, the program/module starts here. + +///////////////////////////////////////////////////////////////////////////////////////// + +MPCC_MODULE(NewOSCOFFToAE) { return 0; }
\ No newline at end of file diff --git a/Sources/ppcasm.cc b/Sources/ppcasm.cc index 4b4ef47..45e407e 100644 --- a/Sources/ppcasm.cc +++ b/Sources/ppcasm.cc @@ -97,9 +97,12 @@ void print_warning(std::string reason, const std::string &file) noexcept { } } // namespace detail +/// Do not move it on top! it uses the assembler detail namespace! +#include <asmutils.h> + ///////////////////////////////////////////////////////////////////////////////////////// -// @brief PowerPC assembler entrypoint, the program/module starts here. +/// @brief PowerPC assembler entrypoint, the program/module starts here. ///////////////////////////////////////////////////////////////////////////////////////// @@ -653,7 +656,7 @@ bool CompilerKit::EncoderPowerPC::WriteNumber(const std::size_t &pos, ///////////////////////////////////////////////////////////////////////////////////////// -// @brief Read and write an instruction to the output array. +/// @brief Read and write an instruction to the output array. ///////////////////////////////////////////////////////////////////////////////////////// @@ -700,8 +703,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, << line.substr(pos) << "\n"; } - std::cout << numOffset.raw << std::endl; - kBytes.emplace_back(numOffset.number[0]); kBytes.emplace_back(numOffset.number[1]); kBytes.emplace_back(numOffset.number[2]); @@ -727,8 +728,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, << line.substr(pos) << "\n"; } - std::cout << numOffset.raw << std::endl; - kBytes.emplace_back(numOffset.number[0]); kBytes.emplace_back(numOffset.number[1]); kBytes.emplace_back(numOffset.number[2]); @@ -754,8 +753,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, << line.substr(pos) << "\n"; } - std::cout << numOffset.raw << std::endl; - kBytes.emplace_back(numOffset.number[0]); kBytes.emplace_back(numOffset.number[1]); kBytes.emplace_back(numOffset.number[2]); @@ -791,6 +788,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, break; } + /// General purpose, float, vector operations. Everything that involve registers. case G0REG: case FREG: case VREG: @@ -800,7 +798,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, std::size_t register_count = 0UL; std::string opcodeName = opcodePPC.name; - NumberCast64 num(opcodePPC.opcode); for (size_t line_index = 0UL; line_index < line.size(); @@ -840,6 +837,33 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, throw std::runtime_error("invalid_register_index"); } + if (opcodeName == "li") { + char numIndex = 0; + + for (size_t i = 0; i != reg_index; i++) { + numIndex += 0x20; + } + + kBytes.push_back(0x38); + kBytes.push_back(numIndex); + + auto num = GetNumber32(line, reg_str); + + kBytes.push_back(num.number[0]); + kBytes.push_back(num.number[1]); + + // check if bigger than two. + for (size_t i = 2; i < 4; i++) { + if (num.number[i] > 0) { + detail::print_warning("number overflow on li operation.", + file); + break; + } + } + + break; + } + if (opcodeName == "mr") { switch (register_count) { case 0: { @@ -953,169 +977,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, } } - // try to fetch a number from the name - if (name.find("stw") != std::string::npos || - name.find("li") != std::string::npos) { - auto where_string = name; - - // if we load something, we'd need it's symbol/literal - // @note: Something may jump on it, dont remove that if. - if (name.find("stw") != std::string::npos || - name.find("li") != std::string::npos) - where_string = ","; - - jump_label = line; - - auto found_sym = false; - - while (jump_label.find(where_string) != std::string::npos) { - jump_label = jump_label.substr(jump_label.find(where_string) + - where_string.size()); - - while (jump_label.find(" ") != std::string::npos) { - jump_label.erase(jump_label.find(" "), 1); - } - - if (jump_label[0] != kAsmRegisterPrefix[0] && - !isdigit(jump_label[1])) { - if (found_sym) { - detail::print_error( - "invalid combination of opcode and operands.\nhere -> " + - jump_label, - file); - throw std::runtime_error("invalid_comb_op_ops"); - } else { - // death trap installed. - found_sym = true; - } - } - } - - cpy_jump_label = jump_label; - - // replace any spaces with $ - if (jump_label[0] == ' ') { - while (jump_label.find(' ') != std::string::npos) { - if (isalnum(jump_label[0]) || isdigit(jump_label[0])) break; - - jump_label.erase(jump_label.find(' '), 1); - } - } - - if (!this->WriteNumber(0, jump_label)) { - // stw expects this: stw 0x000000, r0 - if (name == "stw") { - detail::print_error( - "invalid combination of opcode and operands.\nHere ->" + line, - file); - throw std::runtime_error("invalid_comb_op_ops"); - } - } else { - if (name == "stw" && - cpy_jump_label.find("import ") != std::string::npos) { - detail::print_error("invalid usage import on 'stw', here: " + line, - file); - throw std::runtime_error("invalid_sta_usage"); - } - } - - goto asm_write_label; - } - - // This is the case where we jump to a label, it is also used as a goto. - if (name == "li" || name == "stw") { - asm_write_label: - if (cpy_jump_label.find('\n') != std::string::npos) - cpy_jump_label.erase(cpy_jump_label.find('\n'), 1); - - if (cpy_jump_label.find("import") != std::string::npos) { - cpy_jump_label.erase(cpy_jump_label.find("import"), strlen("import")); - - if (name == "stw") { - detail::print_error("import is not allowed on a stw operation.", - file); - throw std::runtime_error("import_sta_op"); - } else { - goto asm_end_label_cpy; - } - } - - if (name == "li" || name == "stw") { - for (auto &label : kOriginLabel) { - if (cpy_jump_label == label.first) { - if (kVerbose) { - kStdOut << "ppcasm: Replace label " << cpy_jump_label - << " to address: " << label.second << std::endl; - } - - CompilerKit::NumberCast64 num(label.second); - - for (auto &num : num.number) { - kBytes.push_back(num); - } - - goto asm_end_label_cpy; - } - } - - if (cpy_jump_label[0] == '0') { - switch (cpy_jump_label[1]) { - case 'x': - case 'o': - case 'b': - if (this->WriteNumber(0, cpy_jump_label)) - goto asm_end_label_cpy; - - break; - default: - break; - } - - if (isdigit(cpy_jump_label[0])) { - if (this->WriteNumber(0, cpy_jump_label)) goto asm_end_label_cpy; - - break; - } - } - } - - if (cpy_jump_label.size() < 1) { - detail::print_error("label is empty, can't jump on it.", file); - throw std::runtime_error("label_empty"); - } - - /// don't go any further if: - /// load word (li) or store word. (stw) - - if (name.find("li") != std::string::npos || - name.find("st") != std::string::npos) - break; - - auto mld_reloc_str = std::to_string(cpy_jump_label.size()); - mld_reloc_str += kUndefinedSymbol; - mld_reloc_str += cpy_jump_label; - - bool ignore_back_slash = false; - - for (auto &reloc_chr : mld_reloc_str) { - if (reloc_chr == '\\') { - ignore_back_slash = true; - continue; - } - - if (ignore_back_slash) { - ignore_back_slash = false; - continue; - } - - kBytes.push_back(reloc_chr); - } - - kBytes.push_back('\0'); - goto asm_end_label_cpy; - } - - asm_end_label_cpy: ++kOrigin; break; @@ -7,7 +7,7 @@ # ======================================================== # -COMMON_INC=-IHeaders -I./ +COMMON_INC=-I./Headers -I./ -I./Sources/Detail ifeq ($(shell uname), "Darwin") LINK_CC=g++ -std=c++20 |
