3 #include <core/assert.hh>
5 #include "llvm-generator-visitor.hh"
9 LLVMGeneratorVisitor::LLVMGeneratorVisitor(std::ostream
& out
)
14 assert_msg(out
.good(), "The output for llvm assembly is not valid.");
16 //out_.setf(std::ios::hex, std::ios::basefield);
17 //out_.setf(std::ios::showbase);
20 #define ADD_CAST_TABLE_ENTRY(Type1, Type2, Method) \
22 castTableKey_t key = std::make_pair(Type1::nodeTypeId(), \
23 Type2::nodeTypeId()); \
24 assert_msg(!castTable_.count(key), \
25 "the same key has been insterted two times"); \
26 castTable_[key] = &LLVMGeneratorVisitor::Method; \
29 ADD_CAST_TABLE_ENTRY(BoolType
, BoolType
, castBoolToBool
);
30 ADD_CAST_TABLE_ENTRY(BoolType
, FloatType
, castBoolToFloat
);
31 ADD_CAST_TABLE_ENTRY(BoolType
, DoubleType
, castBoolToDouble
);
32 ADD_CAST_TABLE_ENTRY(IntegerType
, IntegerType
, castIntegerToInteger
);
33 ADD_CAST_TABLE_ENTRY(FloatType
, DoubleType
, castFloatToDouble
);
36 LLVMGeneratorVisitor::~LLVMGeneratorVisitor()
41 LLVMGeneratorVisitor::visit(const Function
& node
)
43 out_
<< "define void @" << node
.name
<< "() {" << std::endl
;
45 out_
<< " ret void" << std::endl
50 LLVMGeneratorVisitor::visit(const VarDecl
& node
)
54 out_
<< " %" << node
.name
<< " = alloca ";
55 node
.type
->accept(*this);
60 LLVMGeneratorVisitor::visit(const LoadVar
& node
)
64 out_
<< " %" << node
.to
<< " = load ";
65 node
.type
->accept(*this);
66 out_
<< " * %" << node
.name
<< std::endl
;
70 LLVMGeneratorVisitor::visit(const StoreVar
& node
)
73 assert(node
.value
->type
);
76 node
.value
->type
->accept(*this);
77 node
.value
->accept(*this);
79 node
.value
->type
->accept(*this);
80 out_
<< " * %" << node
.name
<< std::endl
;
84 LLVMGeneratorVisitor::visit(const AssignExp
& node
)
86 out_
<< " %" << node
.dest
->name
<< " = ";
87 node
.value
->accept(*this);
91 #define GEN_BINARY_EXP(Type, Instr) \
93 LLVMGeneratorVisitor::visit(const Type & node) \
96 node.type->accept(*this); \
97 node.left->accept(*this); \
99 node.right->accept(*this); \
102 GEN_BINARY_EXP(AddExp
, "add")
103 GEN_BINARY_EXP(SubExp
, "sub")
104 GEN_BINARY_EXP(MulExp
, "mul")
105 GEN_BINARY_EXP(DivExp
, "sdiv") /// @todo play with udiv and sdiv instructions
106 GEN_BINARY_EXP(ModExp
, "srem") /// @todo play with urem and srem instructions
108 GEN_BINARY_EXP(AndExp
, "and")
109 GEN_BINARY_EXP(OrExp
, "or")
110 GEN_BINARY_EXP(XorExp
, "xor")
112 GEN_BINARY_EXP(ShlExp
, "shl")
113 GEN_BINARY_EXP(AShrExp
, "ashr")
114 GEN_BINARY_EXP(LShrExp
, "lshr")
116 GEN_BINARY_EXP(EqExp
, "icmp eq")
117 GEN_BINARY_EXP(NeqExp
, "icmp ne")
118 GEN_BINARY_EXP(LtExp
, "icmp slt")
119 GEN_BINARY_EXP(LtEqExp
, "icmp sle")
120 GEN_BINARY_EXP(GtExp
, "icmp sgt")
121 GEN_BINARY_EXP(GtEqExp
, "icmp sge")
124 // LLVMGeneratorVisitor::visit(const EqExp & node)
130 LLVMGeneratorVisitor::visit(const IdExp
& node
)
132 out_
<< "%" << node
.name
;
136 LLVMGeneratorVisitor::visit(const TmpResultExp
& node
)
138 out_
<< "%" << node
.name
;
142 LLVMGeneratorVisitor::visit(const NumberExp
& node
)
144 if (node
.type
->nodeType
== FloatType::nodeTypeId())
145 out_
<< std::setprecision(1000) << (float)node
.number
;
147 out_
<< std::setprecision(1000) << node
.number
;
151 LLVMGeneratorVisitor::visit(const Label
& node
)
153 out_
<< " br label %" << node
.name
<< " ; dummy branch to start a block" << std::endl
154 << node
.name
<< ":" << std::endl
;
158 LLVMGeneratorVisitor::visit(const Goto
& node
)
160 out_
<< " br label %" << node
.label
<< std::endl
;
164 LLVMGeneratorVisitor::visit(const If
& node
)
166 assert(node
.ifTrue
->nodeType
== Label::nodeTypeId());
167 assert(node
.ifFalse
->nodeType
== Label::nodeTypeId());
169 Label
* trueLabel
= reinterpret_cast<Label
*>(node
.ifTrue
);
170 Label
* falseLabel
= reinterpret_cast<Label
*>(node
.ifFalse
);
173 node
.cond
->accept(*this);
174 out_
<< ", label %" << trueLabel
->name
<< ", label %"
175 << falseLabel
->name
<< std::endl
;
179 LLVMGeneratorVisitor::visit(const Type
& /*node*/)
181 //assert_msg(false, "we should never reach this code");
185 LLVMGeneratorVisitor::visit(const NumberType
& /*node*/)
187 assert_msg(false, "we should never reach this code");
191 LLVMGeneratorVisitor::visit(const BoolType
& /*node*/)
197 LLVMGeneratorVisitor::visit(const IntegerType
& node
)
199 out_
<< " i" << node
.size
<< " ";
203 LLVMGeneratorVisitor::visit(const FloatType
& /*node*/)
209 LLVMGeneratorVisitor::visit(const DoubleType
& /*node*/)
215 LLVMGeneratorVisitor::visit(const CastExp
& node
)
217 Type
* from
= node
.exp
->type
;
218 Type
* to
= node
.type
;
222 castTableKey_t key
= std::make_pair(from
->nodeType
, to
->nodeType
);
223 assert(castTable_
.count(key
) > 0);
224 (this->*castTable_
[key
])(node
);
228 LLVMGeneratorVisitor::castBoolToBool(const CastExp
& node
)
230 out_
<< "add i1 0, ";
231 node
.exp
->accept(*this);
235 #define SIMPLE_NUMBER_CAST(Type1, Type2, CastInstr, DestType) \
237 LLVMGeneratorVisitor::cast##Type1##To##Type2(const CastExp & node) \
240 node.exp->accept(*this); \
245 SIMPLE_NUMBER_CAST(Bool
, Float
, "sitofp i1 ", " to float")
246 SIMPLE_NUMBER_CAST(Bool
, Double
, "sitofp i1 ", " to double")
247 SIMPLE_NUMBER_CAST(Float
, Double
, "fpext float ", " to double")
250 LLVMGeneratorVisitor::castIntegerToInteger(const CastExp
& node
)
252 IntegerType
* from
= reinterpret_cast<IntegerType
*>(node
.exp
->type
);
253 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
255 if (from
->size
== to
->size
)
257 out_
<< "add i" << to
->size
<< " 0, ";
258 node
.exp
->accept(*this);
262 if (from
->size
> to
->size
)
264 else if (from
->isSigned
)
268 out_
<< " i" << from
->size
<< " ";
269 node
.exp
->accept(*this);
270 out_
<< " to i" << to
->size
;