aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/sirit/sirit.h14
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/literal.cpp37
-rw-r--r--src/op.cpp4
-rw-r--r--src/opcodes/constant.cpp6
-rw-r--r--src/operand.cpp75
-rw-r--r--src/operand.h36
-rw-r--r--tests/main.cpp7
8 files changed, 161 insertions, 19 deletions
diff --git a/include/sirit/sirit.h b/include/sirit/sirit.h
index aee03b6..b704cd6 100644
--- a/include/sirit/sirit.h
+++ b/include/sirit/sirit.h
@@ -19,6 +19,7 @@ static const std::uint32_t GeneratorMagicNumber = 0;
static const std::uint32_t Undefined = UINT32_MAX;
class Op;
+class Operand;
class Module {
public:
@@ -55,7 +56,7 @@ public:
* @return Returns op.
*/
const Op* Emit(const Op* op);
-
+
// Types
/// Returns type void.
@@ -128,6 +129,9 @@ public:
/// Returns a false scalar constant.
const Op* ConstantFalse(const Op* result_type);
+ /// Returns a numeric scalar constant.
+ const Op* Constant(const Op* result_type, Operand* literal);
+
// Function
/// Emits a function.
@@ -145,6 +149,14 @@ public:
/// Emits a return. It ends a block.
const Op* Return();
+ // Literals
+ static Operand* Literal(std::uint32_t value);
+ static Operand* Literal(std::uint64_t value);
+ static Operand* Literal(std::int32_t value);
+ static Operand* Literal(std::int64_t value);
+ static Operand* Literal(float value);
+ static Operand* Literal(double value);
+
private:
const Op* AddCode(Op* op);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e5c53ab..5610414 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,6 +7,7 @@ add_library(sirit
stream.h
operand.cpp
operand.h
+ literal.cpp
common_types.h
opcodes.h
opcodes/type.cpp
diff --git a/src/literal.cpp b/src/literal.cpp
new file mode 100644
index 0000000..79da059
--- /dev/null
+++ b/src/literal.cpp
@@ -0,0 +1,37 @@
+/* This file is part of the sirit project.
+ * Copyright (c) 2018 ReinUsesLisp
+ * This software may be used and distributed according to the terms of the GNU
+ * Lesser General Public License version 2.1 or any later version.
+ */
+
+#include "sirit/sirit.h"
+#include "common_types.h"
+#include "operand.h"
+
+namespace Sirit {
+
+Operand* Module::Literal(u32 value) {
+ return new LiteralNumber(value);
+}
+
+Operand* Module::Literal(u64 value) {
+ return new LiteralNumber(value);
+}
+
+Operand* Module::Literal(s32 value) {
+ return new LiteralNumber(value);
+}
+
+Operand* Module::Literal(s64 value) {
+ return new LiteralNumber(value);
+}
+
+Operand* Module::Literal(f32 value) {
+ return new LiteralNumber(value);
+}
+
+Operand* Module::Literal(f64 value) {
+ return new LiteralNumber(value);
+}
+
+} // namespace Sirit
diff --git a/src/op.cpp b/src/op.cpp
index a197126..52f0cc4 100644
--- a/src/op.cpp
+++ b/src/op.cpp
@@ -13,7 +13,7 @@ namespace Sirit {
Op::Op(spv::Op opcode_, u32 id_, const Op* result_type_)
: opcode(opcode_), id(id_), result_type(result_type_) {
- operand_type = OperandType::Ref;
+ operand_type = OperandType::Op;
}
Op::~Op() = default;
@@ -69,7 +69,7 @@ void Op::Add(const Operand* operand) {
}
void Op::Add(u32 integer) {
- Add(new LiteralInteger(integer));
+ Add(new LiteralNumber(integer));
}
void Op::Add(const std::string& string) {
diff --git a/src/opcodes/constant.cpp b/src/opcodes/constant.cpp
index 15a59d9..6df4e4b 100644
--- a/src/opcodes/constant.cpp
+++ b/src/opcodes/constant.cpp
@@ -18,4 +18,10 @@ const Op* Module::ConstantFalse(const Op* result_type) {
return AddDeclaration(new Op(spv::Op::OpConstantFalse, bound, result_type));
}
+const Op* Module::Constant(const Op* result_type, Operand* literal) {
+ Op* op{new Op(spv::Op::OpConstant, bound, result_type)};
+ op->Add(literal);
+ return AddDeclaration(op);
+}
+
} // namespace Sirit
diff --git a/src/operand.cpp b/src/operand.cpp
index 8c4329e..6123e9d 100644
--- a/src/operand.cpp
+++ b/src/operand.cpp
@@ -34,24 +34,79 @@ OperandType Operand::GetType() const {
return operand_type;
}
-LiteralInteger::LiteralInteger(u32 integer_)
- : integer(integer_) {
- operand_type = OperandType::Integer;
+LiteralNumber::LiteralNumber() {
+ operand_type = OperandType::Number;
}
-LiteralInteger::~LiteralInteger() = default;
+LiteralNumber::LiteralNumber(u32 number)
+ : uint32(number), type(NumberType::U32) {
+ LiteralNumber();
+}
+
+LiteralNumber::LiteralNumber(s32 number)
+ : int32(number), type(NumberType::S32) {
+ LiteralNumber();
+}
+
+LiteralNumber::LiteralNumber(f32 number)
+ : float32(number), type(NumberType::F32) {
+ LiteralNumber();
+}
+
+LiteralNumber::LiteralNumber(u64 number)
+ : uint64(number), type(NumberType::U64) {
+ LiteralNumber();
+}
-void LiteralInteger::Fetch(Stream& stream) const {
- stream.Write(integer);
+LiteralNumber::LiteralNumber(s64 number)
+ : int64(number), type(NumberType::S64) {
+ LiteralNumber();
}
-u16 LiteralInteger::GetWordCount() const {
- return 1;
+LiteralNumber::LiteralNumber(f64 number)
+ : float64(number), type(NumberType::F64) {
+ LiteralNumber();
+}
+
+LiteralNumber::~LiteralNumber() = default;
+
+void LiteralNumber::Fetch(Stream& stream) const {
+ switch (type) {
+ case NumberType::S32:
+ case NumberType::U32:
+ case NumberType::F32:
+ stream.Write(uint32);
+ break;
+ case NumberType::S64:
+ case NumberType::U64:
+ case NumberType::F64:
+ stream.Write(uint64);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+u16 LiteralNumber::GetWordCount() const {
+ switch (type) {
+ case NumberType::S32:
+ case NumberType::U32:
+ case NumberType::F32:
+ return 1;
+ case NumberType::S64:
+ case NumberType::U64:
+ case NumberType::F64:
+ return 2;
+ default:
+ assert(0);
+ return 0;
+ }
}
-bool LiteralInteger::operator==(const Operand& other) const {
+bool LiteralNumber::operator==(const Operand& other) const {
if (operand_type == other.GetType()) {
- return dynamic_cast<const LiteralInteger&>(other).integer == integer;
+ const auto& o{dynamic_cast<const LiteralNumber&>(other)};
+ return o.type == type && o.raw == raw;
}
return false;
}
diff --git a/src/operand.h b/src/operand.h
index 8bb5127..6f2765e 100644
--- a/src/operand.h
+++ b/src/operand.h
@@ -12,8 +12,8 @@ namespace Sirit {
enum class OperandType {
Invalid,
- Ref,
- Integer,
+ Op,
+ Number,
String
};
@@ -34,10 +34,15 @@ protected:
OperandType operand_type{};
};
-class LiteralInteger : public Operand {
+class LiteralNumber : public Operand {
public:
- LiteralInteger(u32 integer);
- ~LiteralInteger();
+ LiteralNumber(u32 number);
+ LiteralNumber(s32 number);
+ LiteralNumber(f32 number);
+ LiteralNumber(u64 number);
+ LiteralNumber(s64 number);
+ LiteralNumber(f64 number);
+ ~LiteralNumber();
virtual void Fetch(Stream& stream) const;
virtual u16 GetWordCount() const;
@@ -45,7 +50,26 @@ public:
virtual bool operator==(const Operand& other) const;
private:
- u32 integer;
+ LiteralNumber();
+
+ enum class NumberType {
+ U32,
+ S32,
+ F32,
+ U64,
+ S64,
+ F64
+ } type;
+
+ union {
+ u64 raw{};
+ u32 uint32;
+ s32 int32;
+ u64 uint64;
+ s64 int64;
+ f32 float32;
+ f64 float64;
+ };
};
class LiteralString : public Operand {
diff --git a/tests/main.cpp b/tests/main.cpp
index f793f01..7a3236b 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -41,6 +41,13 @@ public:
ConstantTrue(TypeBool());
ConstantTrue(TypeBool());
ConstantFalse(TypeBool());
+ Constant(TypeFloat(64), Literal(6342.2));
+ Constant(TypeFloat(64), Literal(6342.21));
+ Constant(TypeFloat(32), Literal(6342.21f));
+ Constant(TypeFloat(16), Literal(30u));
+ Constant(TypeInt(32, false), Literal(30u));
+ Constant(TypeInt(16, false), Literal(30u));
+ Constant(TypeInt(8, false), Literal(30u));
auto main_type{TypeFunction(TypeVoid())};
auto main_func{Emit(Function(TypeVoid(), spv::FunctionControlMask::MaskNone, main_type))};