summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-11-09 10:35:00 +0100
committerRoland Reichwein <mail@reichwein.it>2020-11-09 10:35:00 +0100
commit6ab3715ee2622e293f7c4924511f31347b327e6e (patch)
treeeca588d3d8c320cb25f209b76db91b95cd9f5614
parent1ac8ab06e9aad3b6d22685255459d71cb49e1f28 (diff)
Implement inc instruction, support 64 bit regs
-rw-r--r--Makefile1
-rw-r--r--asm/assembler.h15
-rw-r--r--asm/intel64/all_ops.h5
-rw-r--r--asm/intel64/codes.cpp5
-rw-r--r--asm/intel64/inc.cpp43
-rw-r--r--asm/intel64/inc.h31
-rw-r--r--asm/intel64/mov.cpp5
7 files changed, 105 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index 3d3575f..de84081 100644
--- a/Makefile
+++ b/Makefile
@@ -49,6 +49,7 @@ PROGSRC=\
asm/chunk.cpp \
asm/encode.cpp \
asm/intel64/add.cpp \
+ asm/intel64/inc.cpp \
asm/intel64/int.cpp \
asm/intel64/jmp.cpp \
asm/intel64/mov.cpp \
diff --git a/asm/assembler.h b/asm/assembler.h
index 832a78e..b459b85 100644
--- a/asm/assembler.h
+++ b/asm/assembler.h
@@ -48,6 +48,21 @@ public:
uint32_t m_value;
};
+ class Immediate64
+ {
+ public:
+ Immediate64(uint64_t value): m_value(value) {}
+ uint64_t value() { return m_value; }
+ std::vector<uint8_t> getCode() {
+ std::vector<uint8_t> result(size_t(8));
+ *(reinterpret_cast<uint64_t*>(result.data())) = boost::endian::native_to_little(m_value);
+ return result;
+ };
+
+ private:
+ uint64_t m_value;
+ };
+
class Register8
{
public:
diff --git a/asm/intel64/all_ops.h b/asm/intel64/all_ops.h
index 83b654b..59ce624 100644
--- a/asm/intel64/all_ops.h
+++ b/asm/intel64/all_ops.h
@@ -1,5 +1,10 @@
#pragma once
+#include "add.h"
+#include "inc.h"
#include "int.h"
+#include "jmp.h"
+#include "mov.h"
#include "nop.h"
#include "ret.h"
+#include "xor.h"
diff --git a/asm/intel64/codes.cpp b/asm/intel64/codes.cpp
index 5d93a57..21a891c 100644
--- a/asm/intel64/codes.cpp
+++ b/asm/intel64/codes.cpp
@@ -37,6 +37,11 @@ namespace {
{"ebx", 3}, {"ebp", 5},
{"ecx", 1}, {"esi", 6},
{"edx", 2}, {"edi", 7},
+
+ {"rax", 0}, {"rsp", 4},
+ {"rbx", 3}, {"rbp", 5},
+ {"rcx", 1}, {"rsi", 6},
+ {"rdx", 2}, {"rdi", 7},
};
}
diff --git a/asm/intel64/inc.cpp b/asm/intel64/inc.cpp
new file mode 100644
index 0000000..3df9104
--- /dev/null
+++ b/asm/intel64/inc.cpp
@@ -0,0 +1,43 @@
+#include "inc.h"
+
+#include "codes.h"
+
+#include <asm/assembler.h>
+#include <asm/operators.h>
+
+#include <asm/intel64/codes.h>
+
+using namespace std::string_literals;
+
+Op_inc::Op_inc(Asm::Args& args)
+{
+ if (args[0].type() == typeid(Asm::Args::Register8)) { // inc reg8
+ machine_code = std::vector<uint8_t>{ 0xFE } +
+ ModRM("/0", std::any_cast<Asm::Args::Register8>(args[0]).name());
+ } else if (args[0].type() == typeid(Asm::Args::Register32)) { // inc reg32
+ machine_code = std::vector<uint8_t>{ 0xFF } +
+ ModRM("/0", std::any_cast<Asm::Args::Register32>(args[0]).name());
+ } else if (args[0].type() == typeid(Asm::Args::Register64)) { // inc reg64
+ machine_code = REX("W") + std::vector<uint8_t>{ 0xFF } +
+ ModRM("/0", std::any_cast<Asm::Args::Register64>(args[0]).name());
+ } else {
+ throw std::runtime_error("Unimplemented: inc "s + args[0].type().name());
+ }
+}
+
+namespace {
+
+bool registered {
+ registerOp(mangleName<Asm::Args::Register8>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_inc>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Register32>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_inc>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Register64>("inc"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_inc>(args);
+ })
+};
+
+}
+
diff --git a/asm/intel64/inc.h b/asm/intel64/inc.h
new file mode 100644
index 0000000..0887392
--- /dev/null
+++ b/asm/intel64/inc.h
@@ -0,0 +1,31 @@
+// Increment Register
+
+#pragma once
+
+#include <asm/assembler.h>
+
+class Op_inc: public Op
+{
+public:
+ Op_inc(Asm::Args& args);
+
+public:
+ std::vector<uint8_t> getCode() override
+ {
+ return machine_code;
+ }
+
+ size_t size() override
+ {
+ return machine_code.size();
+ }
+
+ bool optimize() override ///< returns true if changed
+ {
+ return false;
+ }
+
+protected:
+ std::vector<uint8_t> machine_code;
+};
+
diff --git a/asm/intel64/mov.cpp b/asm/intel64/mov.cpp
index 8603fc9..5741170 100644
--- a/asm/intel64/mov.cpp
+++ b/asm/intel64/mov.cpp
@@ -17,6 +17,8 @@ Op_mov::Op_mov(Asm::Args& args)
ModRM(std::any_cast<Asm::Args::Register8>(args[1]).name(), std::any_cast<Asm::Args::Register8>(args[0]).name());
} else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Immediate32)) { // mov reg32, imm32
machine_code = std::vector<uint8_t>{ static_cast<uint8_t>(0xB8 + RegNo(std::any_cast<Asm::Args::Register32>(args[0]).name())) } + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode();
+ } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate64)) { // mov reg64, imm64
+ machine_code = std::vector<uint8_t>{ REX("W") + static_cast<uint8_t>(0xB8 + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name())) } + std::any_cast<Asm::Args::Immediate64>(args[1]).getCode();
} else {
throw std::runtime_error("Unimplemented: mov "s + args[0].type().name() + " "s + args[1].type().name());
}
@@ -30,6 +32,9 @@ bool registered {
}) &&
registerOp(mangleName<Asm::Args::Register32, Asm::Args::Immediate32>("mov"), [](Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_mov>(args);
+ }) &&
+ registerOp(mangleName<Asm::Args::Register64, Asm::Args::Immediate64>("mov"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_mov>(args);
})
};