summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-08 01:26:29 +0200
committerAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-08 01:26:29 +0200
commit5cf92b502d4d2bd026f580dc93ba243f657b0e79 (patch)
treeae3afbfb1c4626b1f1e7d14a3658976f47d54c41
parent6300c08cc3677bfca7e23077f634d986ed3658c1 (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.json2
-rw-r--r--Examples/ExamplePowerPC.S.pp7
-rw-r--r--Sources/Detail/Readme.md2
-rw-r--r--Sources/Detail/asmutils.h86
-rw-r--r--Sources/Old/Readme.md3
-rw-r--r--Sources/coff2ae.cc19
-rw-r--r--Sources/ppcasm.cc205
-rw-r--r--makefile2
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;
diff --git a/makefile b/makefile
index 04d6ae1..e0d960c 100644
--- a/makefile
+++ b/makefile
@@ -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