summaryrefslogtreecommitdiff
path: root/Type.cc
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-15 21:16:26 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-15 21:16:26 +0800
commit41f6e75e3f26bdcccfcb3910f202452e14653826 (patch)
tree0076a928d4ac9737f8b83b7b6b0c055e5ff4f46a /Type.cc
parentd80958f987790f533f5048c2e0e8a1cd5fd9f5a1 (diff)
basic support of types
Diffstat (limited to 'Type.cc')
-rw-r--r--Type.cc212
1 files changed, 212 insertions, 0 deletions
diff --git a/Type.cc b/Type.cc
new file mode 100644
index 0000000..4e3dd86
--- /dev/null
+++ b/Type.cc
@@ -0,0 +1,212 @@
+#include <llvm/IR/InstrTypes.h>
+
+#include "Type.hh"
+
+namespace pcc {
+Type::Type(const char* name, bool IsBasicType, int width)
+ : name_(name)
+ , IsBasicType_(IsBasicType)
+ , width_(width) {}
+
+const char* Type::GetCommonName() { return name_; }
+
+int Type::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ return NotAllowed(v0, v1, context);
+}
+
+int Type::NotAllowed(Value v0, Value v1, Context* context) { return -1; }
+
+int Type::CreateAdd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Add, v0, v1);
+ return 0;
+}
+
+int Type::CreateSub(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Sub, v0, v1);
+ return 0;
+}
+
+int Type::CreateMul(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Mul, v0, v1);
+ return 0;
+}
+
+int Type::CreateDiv(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::SDiv, v0, v1);
+ return 0;
+}
+
+int Type::CreateMod(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::SRem, v0, v1);
+ return 0;
+}
+
+int Type::CreateLt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SLT, v0, v1);
+ return 0;
+}
+
+int Type::CreateLe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SLE, v0, v1);
+ return 0;
+}
+
+int Type::CreateGt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SGT, v0, v1);
+ return 0;
+}
+
+int Type::CreateGe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_SGE, v0, v1);
+ return 0;
+}
+
+int Type::CreateEq(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_EQ, v0, v1);
+ return 0;
+}
+
+int Type::CreateNe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateICmp(llvm::CmpInst::ICMP_NE, v0, v1);
+ return 0;
+}
+
+int Type::CreateAnd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::And, v0, v1);
+ return 0;
+}
+
+int Type::CreateOr(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Or, v0, v1);
+ return 0;
+}
+
+int Type::CreateXor(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::Xor, v0, v1);
+ return 0;
+}
+
+int Type::CreateFAdd(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FAdd, v0, v1);
+ return 0;
+}
+
+int Type::CreateFSub(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FSub, v0, v1);
+ return 0;
+}
+
+int Type::CreateFMul(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FMul, v0, v1);
+ return 0;
+}
+
+int Type::CreateFDiv(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FDiv, v0, v1);
+ return 0;
+}
+
+int Type::CreateFMod(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateBinOp(llvm::Instruction::FRem, v0, v1);
+ return 0;
+}
+
+int Type::CreateFLt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OLT, v0, v1);
+ return 0;
+}
+
+int Type::CreateFLe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OLE, v0, v1);
+ return 0;
+}
+
+int Type::CreateFGt(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OGT, v0, v1);
+ return 0;
+}
+
+int Type::CreateFGe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OGE, v0, v1);
+ return 0;
+}
+
+int Type::CreateFEq(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_OEQ, v0, v1);
+ return 0;
+}
+
+int Type::CreateFNe(Value v0, Value v1, Context* context) {
+ context->GetBuilder()->CreateFCmp(llvm::CmpInst::FCMP_ONE, v0, v1);
+ return 0;
+}
+
+BooleanType::BooleanType()
+ : Type("boolean", true, 1) {}
+
+int BooleanType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::BooleanType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::NotAllowed,
+ &BooleanType::NotAllowed, &BooleanType::CreateEq,
+ &BooleanType::CreateNe, &BooleanType::CreateAnd,
+ &BooleanType::CreateOr, &BooleanType::CreateXor,
+ &BooleanType::NotAllowed,
+ };
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+CharType::CharType()
+ : Type("char", true, 8) {}
+
+int CharType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::CharType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &CharType::CreateAdd, &CharType::CreateSub, &CharType::CreateMul,
+ &CharType::CreateDiv, &CharType::CreateMod, &CharType::CreateLt,
+ &CharType::CreateLe, &CharType::CreateGt, &CharType::CreateGe,
+ &CharType::CreateEq, &CharType::CreateNe, &CharType::CreateAnd,
+ &CharType::CreateOr, &CharType::CreateXor, &CharType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+IntegerType::IntegerType()
+ : Type("integer", true, 32) {}
+
+int IntegerType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::IntegerType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &IntegerType::CreateAdd, &IntegerType::CreateSub,
+ &IntegerType::CreateMul, &IntegerType::CreateDiv,
+ &IntegerType::CreateMod, &IntegerType::CreateLt,
+ &IntegerType::CreateLe, &IntegerType::CreateGt,
+ &IntegerType::CreateGe, &IntegerType::CreateEq,
+ &IntegerType::CreateNe, &IntegerType::CreateAnd,
+ &IntegerType::CreateOr, &IntegerType::CreateXor,
+ &IntegerType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+RealType::RealType()
+ : Type("real", true, 32) {}
+
+int RealType::CreateBinaryOperation(BinaryOperator op, Value v0, Value v1,
+ Context* context) {
+ static int (pcc::RealType::*operations[ToUnderlying(
+ BinaryOperator::OPERATOR_NUMBER)])(Value, Value, Context*) = {
+ &RealType::CreateFAdd, &RealType::CreateFSub, &RealType::CreateFMul,
+ &RealType::CreateFDiv, &RealType::CreateFMod, &RealType::CreateFLt,
+ &RealType::CreateFLe, &RealType::CreateFGt, &RealType::CreateFGe,
+ &RealType::CreateFEq, &RealType::CreateFNe, &RealType::NotAllowed,
+ &RealType::NotAllowed, &RealType::NotAllowed, &RealType::NotAllowed};
+ return (this->*operations[ToUnderlying(op)])(v0, v1, context);
+}
+
+} // namespace pcc \ No newline at end of file