summaryrefslogtreecommitdiffhomepage
path: root/Sources
diff options
context:
space:
mode:
authorAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-07 21:50:08 +0200
committerAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-07 21:50:08 +0200
commit6300c08cc3677bfca7e23077f634d986ed3658c1 (patch)
tree31f9aafd1e8f222124ad4d4d13c8e80893220fae /Sources
parent73656aff947dd09f6ca4f3b9be0d58e888dcba87 (diff)
PowerPC: Improve support of assembler, add Move register support and
XCOFF header, also changed mv to mr inside PowerPC C compiler. Signed-off-by: Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>
Diffstat (limited to 'Sources')
-rw-r--r--Sources/ppc-cc.cc6
-rw-r--r--Sources/ppcasm.cc134
2 files changed, 103 insertions, 37 deletions
diff --git a/Sources/ppc-cc.cc b/Sources/ppc-cc.cc
index 4c894bc..0548dae 100644
--- a/Sources/ppc-cc.cc
+++ b/Sources/ppc-cc.cc
@@ -1210,7 +1210,7 @@ class AssemblyMountpointCLang final : public CompilerKit::AssemblyInterface {
if (countComma == 1) {
leaf.fUserValue.replace(leaf.fUserValue.find("ldw"),
- strlen("ldw"), "mv");
+ strlen("ldw"), "mr");
}
}
@@ -1221,10 +1221,10 @@ class AssemblyMountpointCLang final : public CompilerKit::AssemblyInterface {
}
}
- if (cnt > 1 && keyword != "mv" && keyword != "add" &&
+ if (cnt > 1 && keyword != "mr" && keyword != "add" &&
keyword != "dec") {
leaf.fUserValue.replace(leaf.fUserValue.find(keyword),
- keyword.size(), "mv");
+ keyword.size(), "mr");
}
}
}
diff --git a/Sources/ppcasm.cc b/Sources/ppcasm.cc
index f5fed7b..4b4ef47 100644
--- a/Sources/ppcasm.cc
+++ b/Sources/ppcasm.cc
@@ -13,7 +13,7 @@
// @brief PowerPC Assembler.
// REMINDER: when dealing with an undefined symbol use (string
-// size):LinkerFindSymbol:(string) so that ld will look for it.
+// size):LinkerFindSymbol:(string) so that li will look for it.
/////////////////////////////////////////////////////////////////////////////////////////
@@ -300,7 +300,7 @@ asm_fail_exit:
/////////////////////////////////////////////////////////////////////////////////////////
static bool asm_read_attributes(std::string &line) {
- // import is the opposite of export, it signals to the ld
+ // import is the opposite of export, it signals to the li
// that we need this symbol.
if (ParserKit::find_word(line, "import ")) {
if (kOutputAsBinary) {
@@ -333,7 +333,7 @@ static bool asm_read_attributes(std::string &line) {
}
// this is a special case for the start stub.
- // we want this so that ld can find it.
+ // we want this so that li can find it.
if (name == kPefStart) {
kCurrentRecord.fKind = CompilerKit::kPefCode;
@@ -390,7 +390,7 @@ static bool asm_read_attributes(std::string &line) {
}
// this is a special case for the start stub.
- // we want this so that ld can find it.
+ // we want this so that li can find it.
if (name == kPefStart) {
kCurrentRecord.fKind = CompilerKit::kPefCode;
@@ -509,7 +509,7 @@ std::string CompilerKit::EncoderPowerPC::CheckLine(std::string &line,
}
// these do take an argument.
- std::vector<std::string> operands_inst = {"stw", "ld", "lda", "sta"};
+ std::vector<std::string> operands_inst = {"stw", "li"};
// these don't.
std::vector<std::string> filter_inst = {"blr", "bl", "sc"};
@@ -678,6 +678,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
break;
}
+ case BADDR:
case PCREL: {
auto pos = line.find(opcodePPC.name) + strlen(opcodePPC.name);
@@ -790,13 +791,15 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
break;
}
- // reg to reg means register to register transfer operation.
case G0REG:
case FREG:
case VREG:
case GREG: {
// \brief how many registers we found.
std::size_t found_some_count = 0UL;
+ std::size_t register_count = 0UL;
+ std::string opcodeName = opcodePPC.name;
+
NumberCast64 num(opcodePPC.opcode);
@@ -837,31 +840,94 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
throw std::runtime_error("invalid_register_index");
}
- char numIndex = 0;
+ if (opcodeName == "mr") {
+ switch (register_count) {
+ case 0: {
+ kBytes.push_back(0x78);
- for (size_t i = 0; i != reg_index; i++) {
- numIndex += 0x20;
- }
+ char numIndex = 0x3;
- num.number[2] += numIndex;
+ for (size_t i = 0; i != reg_index; i++) {
+ numIndex += 0x8;
+ }
- ++found_some_count;
+ kBytes.push_back(numIndex);
- if (kVerbose) {
- kStdOut << "ppcasm: Found register: " << register_syntax
- << "\n";
- kStdOut << "ppcasm: Amount of registers in instruction: "
- << found_some_count << "\n";
+ break;
+ }
+ case 1: {
+ char numIndex = 0x1;
+
+ for (size_t i = 0; i != reg_index; i++) {
+ numIndex += 0x20;
+ }
+
+ for (size_t i = 0; i != reg_index; i++) {
+ kBytes[kBytes.size() - 1] += 0x8;
+ }
+
+ kBytes[kBytes.size() - 1] -= 0x8;
+
+ kBytes.push_back(numIndex);
+
+ if (reg_index >= 10 && reg_index < 20)
+ kBytes.push_back(0x7d);
+ else if (reg_index >= 20 && reg_index < 30)
+ kBytes.push_back(0x7e);
+ else if (reg_index >= 30)
+ kBytes.push_back(0x7e);
+ else
+ kBytes.push_back(0x7c);
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ ++register_count;
}
- if (opcodePPC.name[0] == 'm') break;
+ if (opcodeName.find("mf") != std::string::npos ||
+ opcodeName.find("mt") != std::string::npos) {
+ char numIndex = 0;
+
+ for (size_t i = 0; i != reg_index; i++) {
+ numIndex += 0x20;
+ }
+
+ num.number[2] += numIndex;
+
+ ++found_some_count;
+
+ if (kVerbose) {
+ kStdOut << "ppcasm: Found register: " << register_syntax
+ << "\n";
+ kStdOut << "ppcasm: Amount of registers in instruction: "
+ << found_some_count << "\n";
+ }
+
+ for (auto ch : num.number) {
+ kBytes.emplace_back(ch);
+ }
+
+ break;
+ }
}
}
- for (auto ch : num.number) {
- kBytes.emplace_back(ch);
+ if (opcodeName == "mr") {
+ if (register_count == 1) {
+ detail::print_error(
+ "Unrecognized register found.\ntip: each ppcasm register "
+ "starts with 'r'.\nline: " +
+ line,
+ file);
+
+ throw std::runtime_error("not_a_register");
+ }
}
-
+
// we're not in immediate addressing, reg to reg.
if (opcodePPC.ops->type != GREG) {
// remember! register to register!
@@ -876,7 +942,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
}
- if (found_some_count < 1 && name != "ld" && name != "stw") {
+ if (found_some_count < 1 && name[0] != 'l' && name[0] == 's') {
detail::print_error(
"invalid combination of opcode and registers.\nline: " + line,
file);
@@ -889,13 +955,13 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
// try to fetch a number from the name
if (name.find("stw") != std::string::npos ||
- name.find("ld") != 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("ld") != std::string::npos)
+ name.find("li") != std::string::npos)
where_string = ",";
jump_label = line;
@@ -937,17 +1003,17 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
if (!this->WriteNumber(0, jump_label)) {
- // sta expects this: sta 0x000000, r0
- if (name == "sta") {
+ // 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 == "sta" &&
+ if (name == "stw" &&
cpy_jump_label.find("import ") != std::string::npos) {
- detail::print_error("invalid usage import on 'sta', here: " + line,
+ detail::print_error("invalid usage import on 'stw', here: " + line,
file);
throw std::runtime_error("invalid_sta_usage");
}
@@ -957,7 +1023,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
// This is the case where we jump to a label, it is also used as a goto.
- if (name == "ld" || name == "stw") {
+ 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);
@@ -965,8 +1031,8 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
if (cpy_jump_label.find("import") != std::string::npos) {
cpy_jump_label.erase(cpy_jump_label.find("import"), strlen("import"));
- if (name == "sta") {
- detail::print_error("import is not allowed on a sta operation.",
+ if (name == "stw") {
+ detail::print_error("import is not allowed on a stw operation.",
file);
throw std::runtime_error("import_sta_op");
} else {
@@ -974,7 +1040,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
}
- if (name == "lda" || name == "sta") {
+ if (name == "li" || name == "stw") {
for (auto &label : kOriginLabel) {
if (cpy_jump_label == label.first) {
if (kVerbose) {
@@ -1019,9 +1085,9 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
}
/// don't go any further if:
- /// load word (ld) or store word. (stw)
+ /// load word (li) or store word. (stw)
- if (name.find("ld") != std::string::npos ||
+ if (name.find("li") != std::string::npos ||
name.find("st") != std::string::npos)
break;