summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-05 22:25:00 +0200
committerAmlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>2024-04-05 22:32:06 +0200
commit735ba60b26bc604d04e4a67e2b4570c1a50eb035 (patch)
tree3340cf336c51358cbfb4804a57763c306e000be9
parent672ec345c6eb5a06500cba10e3f329b8a65ee047 (diff)
PowerPC: Implement register support inside powerpc assembler.
Signed-off-by: Amlal El Mahrouss <113760121+Amlal-ElMahrouss@users.noreply.github.com>
-rw-r--r--Examples/ExamplePowerPC.S3
-rw-r--r--Headers/AsmKit/Arch/powerpc.hpp2
-rw-r--r--Sources/ppcasm.cc37
3 files changed, 25 insertions, 17 deletions
diff --git a/Examples/ExamplePowerPC.S b/Examples/ExamplePowerPC.S
index 1f8bd21..02fa7c0 100644
--- a/Examples/ExamplePowerPC.S
+++ b/Examples/ExamplePowerPC.S
@@ -1 +1,4 @@
+# Sample program
+
+mr r0, r0
blr \ No newline at end of file
diff --git a/Headers/AsmKit/Arch/powerpc.hpp b/Headers/AsmKit/Arch/powerpc.hpp
index d8dea1f..9a7c8f4 100644
--- a/Headers/AsmKit/Arch/powerpc.hpp
+++ b/Headers/AsmKit/Arch/powerpc.hpp
@@ -63,7 +63,7 @@ struct op {
struct CpuOpcodePPC {
uint32_t opcode;
- char *name;
+ const char *name; // c++ wants the string to be const, it makes sense here.
struct op ops[5];
uint32_t cpus;
};
diff --git a/Sources/ppcasm.cc b/Sources/ppcasm.cc
index 0214053..f7b8882 100644
--- a/Sources/ppcasm.cc
+++ b/Sources/ppcasm.cc
@@ -665,13 +665,17 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
std::string name(opcodePPC.name);
std::string jump_label, cpy_jump_label;
- kBytes.emplace_back(opcodePPC.opcode);
-
// check funct7 type.
switch (opcodePPC.ops->type) {
+ default: {
+ kBytes.emplace_back(opcodePPC.opcode);
+ break;
+ }
// reg to reg means register to register transfer operation.
- case GREG:
- case G0REG: {
+ case G0REG:
+ case FREG:
+ case VREG:
+ case GREG: {
// \brief how many registers we found.
std::size_t found_some = 0UL;
@@ -691,6 +695,8 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
if (isdigit(line[line_index + 2]))
reg_str += line[line_index + 2];
+ NumberCast32 num(opcodePPC.opcode);
+
// it ranges from r0 to r19
// something like r190 doesn't exist in the instruction set.
if (kOutputArch == CompilerKit::kPefArchPowerPC) {
@@ -708,24 +714,25 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
// finally cast to a size_t
std::size_t reg_index = strtol(reg_str.c_str(), nullptr, 10);
- uint8_t base = 0x08;
-
- for (size_t i = 0; i != reg_index; i++)
- {
- base += 2;
- }
-
- kBytes.emplace_back(base);
-
if (reg_index > kAsmRegisterLimit) {
detail::print_error("invalid register index, r" + reg_str,
file);
throw std::runtime_error("invalid_register_index");
}
- kBytes.emplace_back(reg_index);
++found_some;
+ char numIndex = 0;
+
+ for (size_t i = 0; i != reg_index; i++)
+ {
+ numIndex += 0x20;
+ }
+
+ num.number[2] += numIndex;
+
+ kBytes.emplace_back(num.raw);
+
if (kVerbose) {
kStdOut << "ppcasm: Register found: " << register_syntax << "\n";
kStdOut << "ppcasm: Register amount in instruction: "
@@ -775,8 +782,6 @@ bool CompilerKit::EncoderPowerPC::WriteLine(std::string &line,
throw std::runtime_error("invalid_comb_op_pop");
}
}
- default:
- break;
}
// try to fetch a number from the name