Skip to content

Commit 0e05e37

Browse files
committed
LLVMCodeBuilder: Implement select instruction
1 parent 24b1866 commit 0e05e37

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class ICodeBuilder
5858
virtual CompilerValue *createExp(CompilerValue *num) = 0;
5959
virtual CompilerValue *createExp10(CompilerValue *num) = 0;
6060

61+
virtual CompilerValue *createSelect(CompilerValue *cond, CompilerValue *trueValue, CompilerValue *falseValue, Compiler::StaticType valueType) = 0;
62+
6163
virtual void createVariableWrite(Variable *variable, CompilerValue *value) = 0;
6264

6365
virtual void createListClear(List *list) = 0;

src/dev/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,18 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
446446
break;
447447
}
448448

449+
case LLVMInstruction::Type::Select: {
450+
assert(step.args.size() == 3);
451+
const auto &arg1 = step.args[0];
452+
const auto &arg2 = step.args[1];
453+
const auto &arg3 = step.args[2];
454+
llvm::Value *cond = castValue(arg1.second, arg1.first);
455+
llvm::Value *trueValue = castValue(arg2.second, arg2.first);
456+
llvm::Value *falseValue = castValue(arg3.second, arg3.first);
457+
step.functionReturnReg->value = m_builder.CreateSelect(cond, trueValue, falseValue);
458+
break;
459+
}
460+
449461
case LLVMInstruction::Type::WriteVariable: {
450462
assert(step.args.size() == 1);
451463
assert(m_variablePtrs.find(step.workVariable) != m_variablePtrs.cend());
@@ -1125,6 +1137,11 @@ CompilerValue *LLVMCodeBuilder::createExp10(CompilerValue *num)
11251137
return createOp(LLVMInstruction::Type::Exp10, Compiler::StaticType::Number, Compiler::StaticType::Number, { num });
11261138
}
11271139

1140+
CompilerValue *LLVMCodeBuilder::createSelect(CompilerValue *cond, CompilerValue *trueValue, CompilerValue *falseValue, Compiler::StaticType valueType)
1141+
{
1142+
return createOp(LLVMInstruction::Type::Select, valueType, { Compiler::StaticType::Bool, valueType, valueType }, { cond, trueValue, falseValue });
1143+
}
1144+
11281145
void LLVMCodeBuilder::createVariableWrite(Variable *variable, CompilerValue *value)
11291146
{
11301147
LLVMInstruction ins(LLVMInstruction::Type::WriteVariable);

src/dev/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ class LLVMCodeBuilder : public ICodeBuilder
6565
CompilerValue *createExp(CompilerValue *num) override;
6666
CompilerValue *createExp10(CompilerValue *num) override;
6767

68+
CompilerValue *createSelect(CompilerValue *cond, CompilerValue *trueValue, CompilerValue *falseValue, Compiler::StaticType valueType) override;
69+
6870
void createVariableWrite(Variable *variable, CompilerValue *value) override;
6971

7072
void createListClear(List *list) override;

src/dev/engine/internal/llvm/llvminstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct LLVMInstruction
4040
Log10,
4141
Exp,
4242
Exp10,
43+
Select,
4344
WriteVariable,
4445
ReadVariable,
4546
ClearList,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,79 @@ TEST_F(LLVMCodeBuilderTest, WriteVariable)
13811381
ASSERT_EQ(localVar3->value(), true);
13821382
}
13831383

1384+
TEST_F(LLVMCodeBuilderTest, Select)
1385+
{
1386+
EngineMock engine;
1387+
Stage stage;
1388+
Sprite sprite;
1389+
sprite.setEngine(&engine);
1390+
EXPECT_CALL(engine, stage()).WillRepeatedly(Return(&stage));
1391+
1392+
createBuilder(&sprite, true);
1393+
1394+
// Number
1395+
CompilerValue *v = m_builder->addConstValue(true);
1396+
v = m_builder->createSelect(v, m_builder->addConstValue(5.8), m_builder->addConstValue(-17.42), Compiler::StaticType::Number);
1397+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number }, { v });
1398+
1399+
v = m_builder->addConstValue(false);
1400+
v = m_builder->createSelect(v, m_builder->addConstValue(5.8), m_builder->addConstValue(-17.42), Compiler::StaticType::Number);
1401+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number }, { v });
1402+
1403+
// Bool
1404+
v = m_builder->addConstValue(true);
1405+
v = m_builder->createSelect(v, m_builder->addConstValue(true), m_builder->addConstValue(false), Compiler::StaticType::Bool);
1406+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool }, { v });
1407+
1408+
v = m_builder->addConstValue(false);
1409+
v = m_builder->createSelect(v, m_builder->addConstValue(true), m_builder->addConstValue(false), Compiler::StaticType::Bool);
1410+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool }, { v });
1411+
1412+
// String
1413+
v = m_builder->addConstValue(true);
1414+
v = m_builder->createSelect(v, m_builder->addConstValue("hello"), m_builder->addConstValue("world"), Compiler::StaticType::String);
1415+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String }, { v });
1416+
1417+
v = m_builder->addConstValue(false);
1418+
v = m_builder->createSelect(v, m_builder->addConstValue("hello"), m_builder->addConstValue("world"), Compiler::StaticType::String);
1419+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String }, { v });
1420+
1421+
// Different types
1422+
v = m_builder->addConstValue(true);
1423+
v = m_builder->createSelect(v, m_builder->addConstValue("543"), m_builder->addConstValue("true"), Compiler::StaticType::Number);
1424+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number }, { v });
1425+
1426+
v = m_builder->addConstValue(false);
1427+
v = m_builder->createSelect(v, m_builder->addConstValue("543"), m_builder->addConstValue("true"), Compiler::StaticType::Number);
1428+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number }, { v });
1429+
1430+
v = m_builder->addConstValue(true);
1431+
v = m_builder->createSelect(v, m_builder->addConstValue(1), m_builder->addConstValue("false"), Compiler::StaticType::Bool);
1432+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool }, { v });
1433+
1434+
v = m_builder->addConstValue(false);
1435+
v = m_builder->createSelect(v, m_builder->addConstValue(1), m_builder->addConstValue("false"), Compiler::StaticType::Bool);
1436+
m_builder->addFunctionCall("test_print_bool", Compiler::StaticType::Void, { Compiler::StaticType::Bool }, { v });
1437+
1438+
static const std::string expected =
1439+
"5.8\n"
1440+
"-17.42\n"
1441+
"1\n"
1442+
"0\n"
1443+
"hello\n"
1444+
"world\n"
1445+
"543\n"
1446+
"0\n"
1447+
"1\n"
1448+
"0\n";
1449+
1450+
auto code = m_builder->finalize();
1451+
testing::internal::CaptureStdout();
1452+
auto ctx = code->createExecutionContext(&sprite);
1453+
code->run(ctx.get());
1454+
ASSERT_EQ(testing::internal::GetCapturedStdout(), expected);
1455+
}
1456+
13841457
TEST_F(LLVMCodeBuilderTest, ReadVariable)
13851458
{
13861459
EngineMock engine;

test/mocks/codebuildermock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ class CodeBuilderMock : public ICodeBuilder
4848
MOCK_METHOD(CompilerValue *, createExp, (CompilerValue *), (override));
4949
MOCK_METHOD(CompilerValue *, createExp10, (CompilerValue *), (override));
5050

51+
MOCK_METHOD(CompilerValue *, createSelect, (CompilerValue *, CompilerValue *, CompilerValue *, Compiler::StaticType), (override));
52+
5153
MOCK_METHOD(void, createVariableWrite, (Variable *, CompilerValue *), (override));
5254

5355
MOCK_METHOD(void, createListClear, (List *), (override));

0 commit comments

Comments
 (0)