diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-28 08:17:02 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-04-28 08:17:02 +0200 |
| commit | f84498ff447cc4bf891999e782ef90bfbc9577bd (patch) | |
| tree | a29aac9395fb9fc068b59942bf6befb1fb02f3b9 /Sources/ppcasm.cc | |
| parent | c18972980351335ef65029aae677bac76c70d161 (diff) | |
MHR-21: Add support for cmp* instructions in POWER, fix AMD64 assembler,
the origin doesn't get incremented.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Sources/ppcasm.cc')
| -rw-r--r-- | Sources/ppcasm.cc | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/Sources/ppcasm.cc b/Sources/ppcasm.cc index f95020e..9d12922 100644 --- a/Sources/ppcasm.cc +++ b/Sources/ppcasm.cc @@ -48,6 +48,8 @@ static CharType kOutputArch = CompilerKit::kPefArchPowerPC; static Boolean kOutputAsBinary = false; +constexpr auto cPowerIPAlignment = 0x4U; + static UInt32 kErrorLimit = 10; static UInt32 kAcceptableErrors = 0; @@ -677,6 +679,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, if (ParserKit::find_word(line, opcodePPC.name)) { std::string name(opcodePPC.name); std::string jump_label, cpy_jump_label; + std::vector<size_t> found_registers_index; // check funct7 type. switch (opcodePPC.ops->type) { @@ -833,9 +836,9 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, } ++register_count; + ++found_some_count; } - /// FIXME: Prompt correct opcode in little endian. if (opcodeName == "addi") { if (found_some_count == 2 || found_some_count == 0) kBytes.emplace_back(reg_index); @@ -850,6 +853,15 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, } } + if (opcodeName.find("cmp") != std::string::npos) { + ++found_some_count; + + if (found_some_count > 3) { + detail::print_error("Too much registers. -> " + line, file); + throw std::runtime_error("too_much_regs"); + } + } + if (opcodeName.find("mf") != std::string::npos || opcodeName.find("mt") != std::string::npos) { char numIndex = 0; @@ -886,15 +898,29 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, for (auto ch : num.number) { kBytes.emplace_back(ch); } - - break; } + + found_registers_index.push_back(reg_index); } } if (opcodeName == "addi") { kBytes.emplace_back(0x38); } + + if (opcodeName.find("cmp") != std::string::npos) { + char rightReg = 0; + + for (size_t i = 0; i != found_registers_index[0]; i++) { + rightReg += 0x08; + } + + kBytes.emplace_back(0x00); + kBytes.emplace_back(rightReg); + kBytes.emplace_back(found_registers_index[1]); + kBytes.emplace_back(0x7c); + } + if ((opcodeName[0] == 's' && opcodeName[1] == 't')) { size_t offset = 0UL; @@ -913,8 +939,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, if (opcodeName == "mr") { if (register_count == 1) { detail::print_error("Too few registers. -> " + line, file); - - throw std::runtime_error("not_a_register"); + throw std::runtime_error("too_few_registers"); } } @@ -943,7 +968,7 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line, } } - kOrigin += 0x04; + kOrigin += cPowerIPAlignment; break; } } |
