diff options
Diffstat (limited to 'asm/intel64')
-rw-r--r-- | asm/intel64/all_ops.h | 2 | ||||
-rw-r--r-- | asm/intel64/idiv.cpp | 3 | ||||
-rw-r--r-- | asm/intel64/pop.cpp | 30 | ||||
-rw-r--r-- | asm/intel64/pop.h | 31 | ||||
-rw-r--r-- | asm/intel64/push.cpp | 30 | ||||
-rw-r--r-- | asm/intel64/push.h | 31 | ||||
-rw-r--r-- | asm/intel64/trivials.cpp | 4 | ||||
-rw-r--r-- | asm/intel64/trivials.h | 15 |
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(); }; |