summaryrefslogtreecommitdiffhomepage
path: root/asm/intel64
diff options
context:
space:
mode:
Diffstat (limited to 'asm/intel64')
-rw-r--r--asm/intel64/all_ops.h2
-rw-r--r--asm/intel64/idiv.cpp3
-rw-r--r--asm/intel64/pop.cpp30
-rw-r--r--asm/intel64/pop.h31
-rw-r--r--asm/intel64/push.cpp30
-rw-r--r--asm/intel64/push.h31
-rw-r--r--asm/intel64/trivials.cpp4
-rw-r--r--asm/intel64/trivials.h15
8 files changed, 131 insertions, 15 deletions
diff --git a/asm/intel64/all_ops.h b/asm/intel64/all_ops.h
index c41734c..779506d 100644
--- a/asm/intel64/all_ops.h
+++ b/asm/intel64/all_ops.h
@@ -10,6 +10,8 @@
#include "jmp.h"
#include "mov.h"
#include "mul.h"
+#include "pop.h"
+#include "push.h"
#include "sub.h"
#include "trivials.h"
#include "xor.h"
diff --git a/asm/intel64/idiv.cpp b/asm/intel64/idiv.cpp
index c90724f..3ee17a3 100644
--- a/asm/intel64/idiv.cpp
+++ b/asm/intel64/idiv.cpp
@@ -31,9 +31,6 @@ bool registered {
registerOp(mangleName<Asm::Args::Register8>("idiv"), [](Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_idiv>(args);
}) &&
- registerOp(mangleName<Asm::Args::Register32>("idiv"), [](Asm::Args& args) -> std::shared_ptr<Op>{
- return std::make_shared<Op_idiv>(args);
- }) &&
registerOp(mangleName<Asm::Args::Register64>("idiv"), [](Asm::Args& args) -> std::shared_ptr<Op>{
return std::make_shared<Op_idiv>(args);
})
diff --git a/asm/intel64/pop.cpp b/asm/intel64/pop.cpp
new file mode 100644
index 0000000..8528b15
--- /dev/null
+++ b/asm/intel64/pop.cpp
@@ -0,0 +1,30 @@
+#include "pop.h"
+
+#include "codes.h"
+
+#include <asm/assembler.h>
+#include <asm/operators.h>
+
+#include <asm/intel64/codes.h>
+
+using namespace std::string_literals;
+
+Op_pop::Op_pop(Asm::Args& args)
+{
+ if (args[0].type() == typeid(Asm::Args::Register64)) { // pop reg64
+ machine_code = std::vector<uint8_t>{ 0x58 } + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name());
+ } else {
+ throw std::runtime_error("Unimplemented: pop "s + args[0].type().name());
+ }
+}
+
+namespace {
+
+bool registered {
+ registerOp(mangleName<Asm::Args::Register64>("pop"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_pop>(args);
+ })
+};
+
+}
+
diff --git a/asm/intel64/pop.h b/asm/intel64/pop.h
new file mode 100644
index 0000000..3bcd421
--- /dev/null
+++ b/asm/intel64/pop.h
@@ -0,0 +1,31 @@
+// Pop value from stack
+
+#pragma once
+
+#include <asm/assembler.h>
+
+class Op_pop: public Op
+{
+public:
+ Op_pop(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/push.cpp b/asm/intel64/push.cpp
new file mode 100644
index 0000000..bad2c90
--- /dev/null
+++ b/asm/intel64/push.cpp
@@ -0,0 +1,30 @@
+#include "push.h"
+
+#include "codes.h"
+
+#include <asm/assembler.h>
+#include <asm/operators.h>
+
+#include <asm/intel64/codes.h>
+
+using namespace std::string_literals;
+
+Op_push::Op_push(Asm::Args& args)
+{
+ if (args[0].type() == typeid(Asm::Args::Register64)) { // push reg64
+ machine_code = std::vector<uint8_t>{ 0x50 } + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name());
+ } else {
+ throw std::runtime_error("Unimplemented: push "s + args[0].type().name());
+ }
+}
+
+namespace {
+
+bool registered {
+ registerOp(mangleName<Asm::Args::Register64>("push"), [](Asm::Args& args) -> std::shared_ptr<Op>{
+ return std::make_shared<Op_push>(args);
+ })
+};
+
+}
+
diff --git a/asm/intel64/push.h b/asm/intel64/push.h
new file mode 100644
index 0000000..9525981
--- /dev/null
+++ b/asm/intel64/push.h
@@ -0,0 +1,31 @@
+// Push value onto stack
+
+#pragma once
+
+#include <asm/assembler.h>
+
+class Op_push: public Op
+{
+public:
+ Op_push(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/trivials.cpp b/asm/intel64/trivials.cpp
index dd89ecd..094d27f 100644
--- a/asm/intel64/trivials.cpp
+++ b/asm/intel64/trivials.cpp
@@ -2,6 +2,10 @@
#include <asm/assembler.h>
+Op_nop::Op_nop(): OpSimple({ 0x90 }) {}
+Op_ret::Op_ret(): OpSimple({ 0xC3 }) {} // near return; TODO: far return is 0xCB
+Op_syscall::Op_syscall(): OpSimple({ 0x0F, 0x05 }) {}
+
namespace {
bool registered {
diff --git a/asm/intel64/trivials.h b/asm/intel64/trivials.h
index 72ea3f8..898001e 100644
--- a/asm/intel64/trivials.h
+++ b/asm/intel64/trivials.h
@@ -5,20 +5,11 @@
#include <asm/chunk.h>
// No Operation
-class Op_nop: public OpSimple
-{
-public: Op_nop() : OpSimple({ 0x90 }) {}
-};
+class Op_nop: public OpSimple { public: Op_nop(); };
// Return from procedure
-class Op_ret: public OpSimple
-{
-public: Op_ret() : OpSimple({ 0xC3 }) {} // near return; TODO: far return is 0xCB
-};
+class Op_ret: public OpSimple { public: Op_ret(); };
// Syscall
-class Op_syscall: public OpSimple
-{
-public: Op_syscall() : OpSimple({ 0x0F, 0x05 }) {}
-};
+class Op_syscall: public OpSimple { public: Op_syscall(); };