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
);
39 LLVMGeneratorVisitor::~LLVMGeneratorVisitor()
44 LLVMGeneratorVisitor::visit(const Function
& node
)
46 out_
<< "define void @" << node
.name
<< "() {" << std::endl
;
48 out_
<< " ret void" << std::endl
53 LLVMGeneratorVisitor::visit(const VarDecl
& node
)
57 out_
<< " %" << node
.name
<< " = alloca ";
58 node
.type
->accept(*this);
63 LLVMGeneratorVisitor::visit(const LoadVar
& node
)
67 out_
<< " %" << node
.to
<< " = load ";
68 node
.type
->accept(*this);
69 out_
<< " * %" << node
.name
<< std::endl
;
73 LLVMGeneratorVisitor::visit(const StoreVar
& node
)
76 assert(node
.value
->type
);
79 node
.value
->type
->accept(*this);
80 node
.value
->accept(*this);
82 node
.value
->type
->accept(*this);
83 out_
<< " * %" << node
.name
<< std::endl
;
87 LLVMGeneratorVisitor::visit(const AssignExp
& node
)
89 out_
<< " %" << node
.dest
->name
<< " = ";
90 node
.value
->accept(*this);
94 #define GEN_BINARY_EXP_EXT(Name, Type, Instr) \
96 LLVMGeneratorVisitor::Name(const Type & node) \
99 node.type->accept(*this); \
100 node.left->accept(*this); \
102 node.right->accept(*this); \
105 #define GEN_BINARY_EXP(Type, Instr) GEN_BINARY_EXP_EXT(visit, Type, Instr)
107 GEN_BINARY_EXP(AddExp
, "add")
108 GEN_BINARY_EXP(SubExp
, "sub")
109 GEN_BINARY_EXP(MulExp
, "mul")
110 GEN_BINARY_EXP_EXT(visitUDivExp
, DivExp
, "udiv")
111 GEN_BINARY_EXP_EXT(visitSDivExp
, DivExp
, "sdiv")
112 GEN_BINARY_EXP_EXT(visitFDivExp
, DivExp
, "fdiv")
113 GEN_BINARY_EXP_EXT(visitUModExp
, ModExp
, "urem")
114 GEN_BINARY_EXP_EXT(visitSModExp
, ModExp
, "srem")
115 GEN_BINARY_EXP_EXT(visitFModExp
, ModExp
, "frem")
117 GEN_BINARY_EXP(AndExp
, "and")
118 GEN_BINARY_EXP(OrExp
, "or")
119 GEN_BINARY_EXP(XorExp
, "xor")
121 GEN_BINARY_EXP(ShlExp
, "shl")
122 GEN_BINARY_EXP(AShrExp
, "ashr")
123 GEN_BINARY_EXP(LShrExp
, "lshr")
125 GEN_BINARY_EXP(EqExp
, "icmp eq")
126 GEN_BINARY_EXP(NeqExp
, "icmp ne")
127 GEN_BINARY_EXP(LtExp
, "icmp slt")
128 GEN_BINARY_EXP(LtEqExp
, "icmp sle")
129 GEN_BINARY_EXP(GtExp
, "icmp sgt")
130 GEN_BINARY_EXP(GtEqExp
, "icmp sge")
132 #define GEN_DIV_MOD_EXP(Name) \
134 LLVMGeneratorVisitor::visit(const Name##Exp & node) \
136 if (node.type->nodeType == BoolType::nodeTypeId()) \
137 visitU##Name##Exp(node); \
138 else if (node.type->nodeType == FloatType::nodeTypeId() || \
139 node.type->nodeType == DoubleType::nodeTypeId()) \
140 visitF##Name##Exp(node); \
141 else if (node.type->nodeType == IntegerType::nodeTypeId()) \
143 IntegerType * type = reinterpret_cast<IntegerType *>(node.type); \
144 type->isSigned ? visitS##Name##Exp(node) : visitU##Name##Exp(node); \
154 // LLVMGeneratorVisitor::visit(const EqExp & node)
160 LLVMGeneratorVisitor::visit(const IdExp
& node
)
162 out_
<< "%" << node
.name
;
166 LLVMGeneratorVisitor::visit(const TmpResultExp
& node
)
168 out_
<< "%" << node
.name
;
172 LLVMGeneratorVisitor::visit(const NumberExp
& node
)
174 if (node
.type
->nodeType
== FloatType::nodeTypeId())
175 out_
<< std::setprecision(1000) << (float)node
.number
;
177 out_
<< std::setprecision(1000) << node
.number
;
181 LLVMGeneratorVisitor::visit(const Label
& node
)
183 out_
<< " br label %" << node
.name
<< " ; dummy branch to start a block" << std::endl
184 << node
.name
<< ":" << std::endl
;
188 LLVMGeneratorVisitor::visit(const Goto
& node
)
190 out_
<< " br label %" << node
.label
<< std::endl
;
194 LLVMGeneratorVisitor::visit(const If
& node
)
196 assert(node
.ifTrue
->nodeType
== Label::nodeTypeId());
197 assert(node
.ifFalse
->nodeType
== Label::nodeTypeId());
199 Label
* trueLabel
= reinterpret_cast<Label
*>(node
.ifTrue
);
200 Label
* falseLabel
= reinterpret_cast<Label
*>(node
.ifFalse
);
203 node
.cond
->accept(*this);
204 out_
<< ", label %" << trueLabel
->name
<< ", label %"
205 << falseLabel
->name
<< std::endl
;
209 LLVMGeneratorVisitor::visit(const Type
& /*node*/)
211 //assert_msg(false, "we should never reach this code");
215 LLVMGeneratorVisitor::visit(const NumberType
& /*node*/)
217 assert_msg(false, "we should never reach this code");
221 LLVMGeneratorVisitor::visit(const BoolType
& /*node*/)
227 LLVMGeneratorVisitor::visit(const IntegerType
& node
)
229 out_
<< " i" << node
.size
<< " ";
233 LLVMGeneratorVisitor::visit(const FloatType
& /*node*/)
239 LLVMGeneratorVisitor::visit(const DoubleType
& /*node*/)
245 LLVMGeneratorVisitor::visit(const CastExp
& node
)
247 Type
* from
= node
.exp
->type
;
248 Type
* to
= node
.type
;
252 castTableKey_t key
= std::make_pair(from
->nodeType
, to
->nodeType
);
253 assert(castTable_
.count(key
) > 0);
254 (this->*castTable_
[key
])(node
);
258 LLVMGeneratorVisitor::castBoolToBool(const CastExp
& node
)
260 out_
<< "add i1 0, ";
261 node
.exp
->accept(*this);
265 #define SIMPLE_NUMBER_CAST(Type1, Type2, CastInstr, DestType) \
267 LLVMGeneratorVisitor::cast##Type1##To##Type2(const CastExp & node) \
270 node.exp->accept(*this); \
275 SIMPLE_NUMBER_CAST(Bool
, Float
, "uitofp i1 ", " to float")
276 SIMPLE_NUMBER_CAST(Bool
, Double
, "uitofp i1 ", " to double")
277 SIMPLE_NUMBER_CAST(Float
, Double
, "fpext float ", " to double")
280 LLVMGeneratorVisitor::castBoolToInteger(const CastExp
& node
)
282 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
286 out_
<< "add i1 0, ";
287 node
.exp
->accept(*this);
292 node
.exp
->accept(*this);
299 LLVMGeneratorVisitor::castIntegerToInteger(const CastExp
& node
)
301 IntegerType
* from
= reinterpret_cast<IntegerType
*>(node
.exp
->type
);
302 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
304 if (from
->size
== to
->size
)
306 out_
<< "add i" << to
->size
<< " 0, ";
307 node
.exp
->accept(*this);
311 if (from
->size
> to
->size
)
313 else if (from
->isSigned
)
317 out_
<< " i" << from
->size
<< " ";
318 node
.exp
->accept(*this);
319 out_
<< " to i" << to
->size
;
322 #define INTEGER_TO_FLOAT(Float, Str) \
324 LLVMGeneratorVisitor::castIntegerTo##Float(const CastExp & node) \
326 IntegerType * from = \
327 reinterpret_cast<IntegerType *>(node.exp->type); \
329 out_ << (from->isSigned ? "sitofp " : "uitofp "); \
330 from->accept(*this); \
331 node.exp->accept(*this); \
332 out_ << " to " Str; \
335 INTEGER_TO_FLOAT(Float
, "float")
336 INTEGER_TO_FLOAT(Double
, "double")