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
, IntegerType
, castBoolToInteger
);
31 ADD_CAST_TABLE_ENTRY(BoolType
, FloatType
, castBoolToFloat
);
32 ADD_CAST_TABLE_ENTRY(BoolType
, DoubleType
, castBoolToDouble
);
33 ADD_CAST_TABLE_ENTRY(IntegerType
, IntegerType
, castIntegerToInteger
);
34 ADD_CAST_TABLE_ENTRY(IntegerType
, FloatType
, castIntegerToFloat
);
35 ADD_CAST_TABLE_ENTRY(IntegerType
, DoubleType
, castIntegerToDouble
);
36 ADD_CAST_TABLE_ENTRY(FloatType
, DoubleType
, castFloatToDouble
);
37 ADD_CAST_TABLE_ENTRY(DoubleType
, BoolType
, castDoubleToBool
);
40 LLVMGeneratorVisitor::~LLVMGeneratorVisitor()
45 LLVMGeneratorVisitor::visit(const Function
& node
)
47 out_
<< "define void @" << node
.name
<< "() {" << std::endl
;
49 out_
<< " ret void" << std::endl
54 LLVMGeneratorVisitor::visit(const VarDecl
& node
)
58 out_
<< " %" << node
.name
<< " = alloca ";
59 node
.type
->accept(*this);
64 LLVMGeneratorVisitor::visit(const LoadVar
& node
)
68 out_
<< " %" << node
.to
<< " = load ";
69 node
.type
->accept(*this);
70 out_
<< " * %" << node
.name
<< std::endl
;
74 LLVMGeneratorVisitor::visit(const StoreVar
& node
)
77 assert(node
.value
->type
);
80 node
.value
->type
->accept(*this);
81 node
.value
->accept(*this);
83 node
.value
->type
->accept(*this);
84 out_
<< " * %" << node
.name
<< std::endl
;
88 LLVMGeneratorVisitor::visit(const AssignExp
& node
)
90 out_
<< " %" << node
.dest
->name
<< " = ";
91 node
.value
->accept(*this);
95 #define GEN_BINARY_EXP_EXT(Name, Type, Instr) \
97 LLVMGeneratorVisitor::Name(const Type & node) \
100 node.type->accept(*this); \
101 node.left->accept(*this); \
103 node.right->accept(*this); \
106 #define GEN_BINARY_EXP(Type, Instr) GEN_BINARY_EXP_EXT(visit, Type, Instr)
108 GEN_BINARY_EXP(AddExp
, "add")
109 GEN_BINARY_EXP(SubExp
, "sub")
110 GEN_BINARY_EXP(MulExp
, "mul")
111 GEN_BINARY_EXP_EXT(visitUDivExp
, DivExp
, "udiv")
112 GEN_BINARY_EXP_EXT(visitSDivExp
, DivExp
, "sdiv")
113 GEN_BINARY_EXP_EXT(visitFDivExp
, DivExp
, "fdiv")
114 GEN_BINARY_EXP_EXT(visitUModExp
, ModExp
, "urem")
115 GEN_BINARY_EXP_EXT(visitSModExp
, ModExp
, "srem")
116 GEN_BINARY_EXP_EXT(visitFModExp
, ModExp
, "frem")
118 GEN_BINARY_EXP(AndExp
, "and")
119 GEN_BINARY_EXP(OrExp
, "or")
120 GEN_BINARY_EXP(XorExp
, "xor")
122 GEN_BINARY_EXP(ShlExp
, "shl")
123 GEN_BINARY_EXP(AShrExp
, "ashr")
124 GEN_BINARY_EXP(LShrExp
, "lshr")
126 GEN_BINARY_EXP(EqExp
, "icmp eq")
127 GEN_BINARY_EXP(NeqExp
, "icmp ne")
128 GEN_BINARY_EXP(LtExp
, "icmp slt")
129 GEN_BINARY_EXP(LtEqExp
, "icmp sle")
130 GEN_BINARY_EXP(GtExp
, "icmp sgt")
131 GEN_BINARY_EXP(GtEqExp
, "icmp sge")
133 #define GEN_BINARY_BOOL_EXP(Type, Op) \
135 LLVMGeneratorVisitor::visit(const Type & node) \
138 node.left->accept(*this); \
140 node.right->accept(*this); \
143 GEN_BINARY_BOOL_EXP(AndAndExp
, "and ")
144 GEN_BINARY_BOOL_EXP(OrOrExp
, "or ")
146 #define GEN_DIV_MOD_EXP(Name) \
148 LLVMGeneratorVisitor::visit(const Name##Exp & node) \
150 if (node.type->nodeType == BoolType::nodeTypeId()) \
151 visitU##Name##Exp(node); \
152 else if (node.type->nodeType == FloatType::nodeTypeId() || \
153 node.type->nodeType == DoubleType::nodeTypeId()) \
154 visitF##Name##Exp(node); \
155 else if (node.type->nodeType == IntegerType::nodeTypeId()) \
157 IntegerType * type = reinterpret_cast<IntegerType *>(node.type); \
158 type->isSigned ? visitS##Name##Exp(node) : visitU##Name##Exp(node); \
168 // LLVMGeneratorVisitor::visit(const EqExp & node)
174 LLVMGeneratorVisitor::visit(const IdExp
& node
)
176 out_
<< "%" << node
.name
;
180 LLVMGeneratorVisitor::visit(const TmpResultExp
& node
)
182 out_
<< "%" << node
.name
;
186 LLVMGeneratorVisitor::visit(const NumberExp
& node
)
188 if (node
.type
->nodeType
== FloatType::nodeTypeId())
189 out_
<< std::setprecision(1000) << (float)node
.number
;
191 out_
<< std::setprecision(1000) << node
.number
;
195 LLVMGeneratorVisitor::visit(const Label
& node
)
197 out_
<< " br label %" << node
.name
<< " ; dummy branch to start a block" << std::endl
198 << node
.name
<< ":" << std::endl
;
202 LLVMGeneratorVisitor::visit(const Goto
& node
)
204 out_
<< " br label %" << node
.label
<< std::endl
;
208 LLVMGeneratorVisitor::visit(const If
& node
)
210 assert(node
.ifTrue
->nodeType
== Label::nodeTypeId());
211 assert(node
.ifFalse
->nodeType
== Label::nodeTypeId());
213 Label
* trueLabel
= reinterpret_cast<Label
*>(node
.ifTrue
);
214 Label
* falseLabel
= reinterpret_cast<Label
*>(node
.ifFalse
);
217 node
.cond
->accept(*this);
218 out_
<< ", label %" << trueLabel
->name
<< ", label %"
219 << falseLabel
->name
<< std::endl
;
223 LLVMGeneratorVisitor::visit(const Type
& /*node*/)
225 //assert_msg(false, "we should never reach this code");
229 LLVMGeneratorVisitor::visit(const NumberType
& /*node*/)
231 assert_msg(false, "we should never reach this code");
235 LLVMGeneratorVisitor::visit(const BoolType
& /*node*/)
241 LLVMGeneratorVisitor::visit(const IntegerType
& node
)
243 out_
<< " i" << node
.size
<< " ";
247 LLVMGeneratorVisitor::visit(const FloatType
& /*node*/)
253 LLVMGeneratorVisitor::visit(const DoubleType
& /*node*/)
259 LLVMGeneratorVisitor::visit(const CastExp
& node
)
261 Type
* from
= node
.exp
->type
;
262 Type
* to
= node
.type
;
266 castTableKey_t key
= std::make_pair(from
->nodeType
, to
->nodeType
);
267 assert(castTable_
.count(key
) > 0);
268 (this->*castTable_
[key
])(node
);
272 LLVMGeneratorVisitor::castBoolToBool(const CastExp
& node
)
274 out_
<< "add i1 0, ";
275 node
.exp
->accept(*this);
279 #define SIMPLE_NUMBER_CAST(Type1, Type2, CastInstr, DestType) \
281 LLVMGeneratorVisitor::cast##Type1##To##Type2(const CastExp & node) \
284 node.exp->accept(*this); \
289 SIMPLE_NUMBER_CAST(Bool
, Float
, "uitofp i1 ", " to float")
290 SIMPLE_NUMBER_CAST(Bool
, Double
, "uitofp i1 ", " to double")
291 SIMPLE_NUMBER_CAST(Float
, Double
, "fpext float ", " to double")
294 LLVMGeneratorVisitor::castBoolToInteger(const CastExp
& node
)
296 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
300 out_
<< "add i1 0, ";
301 node
.exp
->accept(*this);
306 node
.exp
->accept(*this);
313 LLVMGeneratorVisitor::castIntegerToInteger(const CastExp
& node
)
315 IntegerType
* from
= reinterpret_cast<IntegerType
*>(node
.exp
->type
);
316 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
318 if (from
->size
== to
->size
)
320 out_
<< "add i" << to
->size
<< " 0, ";
321 node
.exp
->accept(*this);
325 if (from
->size
> to
->size
)
327 else if (from
->isSigned
)
331 out_
<< " i" << from
->size
<< " ";
332 node
.exp
->accept(*this);
333 out_
<< " to i" << to
->size
;
336 #define INTEGER_TO_FLOAT(Float, Str) \
338 LLVMGeneratorVisitor::castIntegerTo##Float(const CastExp & node) \
340 IntegerType * from = \
341 reinterpret_cast<IntegerType *>(node.exp->type); \
343 out_ << (from->isSigned ? "sitofp " : "uitofp "); \
344 from->accept(*this); \
345 node.exp->accept(*this); \
346 out_ << " to " Str; \
349 INTEGER_TO_FLOAT(Float
, "float")
350 INTEGER_TO_FLOAT(Double
, "double")