Skip to content

Commit 9183e2b

Browse files
committed
LLVMCodeBuilder: Implement divide operator
1 parent 31a4e36 commit 9183e2b

File tree

5 files changed

+81
-0
lines changed

5 files changed

+81
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class ICodeBuilder
2727
virtual void createAdd() = 0;
2828
virtual void createSub() = 0;
2929
virtual void createMul() = 0;
30+
virtual void createDiv() = 0;
31+
3032
virtual void beginIfStatement() = 0;
3133
virtual void beginElseBranch() = 0;
3234
virtual void endIf() = 0;

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
118118
break;
119119
}
120120

121+
case Step::Type::Div: {
122+
assert(step.args.size() == 2);
123+
const auto &arg1 = step.args[0];
124+
const auto &arg2 = step.args[1];
125+
llvm::Value *num1 = removeNaN(castValue(arg1.second, arg1.first));
126+
llvm::Value *num2 = removeNaN(castValue(arg2.second, arg2.first));
127+
step.functionReturnReg->value = m_builder.CreateFDiv(num1, num2);
128+
break;
129+
}
130+
121131
case Step::Type::Yield:
122132
if (!m_warp) {
123133
freeHeap();
@@ -457,6 +467,11 @@ void LLVMCodeBuilder::createMul()
457467
createOp(Step::Type::Mul, 2);
458468
}
459469

470+
void LLVMCodeBuilder::createDiv()
471+
{
472+
createOp(Step::Type::Div, 2);
473+
}
474+
460475
void LLVMCodeBuilder::beginIfStatement()
461476
{
462477
Step step(Step::Type::BeginIf);

src/dev/engine/internal/llvmcodebuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class LLVMCodeBuilder : public ICodeBuilder
2929
void createAdd() override;
3030
void createSub() override;
3131
void createMul() override;
32+
void createDiv() override;
33+
3234
void beginIfStatement() override;
3335
void beginElseBranch() override;
3436
void endIf() override;
@@ -64,6 +66,7 @@ class LLVMCodeBuilder : public ICodeBuilder
6466
Add,
6567
Sub,
6668
Mul,
69+
Div,
6770
Yield,
6871
BeginIf,
6972
BeginElse,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,65 @@ TEST_F(LLVMCodeBuilderTest, Multiply)
340340
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
341341
}
342342

343+
TEST_F(LLVMCodeBuilderTest, Divide)
344+
{
345+
std::string expected;
346+
347+
auto addOpTest = [this, &expected](Value v1, Value v2, double expectedResult) {
348+
m_builder->addConstValue(v1);
349+
m_builder->addConstValue(v2);
350+
m_builder->createDiv();
351+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
352+
353+
m_builder->addConstValue(v1);
354+
m_builder->addFunctionCall("test_const_number", Compiler::StaticType::Number, { Compiler::StaticType::Number });
355+
m_builder->addConstValue(v2);
356+
m_builder->addFunctionCall("test_const_number", Compiler::StaticType::Number, { Compiler::StaticType::Number });
357+
m_builder->createDiv();
358+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
359+
360+
std::string str = Value(expectedResult).toString() + '\n';
361+
expected += str;
362+
expected += str;
363+
};
364+
365+
createBuilder(true);
366+
367+
addOpTest(50, 2, 25);
368+
addOpTest(-500, 25, -20);
369+
addOpTest("-500", -25, 20);
370+
addOpTest("3.5", "2.5", 1.4);
371+
addOpTest(true, true, 1);
372+
addOpTest("Infinity", "Infinity", std::numeric_limits<double>::quiet_NaN());
373+
addOpTest("Infinity", 0, std::numeric_limits<double>::infinity());
374+
addOpTest("Infinity", 2, std::numeric_limits<double>::infinity());
375+
addOpTest("Infinity", -2, -std::numeric_limits<double>::infinity());
376+
addOpTest("Infinity", "-Infinity", std::numeric_limits<double>::quiet_NaN());
377+
addOpTest("-Infinity", "Infinity", std::numeric_limits<double>::quiet_NaN());
378+
addOpTest("-Infinity", 0, -std::numeric_limits<double>::infinity());
379+
addOpTest("-Infinity", 2, -std::numeric_limits<double>::infinity());
380+
addOpTest("-Infinity", -2, std::numeric_limits<double>::infinity());
381+
addOpTest("-Infinity", "-Infinity", std::numeric_limits<double>::quiet_NaN());
382+
addOpTest(0, "Infinity", 0);
383+
addOpTest(2, "Infinity", 0);
384+
addOpTest(-2, "Infinity", 0);
385+
addOpTest(0, "-Infinity", 0);
386+
addOpTest(2, "-Infinity", 0);
387+
addOpTest(-2, "-Infinity", 0);
388+
addOpTest(1, "NaN", std::numeric_limits<double>::infinity());
389+
addOpTest("NaN", 1, 0);
390+
addOpTest(5, 0, std::numeric_limits<double>::infinity());
391+
addOpTest(-5, 0, -std::numeric_limits<double>::infinity());
392+
addOpTest(0, 0, std::numeric_limits<double>::quiet_NaN());
393+
394+
auto code = m_builder->finalize();
395+
auto ctx = code->createExecutionContext(&m_target);
396+
397+
testing::internal::CaptureStdout();
398+
code->run(ctx.get());
399+
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
400+
}
401+
343402
TEST_F(LLVMCodeBuilderTest, Yield)
344403
{
345404
auto build = [this]() {

test/mocks/codebuildermock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class CodeBuilderMock : public ICodeBuilder
1717
MOCK_METHOD(void, createAdd, (), (override));
1818
MOCK_METHOD(void, createSub, (), (override));
1919
MOCK_METHOD(void, createMul, (), (override));
20+
MOCK_METHOD(void, createDiv, (), (override));
21+
2022
MOCK_METHOD(void, beginIfStatement, (), (override));
2123
MOCK_METHOD(void, beginElseBranch, (), (override));
2224
MOCK_METHOD(void, endIf, (), (override));

0 commit comments

Comments
 (0)