// Helper Functions for assembling #pragma once #include "chunk.h" #include "../minicc.h" #include #include #include #include #include #include #include #include namespace Asm { class Args: public std::vector { public: Args(){} Args(const std::vector& args): std::vector(args){} class Immediate8 { public: Immediate8(uint8_t value): m_value(value) {} uint8_t value() const {return m_value;} std::vector getCode() {return {m_value};}; private: uint8_t m_value; }; class Immediate64; class Immediate32 { public: Immediate32(uint32_t value): m_value(value) {} Immediate32(const Immediate64&); ///< Convert from Immediate64 if data is small enough uint32_t value() const { return m_value; } std::vector getCode() { std::vector result(size_t(4)); *(reinterpret_cast(result.data())) = boost::endian::native_to_little(m_value); return result; }; private: uint32_t m_value; }; class Immediate64 { public: Immediate64(uint64_t value): m_value(value) {} uint64_t value() const { return m_value; } std::vector getCode() { std::vector result(size_t(8)); *(reinterpret_cast(result.data())) = boost::endian::native_to_little(m_value); return result; }; private: uint64_t m_value; }; class Register8 { public: Register8(const std::string& name): m_name(name) {} std::string name() const { return m_name; } private: std::string m_name; }; class Register32 { public: Register32(const std::string& name): m_name(name) {} std::string name() const { return m_name; } private: std::string m_name; }; class Register64 { public: Register64(const std::string& name): m_name(name) {} std::string name() const { return m_name; } private: std::string m_name; }; // 64 bit Ptr to 8 bit Memory class Mem8Ptr64 { public: Mem8Ptr64(const std::string& reg, int32_t offs = 0); Mem8Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); std::string reg() const; std::string reg2() const; int32_t offs() const; private: std::string m_reg; std::string m_reg2; int32_t m_offs; }; // 64 bit Ptr to 32 bit Memory class Mem32Ptr64 { public: Mem32Ptr64(const std::string& reg, int32_t offs = 0); Mem32Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); std::string reg() const; std::string reg2() const; int32_t offs() const; private: std::string m_reg; std::string m_reg2; int32_t m_offs; }; // 64 bit Ptr to 64 bit Memory class Mem64Ptr64 { public: Mem64Ptr64(const std::string& reg, int32_t offs = 0); Mem64Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); std::string reg() const; std::string reg2() const; int32_t offs() const; private: std::string m_reg; std::string m_reg2; int32_t m_offs; }; class Label { public: Label(const std::string& name): m_name(name) {} std::string name() const { return m_name; } private: std::string m_name; }; }; // class Args } // namespace Asm using FactoryFunction = std::function(const Asm::Args&)>; // mnemonic: mnemonic including argument types bool registerOp(const std::string& mnemonic, FactoryFunction f); // Create Op from a registered mnemonic // mnemonic: just the mnemonic name std::shared_ptr makeOp(const std::string& mnemonic, const Asm::Args& args); // overload for empty list of arguments std::shared_ptr makeOp(const std::string& mnemonic); std::shared_ptr