diff --git a/CMakeLists.txt b/CMakeLists.txt index 00e2e27..4027416 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,6 @@ add_library(city src/ir/Builder.h src/ir/instruction/IRInstruction.cpp src/ir/instruction/IRInstruction.h - src/backend/NativeModule.cpp - src/backend/NativeModule.h src/Assembly.cpp src/Assembly.h src/ir/value/ConstantValue.cpp @@ -62,28 +60,30 @@ add_library(city src/ir/instruction/memory/StoreInst.cpp src/backend/amd64/Amd64.cpp src/backend/amd64/Amd64.h - src/backend/IRTranslator.h src/backend/amd64/Amd64Translator.cpp src/backend/amd64/Amd64Translator.h src/backend/amd64/instruction/Amd64Instruction.cpp src/backend/amd64/instruction/Amd64Instruction.h - src/backend/amd64/instruction/arithmetic/x86AddRM32Inst.h + src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h src/ByteBuffer.h - src/backend/amd64/instruction/arithmetic/x86AddMI32Inst.h + src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h src/ir/instruction/InstructionFunctor.h src/backend/NativeInstruction.cpp src/backend/NativeInstruction.h src/backend/amd64/Amd64Register.cpp src/backend/amd64/Amd64Register.h src/backend/amd64/Amd64ModRM.h - src/backend/amd64/instruction/memory/Amd64PushO64.h - src/backend/amd64/instruction/memory/Amd64MovMR64.h - src/backend/amd64/instruction/memory/Amd64PopO64.h - src/backend/amd64/instruction/control/Amd64RetZONear.h + src/backend/amd64/instruction/memory/Amd64Push.h + src/backend/amd64/instruction/memory/Amd64Mov.h + src/backend/amd64/instruction/memory/Amd64Pop.h + src/backend/amd64/instruction/control/Amd64Ret.h src/runtime/Windows.cpp src/runtime/Windows.h src/Object.cpp src/Object.h + src/backend/amd64/Amd64Module.cpp + src/backend/amd64/Amd64Module.h + src/backend/IRTranslator.h ) target_include_directories(city PUBLIC src) diff --git a/src/JIT.cpp b/src/JIT.cpp index ebc962a..aaf3d1b 100644 --- a/src/JIT.cpp +++ b/src/JIT.cpp @@ -3,32 +3,20 @@ using namespace city; -void JIT::TranslateIRModules() +void JIT::CompileIRModules() { - for (auto &module : this->ir_modules_) + for (auto &[name, module] : this->ir_modules_) { - auto native_module = this->backend_->BuildModule(module); - this->native_modules_.push_back(std::move(native_module)); + this->objects_.insert({name, this->backend_->BuildModule(module)}); } this->ir_modules_.clear(); } -void JIT::CompileNativeModules() -{ - for (auto &native_module : this->native_modules_) - { - auto object = Object::FromNativeModule(native_module); - this->objects_.push_back(std::move(object)); - } - - this->native_modules_.clear(); -} - Assembly JIT::LinkObjects() const { std::size_t allocation_size = 0; - for (auto const &object : this->objects_) + for (auto const &[name, object] : this->objects_) { allocation_size += object.GetBinarySize(); } @@ -37,7 +25,7 @@ Assembly JIT::LinkObjects() const Assembly assembly{std::move(native_memory)}; std::size_t object_insertion_offset = 0; - for (auto const &object : this->objects_) + for (auto const &[name, object] : this->objects_) { auto object_size = object.GetBinarySize(); @@ -47,10 +35,10 @@ Assembly JIT::LinkObjects() const object_insertion_offset += object_size; - for (auto &[name, offset] : object.symtab_) + for (auto &[name, offset] : object.symbol_table_) { assembly.symbol_table_[name] = { - .raw = assembly_addr + offset, + .location = assembly_addr + reinterpret_cast(offset.location), .flags = SymbolFlags::Exectuable, }; } @@ -61,17 +49,20 @@ Assembly JIT::LinkObjects() const return assembly; } -void JIT::AddIRModule(IRModule module) +void JIT::InsertIRModule(IRModule module) { - this->ir_modules_.push_back(std::move(module)); + this->ir_modules_.insert({module.GetName(), std::move(module)}); } -void JIT::RemoveModule(std::string const &name) {} +void JIT::RemoveModule(std::string const &name) +{ + this->ir_modules_.erase(name); + this->objects_.erase(name); +} Assembly JIT::CompileAndLink() { - this->TranslateIRModules(); - this->CompileNativeModules(); + this->CompileIRModules(); return this->LinkObjects(); } diff --git a/src/JIT.h b/src/JIT.h index 2f26014..618332c 100644 --- a/src/JIT.h +++ b/src/JIT.h @@ -2,11 +2,11 @@ #define CITY_COMPILER_H #include +#include #include #include "Assembly.h" #include "Object.h" #include "backend/Backend.h" -#include "backend/NativeModule.h" #include "ir/IRModule.h" namespace city @@ -15,19 +15,13 @@ namespace city { std::unique_ptr backend_; - std::vector ir_modules_; - std::vector native_modules_; - std::vector objects_; + std::unordered_map ir_modules_; + std::unordered_map objects_; /** * Translates all IR modules to native modules and deletes the IR modules. */ - void TranslateIRModules(); - - /** - * Translates all native modules into objects and deletes the native modules. - */ - void CompileNativeModules(); + void CompileIRModules(); /** * Links all objects together (non-destructively) and returns the final linked Assembly. @@ -40,8 +34,13 @@ namespace city * Adds a module to the compiler, transferring ownership to the compiler. * @param module Module to transfer to the compiler */ - void AddIRModule(IRModule module); + void InsertIRModule(IRModule module); + /** + * Removes a module (or corresponding object if already compiled) from the compiler. + * WARNING: May cause linker errors if other modules depend on the removed module. + * @param name Name of module to remove + */ void RemoveModule(std::string const &name); /** diff --git a/src/Object.cpp b/src/Object.cpp index bd40a4f..b2e1965 100644 --- a/src/Object.cpp +++ b/src/Object.cpp @@ -7,34 +7,4 @@ std::size_t Object::GetBinarySize() const noexcept return this->native_memory_.GetAllocationSize(); } -Object Object::FromNativeModule(NativeModule const &module) -{ - // Allocate memory - std::size_t allocation_size = 0; - for (auto &inst : module.instructions_) - { - allocation_size += inst->GetBinarySize(); - } - auto native_memory = NativeMemoryHandle::Allocate(allocation_size); - - // Create object - Object object{std::move(native_memory)}; - - // Write to buffer - std::size_t offset = 0; - for (auto &inst : module.instructions_) - { - auto label = inst->GetLabel(); - if (label != nullptr) - { - object.symtab_[label] = offset; - } - - auto addr = object.native_memory_.GetAddressAtOffset(offset); - offset += inst->WriteToBuffer(addr); - } - - return object; -} - -Object::Object(NativeMemoryHandle native_memory) : native_memory_(std::move(native_memory)) {} +Object::Object(NativeMemoryHandle &&native_memory, SymbolTable &&symbol_table) : native_memory_(std::move(native_memory)), symbol_table_(std::move(symbol_table)) {} diff --git a/src/Object.h b/src/Object.h index 256609e..8a95a21 100644 --- a/src/Object.h +++ b/src/Object.h @@ -1,9 +1,7 @@ #ifndef OBJECT_H #define OBJECT_H -#include -#include -#include "backend/NativeModule.h" +#include "Symbol.h" #include "runtime/NativeMemoryHandle.h" namespace city @@ -16,18 +14,12 @@ namespace city protected: NativeMemoryHandle native_memory_; - - /** - * Holds instruction labels with their offsets into the binary. - */ - std::unordered_map symtab_; + SymbolTable symbol_table_; public: [[nodiscard]] std::size_t GetBinarySize() const noexcept; - static Object FromNativeModule(NativeModule const &module); - - Object(NativeMemoryHandle native_memory); + Object(NativeMemoryHandle &&native_memory, SymbolTable &&symbol_table); }; } // namespace city diff --git a/src/Symbol.h b/src/Symbol.h index fe6abef..c0355e0 100644 --- a/src/Symbol.h +++ b/src/Symbol.h @@ -2,6 +2,8 @@ #define CITY_SYMBOL_H #include +#include +#include namespace city { @@ -12,15 +14,17 @@ namespace city struct Symbol { - std::byte *raw; + std::byte *location; SymbolFlags flags; template T *ToPointer() const noexcept { - return reinterpret_cast(this->raw); + return reinterpret_cast(this->location); } }; + + using SymbolTable = std::unordered_map; } // namespace city #endif // CITY_SYMBOL_H diff --git a/src/backend/Backend.h b/src/backend/Backend.h index b71347a..9dd9f3c 100644 --- a/src/backend/Backend.h +++ b/src/backend/Backend.h @@ -1,7 +1,7 @@ #ifndef CITY_BACKEND_H #define CITY_BACKEND_H -#include "NativeModule.h" +#include "Object.h" #include "ir/IRModule.h" namespace city @@ -9,7 +9,7 @@ namespace city class Backend { public: - [[nodiscard]] virtual NativeModule BuildModule(IRModule &module) = 0; + [[nodiscard]] virtual Object BuildModule(IRModule &module) = 0; /** * Instantiates and returns a handle to the host-native compiler backend. diff --git a/src/backend/IRTranslator.h b/src/backend/IRTranslator.h index 8ac337f..1fd3d03 100644 --- a/src/backend/IRTranslator.h +++ b/src/backend/IRTranslator.h @@ -1,7 +1,6 @@ -#ifndef IRTRANSLATIONINTERFACE_H -#define IRTRANSLATIONINTERFACE_H +#ifndef IRTRANSLATOR_H +#define IRTRANSLATOR_H -#include "NativeModule.h" #include "ir/instruction/InstructionFunctor.h" namespace city @@ -12,10 +11,7 @@ namespace city struct IRTranslator : InstructionFunctor { - NativeModule &module; - - explicit IRTranslator(NativeModule &native_module) : module(native_module) {} }; } // namespace city -#endif // IRTRANSLATIONINTERFACE_H +#endif // IRTRANSLATOR_H diff --git a/src/backend/NativeModule.cpp b/src/backend/NativeModule.cpp deleted file mode 100644 index b5bd91f..0000000 --- a/src/backend/NativeModule.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "NativeModule.h" - -using namespace city; diff --git a/src/backend/NativeModule.h b/src/backend/NativeModule.h deleted file mode 100644 index c2fb25d..0000000 --- a/src/backend/NativeModule.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CITY_OBJECT_H -#define CITY_OBJECT_H - -#include -#include -#include -#include "NativeInstruction.h" - -namespace city -{ - class Object; - - class NativeModule - { - friend class Object; - - protected: - std::vector> instructions_; - - public: - template - requires std::derived_from - NativeInstruction *EmplaceInstruction(Args... args) - { - auto &inst = this->instructions_.emplace_back(std::make_unique(std::forward(args)...)); - return inst.get(); - } - }; -} // namespace city - -#endif // CITY_OBJECT_H diff --git a/src/backend/amd64/Amd64.cpp b/src/backend/amd64/Amd64.cpp index 52331b2..fb5b07a 100644 --- a/src/backend/amd64/Amd64.cpp +++ b/src/backend/amd64/Amd64.cpp @@ -1,15 +1,14 @@ #include "Amd64.h" #include "Amd64Translator.h" -#include "instruction/memory/Amd64MovMR64.h" -#include "instruction/memory/Amd64PopO64.h" -#include "instruction/memory/Amd64PushO64.h" +#include "instruction/memory/Amd64Mov.h" +#include "instruction/memory/Amd64Push.h" #include "ir/Block.h" #include "ir/Function.h" #include "ir/instruction/IRInstruction.h" using namespace city; -std::array const x86_register_definitions = { +std::array const city::amd64_register_definitions = { Amd64Register(Amd64RegisterCode::XMM0), Amd64Register(Amd64RegisterCode::XMM1), Amd64Register(Amd64RegisterCode::XMM2), @@ -20,18 +19,19 @@ std::array const x86_register_definitions = { Amd64Register(Amd64RegisterCode::XMM7), }; -NativeModule Amd64::BuildModule(IRModule &module) +Object Amd64::BuildModule(IRModule &ir_module) { - NativeModule object{}; + Amd64Module amd64_module{}; - Amd64Translator translator{object}; - for (auto &function : module.functions_) + Amd64Translator translator{amd64_module}; + for (auto &function : ir_module.functions_) { // Function Prolog - auto entry = object.EmplaceInstruction(Amd64RegisterCode::RBP); - entry->SetLabel(function->name_); + auto entry = Amd64Push::O64(Amd64RegisterCode::RBP); + entry.SetLabel(function->name_); + amd64_module.InsertInstruction(std::move(entry)); - object.EmplaceInstruction(Amd64RegisterCode::RBP, Amd64RegisterCode::RSP); + amd64_module.InsertInstruction(Amd64Mov::MR64(Amd64RegisterCode::RBP, Amd64RegisterCode::RSP)); // Function Body for (auto block : function->blocks_) @@ -43,5 +43,34 @@ NativeModule Amd64::BuildModule(IRModule &module) } } - return std::move(object); + /* build module */ + // Allocate memory + std::size_t allocation_size = 0; + for (auto &inst : amd64_module.instructions_) + { + allocation_size += inst.GetBinarySize(); + } + auto native_memory = NativeMemoryHandle::Allocate(allocation_size); + + // Symbol table + SymbolTable symbol_table; + + // Write to buffer + std::size_t offset = 0; + for (auto &inst : amd64_module.instructions_) + { + auto label = inst.GetLabel(); + if (label != nullptr) + { + symbol_table[label] = { + .flags = SymbolFlags::Exectuable, + .location = reinterpret_cast(offset), + }; + } + + auto addr = native_memory.GetAddressAtOffset(offset); + offset += inst.WriteToBuffer(addr); + } + + return {std::move(native_memory), std::move(symbol_table)}; } diff --git a/src/backend/amd64/Amd64.h b/src/backend/amd64/Amd64.h index f39fc3c..feb66ec 100644 --- a/src/backend/amd64/Amd64.h +++ b/src/backend/amd64/Amd64.h @@ -1,14 +1,17 @@ #ifndef X86_64_H #define X86_64_H +#include "Amd64Register.h" #include "backend/Backend.h" namespace city { + extern std::array const amd64_register_definitions; + class Amd64 : public Backend { public: - [[nodiscard]] NativeModule BuildModule(IRModule &module) override; + [[nodiscard]] Object BuildModule(IRModule &ir_module) override; }; } // namespace city diff --git a/src/backend/amd64/Amd64Module.cpp b/src/backend/amd64/Amd64Module.cpp new file mode 100644 index 0000000..53ce7c4 --- /dev/null +++ b/src/backend/amd64/Amd64Module.cpp @@ -0,0 +1,12 @@ +// +// Created by Nathan on 12/29/2024. +// + +#include "Amd64Module.h" + +using namespace city; + +void Amd64Module::InsertInstruction(Amd64Instruction &&inst) +{ + this->instructions_.push_back(inst); +} diff --git a/src/backend/amd64/Amd64Module.h b/src/backend/amd64/Amd64Module.h new file mode 100644 index 0000000..db7e5e6 --- /dev/null +++ b/src/backend/amd64/Amd64Module.h @@ -0,0 +1,29 @@ +#ifndef AMD64MODULE_H +#define AMD64MODULE_H + +#include +#include "Amd64.h" +#include "instruction/Amd64Instruction.h" + +namespace city +{ + struct Amd64Translator; + + class Amd64Module + { + friend class Amd64; + friend class Amd64Translator; + + // std::stack stack_; + std::vector instructions_; + std::array registers_ = amd64_register_definitions; + + protected: + void InsertInstruction(Amd64Instruction &&inst); + + + public: + }; +} // namespace city + +#endif // AMD64MODULE_H diff --git a/src/backend/amd64/Amd64Translator.cpp b/src/backend/amd64/Amd64Translator.cpp index cd7eaf9..bcb52d9 100644 --- a/src/backend/amd64/Amd64Translator.cpp +++ b/src/backend/amd64/Amd64Translator.cpp @@ -1,6 +1,6 @@ #include "Amd64Translator.h" -#include "backend/amd64/instruction/control/Amd64RetZONear.h" -#include "backend/amd64/instruction/memory/Amd64PopO64.h" +#include "backend/amd64/instruction/control/Amd64Ret.h" +#include "backend/amd64/instruction/memory/Amd64Pop.h" using namespace city; @@ -15,8 +15,8 @@ IRTranslationResult Amd64Translator::Translate(RetInst *instruction) auto return_value = instruction->GetReturnValue(); } - this->module.EmplaceInstruction(Amd64RegisterCode::RBP); - this->module.EmplaceInstruction(); + this->module.InsertInstruction(Amd64Pop::O64(Amd64RegisterCode::RBP)); + this->module.InsertInstruction(Amd64Ret::ZONear()); return {}; } diff --git a/src/backend/amd64/Amd64Translator.h b/src/backend/amd64/Amd64Translator.h index c2ff5d5..ab7bf90 100644 --- a/src/backend/amd64/Amd64Translator.h +++ b/src/backend/amd64/Amd64Translator.h @@ -1,20 +1,22 @@ #ifndef X86_64TRANSLATIONINTERFACE_H #define X86_64TRANSLATIONINTERFACE_H -#include -#include "Amd64Register.h" +#include "Amd64Module.h" #include "backend/IRTranslator.h" +#include "ir/instruction/InstructionFunctor.h" namespace city { struct Amd64Translator : IRTranslator { + Amd64Module &module; + IRTranslationResult Translate(AddInst *instruction) override; IRTranslationResult Translate(BranchInst *instruction) override; IRTranslationResult Translate(RetInst *instruction) override; IRTranslationResult Translate(StoreInst *instruction) override; - explicit Amd64Translator(NativeModule &object) : IRTranslator(object) {} + explicit Amd64Translator(Amd64Module &module) : module(module) {} }; } // namespace city diff --git a/src/backend/amd64/instruction/arithmetic/x86AddMI32Inst.h b/src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h similarity index 77% rename from src/backend/amd64/instruction/arithmetic/x86AddMI32Inst.h rename to src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h index d234d61..0563373 100644 --- a/src/backend/amd64/instruction/arithmetic/x86AddMI32Inst.h +++ b/src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h @@ -5,7 +5,7 @@ namespace city { - class x86AddMI32Inst : public Amd64Instruction + class Amd64AddMI32Inst : public Amd64Instruction { }; } // namespace city diff --git a/src/backend/amd64/instruction/arithmetic/x86AddRM32Inst.h b/src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h similarity index 75% rename from src/backend/amd64/instruction/arithmetic/x86AddRM32Inst.h rename to src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h index 4ab5a90..490f1d6 100644 --- a/src/backend/amd64/instruction/arithmetic/x86AddRM32Inst.h +++ b/src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h @@ -9,10 +9,10 @@ namespace city /** * ADD r32, r/m32 */ - class x86AddRM32Inst : public Amd64Instruction + class Amd64AddRM32Inst : public Amd64Instruction { public: - x86AddRM32Inst(Value *dst, Value *src) + Amd64AddRM32Inst(Value *dst, Value *src) { this->SetOpcode({0x03}); } diff --git a/src/backend/amd64/instruction/control/Amd64RetZONear.h b/src/backend/amd64/instruction/control/Amd64Ret.h similarity index 55% rename from src/backend/amd64/instruction/control/Amd64RetZONear.h rename to src/backend/amd64/instruction/control/Amd64Ret.h index 1d9b087..172a9c1 100644 --- a/src/backend/amd64/instruction/control/Amd64RetZONear.h +++ b/src/backend/amd64/instruction/control/Amd64Ret.h @@ -5,12 +5,16 @@ namespace city { - class Amd46RetZONear : public Amd64Instruction + class Amd64Ret : public Amd64Instruction { public: - Amd46RetZONear() + static constexpr Amd64Ret ZONear() noexcept { - this->SetOpcode({0xC3}); + Amd64Ret inst; + + inst.SetOpcode({0xC3}); + + return inst; } }; } // namespace city diff --git a/src/backend/amd64/instruction/memory/Amd64Mov.h b/src/backend/amd64/instruction/memory/Amd64Mov.h new file mode 100644 index 0000000..8e7fcfe --- /dev/null +++ b/src/backend/amd64/instruction/memory/Amd64Mov.h @@ -0,0 +1,26 @@ +#ifndef CITY_AMD64MOVMR64_H +#define CITY_AMD64MOVMR64_H + +#include "backend/amd64/instruction/Amd64Instruction.h" + +namespace city +{ + // MR64 + class Amd64Mov : public Amd64Instruction + { + public: + static constexpr Amd64Mov MR64(Amd64RegisterCode dst, Amd64RegisterCode src) noexcept + { + Amd64Mov inst{}; + + auto rexw = static_cast(Amd64PrefixCode::REXW); + inst.SetPrefix({rexw}); + inst.SetOpcode({0x89}); + inst.SetModRM(src, dst, Amd64Mod::Register); + + return inst; + } + }; +} // namespace city + +#endif // CITY_AMD64MOVMR64_H diff --git a/src/backend/amd64/instruction/memory/Amd64MovMR64.h b/src/backend/amd64/instruction/memory/Amd64MovMR64.h deleted file mode 100644 index f79ed33..0000000 --- a/src/backend/amd64/instruction/memory/Amd64MovMR64.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CITY_AMD64MOVMR64_H -#define CITY_AMD64MOVMR64_H - -#include "backend/amd64/instruction/Amd64Instruction.h" - -namespace city -{ - class Amd64MovMR64 : public Amd64Instruction - { - public: - Amd64MovMR64(Amd64RegisterCode dst, Amd64RegisterCode src) - { - auto rexw = static_cast(Amd64PrefixCode::REXW); - this->SetPrefix({rexw}); - this->SetOpcode({0x89}); - this->SetModRM(src, dst, Amd64Mod::Register); - } - }; -} // namespace city - -#endif // CITY_AMD64MOVMR64_H diff --git a/src/backend/amd64/instruction/memory/Amd64PopO64.h b/src/backend/amd64/instruction/memory/Amd64Pop.h similarity index 58% rename from src/backend/amd64/instruction/memory/Amd64PopO64.h rename to src/backend/amd64/instruction/memory/Amd64Pop.h index 40ee155..b91a8f7 100644 --- a/src/backend/amd64/instruction/memory/Amd64PopO64.h +++ b/src/backend/amd64/instruction/memory/Amd64Pop.h @@ -5,13 +5,17 @@ namespace city { - class Amd64PopO64 : public Amd64Instruction + class Amd64Pop : public Amd64Instruction { public: - Amd64PopO64(Amd64RegisterCode reg) + static constexpr Amd64Pop O64(Amd64RegisterCode reg) noexcept { + Amd64Pop inst; + std::uint8_t opcode = 0x58 + static_cast(reg); - this->SetOpcode({opcode}); + inst.SetOpcode({opcode}); + + return inst; } }; } // namespace city diff --git a/src/backend/amd64/instruction/memory/Amd64PushO64.h b/src/backend/amd64/instruction/memory/Amd64Push.h similarity index 58% rename from src/backend/amd64/instruction/memory/Amd64PushO64.h rename to src/backend/amd64/instruction/memory/Amd64Push.h index 7643f63..856067a 100644 --- a/src/backend/amd64/instruction/memory/Amd64PushO64.h +++ b/src/backend/amd64/instruction/memory/Amd64Push.h @@ -5,13 +5,17 @@ namespace city { - class Amd64PushO64 : public Amd64Instruction + class Amd64Push : public Amd64Instruction { public: - Amd64PushO64(Amd64RegisterCode reg) + static constexpr Amd64Push O64(Amd64RegisterCode reg) noexcept { + Amd64Push inst{}; + std::uint8_t opcode = 0x50 + static_cast(reg); - this->SetOpcode({opcode}); + inst.SetOpcode({opcode}); + + return inst; } }; } // namespace city diff --git a/src/ir/IRModule.cpp b/src/ir/IRModule.cpp index 37cbf86..3a863c8 100644 --- a/src/ir/IRModule.cpp +++ b/src/ir/IRModule.cpp @@ -2,6 +2,11 @@ using namespace city; +std::string const &IRModule::GetName() const noexcept +{ + return this->name_; +} + Builder IRModule::CreateBuilder() noexcept { return Builder(*this); diff --git a/src/ir/IRModule.h b/src/ir/IRModule.h index 2d0c723..b5f53ba 100644 --- a/src/ir/IRModule.h +++ b/src/ir/IRModule.h @@ -26,6 +26,8 @@ namespace city std::vector> blocks_; public: + [[nodiscard]] std::string const &GetName() const noexcept; + [[nodiscard]] Builder CreateBuilder() noexcept; IRModule() = delete; diff --git a/src/ir/instruction/control/RetInst.cpp b/src/ir/instruction/control/RetInst.cpp index 8db7b09..2764f9d 100644 --- a/src/ir/instruction/control/RetInst.cpp +++ b/src/ir/instruction/control/RetInst.cpp @@ -8,4 +8,7 @@ void RetInst::Apply(IRTranslator *interface) interface->Translate(this); } -RetInst::RetInst(Value *value) : value_(value) {} +RetInst::RetInst(Value *value) +{ + this->SetReturnValue(value); +} diff --git a/test/amd64.test.cpp b/test/amd64.test.cpp index ee5a6cb..9e2510f 100644 --- a/test/amd64.test.cpp +++ b/test/amd64.test.cpp @@ -13,43 +13,43 @@ class Amd64TestRunner : public testing::Test TEST_F(Amd64TestRunner, ReturnVoidFunction) { - city::IRModule module{"test_return_void"}; + city::IRModule module{"test"}; auto builder = module.CreateBuilder(); - auto function = builder.CreateFunction("test_return_void"); + auto function = builder.CreateFunction("return_void"); builder.SetInsertPoint(function); builder.InsertRetInst(nullptr); - this->jit.AddIRModule(std::move(module)); + this->jit.InsertIRModule(std::move(module)); auto assembly = this->jit.CompileAndLink(); - auto test_symbol = assembly.Lookup("test_return_void"); + auto test_symbol = assembly.Lookup("return_void"); auto test = test_symbol.ToPointer(); test(); - this->jit.RemoveModule("test_return_void"); + this->jit.RemoveModule("test"); } TEST_F(Amd64TestRunner, ReturnConstantFunction) { - city::IRModule module{"test_return_constant"}; + city::IRModule module{"test"}; auto builder = module.CreateBuilder(); - auto function = builder.CreateFunction("test_return_constant"); + auto function = builder.CreateFunction("return_constant"); builder.SetInsertPoint(function); auto return_value = builder.CreateConstant(69); builder.InsertRetInst(return_value); - this->jit.AddIRModule(std::move(module)); + this->jit.InsertIRModule(std::move(module)); auto assembly = this->jit.CompileAndLink(); - auto test_symbol = assembly.Lookup("test_return_constant"); + auto test_symbol = assembly.Lookup("return_constant"); auto test = test_symbol.ToPointer(); ASSERT_EQ(test(), 69); - this->jit.RemoveModule("test_return_only"); + this->jit.RemoveModule("test"); }