Skip to content

Commit

Permalink
some addition impl;
Browse files Browse the repository at this point in the history
  • Loading branch information
NateSeymour committed Jan 12, 2025
1 parent 3537324 commit b56dc1f
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 46 deletions.
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ add_library(city
src/backend/amd64/Amd64Translator.h
src/backend/amd64/instruction/Amd64Instruction.cpp
src/backend/amd64/instruction/Amd64Instruction.h
src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h
src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h
src/backend/amd64/instruction/control/Amd64Ret.h
src/backend/amd64/instruction/memory/Amd64Mov.h
src/backend/amd64/instruction/memory/Amd64Pop.h
Expand Down Expand Up @@ -84,6 +82,9 @@ add_library(city
src/value/ConstantValue.h
src/value/Value.cpp
src/value/Value.h
src/ir/instruction/IRBinaryInstruction.cpp
src/ir/instruction/IRBinaryInstruction.h
src/backend/amd64/instruction/arithmetic/Amd64Add.h
)
target_include_directories(city PUBLIC src)

Expand Down
8 changes: 7 additions & 1 deletion src/backend/amd64/Amd64Builder.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Amd64Builder.h"

#include "instruction/arithmetic/Amd64Add.h"
#include "instruction/control/Amd64Ret.h"
#include "instruction/memory/Amd64Mov.h"
#include "instruction/memory/Amd64Pop.h"
Expand All @@ -21,6 +22,11 @@ Amd64Register *Amd64Builder::FindUnusedRegister() const noexcept
return nullptr;
}

void Amd64Builder::InsertAddInst(Amd64RegisterCode dst, Amd64RegisterCode src)
{
this->module_.InsertInstruction(Amd64Add::MR64(dst, src));
}

void Amd64Builder::InsertReturnInst(Amd64ReturnType return_type) const
{
switch (return_type)
Expand Down Expand Up @@ -73,7 +79,7 @@ Amd64Register *Amd64Builder::MoveValueToRegister(Value *value, Amd64RegisterCode
{
this->module_.InsertInstruction(Amd64Mov::OIX(reg, value->GetDataBuffer()));
}

return &physical_reg;
}

Expand Down
1 change: 1 addition & 0 deletions src/backend/amd64/Amd64Builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace city

[[nodiscard]] Amd64Register *FindUnusedRegister() const noexcept;

void InsertAddInst(Amd64RegisterCode dst, Amd64RegisterCode src);
void InsertReturnInst(Amd64ReturnType return_type = Amd64ReturnType::Near) const;
void InsertPopInst(Amd64RegisterCode reg);

Expand Down
5 changes: 5 additions & 0 deletions src/backend/amd64/Amd64Register.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@

using namespace city;

Amd64RegisterCode Amd64Register::GetCode() const noexcept
{
return this->code_;
}

Amd64Register::Amd64Register(Amd64RegisterCode code) : code_(code) {}
4 changes: 3 additions & 1 deletion src/backend/amd64/Amd64Register.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ namespace city
class Amd64Register : public Container
{
friend class Amd64Builder;

protected:
Amd64RegisterCode code_;

public:
[[nodiscard]] Amd64RegisterCode GetCode() const noexcept;

Amd64Register(Amd64RegisterCode code);
};
} // namespace city
Expand Down
10 changes: 9 additions & 1 deletion src/backend/amd64/Amd64Translator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@

using namespace city;

IRTranslationResult Amd64Translator::Translate(AddInst *instruction) {}
IRTranslationResult Amd64Translator::Translate(AddInst *instruction)
{
auto lhs = this->builder.MoveValueToUnusedRegister(instruction->GetLHS());
auto rhs = this->builder.MoveValueToUnusedRegister(instruction->GetRHS());

this->builder.InsertAddInst(lhs->GetCode(), rhs->GetCode());

return {};
}

IRTranslationResult Amd64Translator::Translate(BranchInst *instruction) {}

Expand Down
25 changes: 25 additions & 0 deletions src/backend/amd64/instruction/arithmetic/Amd64Add.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef AMD64ADD_H
#define AMD64ADD_H

#include "backend/amd64/instruction/Amd64Instruction.h"

namespace city
{
class Amd64Add : public Amd64Instruction
{
public:
static constexpr Amd64Add MR64(Amd64RegisterCode dst, Amd64RegisterCode src)
{
Amd64Add inst;

auto rexw = static_cast<std::uint8_t>(Amd64PrefixCode::REXW);
inst.SetPrefix({rexw});
inst.SetOpcode({0x01});
inst.SetModRM(src, dst, Amd64Mod::Register);

return inst;
}
};
} // namespace city

#endif // AMD64ADD_H
13 changes: 0 additions & 13 deletions src/backend/amd64/instruction/arithmetic/Amd64AddMI32Inst.h

This file was deleted.

22 changes: 0 additions & 22 deletions src/backend/amd64/instruction/arithmetic/Amd64AddRM32Inst.h

This file was deleted.

15 changes: 15 additions & 0 deletions src/ir/instruction/IRBinaryInstruction.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "IRBinaryInstruction.h"

using namespace city;

Value *IRBinaryInstruction::GetLHS() const noexcept
{
return this->lhs_;
}

Value *IRBinaryInstruction::GetRHS() const noexcept
{
return this->rhs_;
}

IRBinaryInstruction::IRBinaryInstruction(Value *lhs, Value *rhs) : lhs_(lhs), rhs_(rhs) {}
23 changes: 23 additions & 0 deletions src/ir/instruction/IRBinaryInstruction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef IRBINARYINSTRUCTION_H
#define IRBINARYINSTRUCTION_H

#include "IRInstruction.h"
#include "value/Value.h"

namespace city
{
class IRBinaryInstruction : public IRInstruction
{
protected:
Value *lhs_;
Value *rhs_;

public:
[[nodiscard]] Value *GetLHS() const noexcept;
[[nodiscard]] Value *GetRHS() const noexcept;

IRBinaryInstruction(Value *lhs, Value *rhs);
};
} // namespace city

#endif // IRBINARYINSTRUCTION_H
2 changes: 1 addition & 1 deletion src/ir/instruction/arithmetic/AddInst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ bool AddInst::HasReturnValue() const noexcept
return true;
}

AddInst::AddInst(Value *lhs, Value *rhs) : lhs_(lhs), rhs_(rhs) {}
AddInst::AddInst(Value *lhs, Value *rhs) : IRBinaryInstruction(lhs, rhs) {}
7 changes: 2 additions & 5 deletions src/ir/instruction/arithmetic/AddInst.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
#ifndef CITY_ADDINST_H
#define CITY_ADDINST_H

#include "ir/instruction/IRInstruction.h"
#include "ir/instruction/IRBinaryInstruction.h"

namespace city
{
class AddInst : public IRInstruction
class AddInst : public IRBinaryInstruction
{
Value *lhs_;
Value *rhs_;

public:
void Apply(IRTranslator *interface) override;

Expand Down
28 changes: 28 additions & 0 deletions test/amd64.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,31 @@ TEST_F(Amd64TestRunner, ReturnConstantFunction)

this->jit.RemoveModule("test");
}

TEST_F(Amd64TestRunner, AddConstantFunction)
{
int const X_VALUE = 69;
int const Y_VALUE = 420;
int const EXPECTED_RETURN_VALUE = X_VALUE + Y_VALUE;

city::IRModule module{"test"};
auto builder = module.CreateBuilder();

auto return_type = builder.GetType<int>();
(void)builder.CreateFunction("add_constants", return_type);

auto x_value = builder.CreateConstant<int>(X_VALUE);
auto y_value = builder.CreateConstant<int>(Y_VALUE);
auto return_value = builder.InsertAddInst(x_value, y_value);

builder.InsertRetInst(return_value->GetReturnValue());

this->jit.InsertIRModule(std::move(module));
auto assembly = this->jit.CompileAndLink();

auto test = assembly["add_constants"].ToPointer<int()>();

ASSERT_EQ(test(), EXPECTED_RETURN_VALUE);

this->jit.RemoveModule("test");
}

0 comments on commit b56dc1f

Please sign in to comment.