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) \
22 castTableKey_t key = std::make_pair(Type1##Type::nodeTypeId(), \
23 Type2##Type::nodeTypeId()); \
24 assert_msg(!castTable_.count(key), \
25 "the same key has been insterted two times"); \
26 castTable_[key] = &LLVMGeneratorVisitor::cast##Type1##To##Type2; \
29 ADD_CAST_TABLE_ENTRY(Bool
, Bool
);
30 ADD_CAST_TABLE_ENTRY(Bool
, Integer
);
31 ADD_CAST_TABLE_ENTRY(Bool
, Float
);
32 ADD_CAST_TABLE_ENTRY(Bool
, Double
);
33 ADD_CAST_TABLE_ENTRY(Integer
, Bool
);
34 ADD_CAST_TABLE_ENTRY(Integer
, Integer
);
35 ADD_CAST_TABLE_ENTRY(Integer
, Float
);
36 ADD_CAST_TABLE_ENTRY(Integer
, Double
);
37 ADD_CAST_TABLE_ENTRY(Float
, Double
);
38 ADD_CAST_TABLE_ENTRY(Float
, Bool
);
39 ADD_CAST_TABLE_ENTRY(Double
, Bool
);
42 LLVMGeneratorVisitor::~LLVMGeneratorVisitor()
47 LLVMGeneratorVisitor::visit(const Function
& node
)
49 out_
<< "define void @" << node
.name
<< "() {" << std::endl
;
51 out_
<< " ret void" << std::endl
56 LLVMGeneratorVisitor::visit(const VarDecl
& node
)
60 out_
<< " %" << node
.name
<< " = alloca ";
61 node
.type
->accept(*this);
66 LLVMGeneratorVisitor::visit(const LoadVar
& node
)
70 out_
<< " %" << node
.to
<< " = load ";
71 node
.type
->accept(*this);
72 out_
<< " * %" << node
.name
<< std::endl
;
76 LLVMGeneratorVisitor::visit(const StoreVar
& node
)
79 assert(node
.value
->type
);
82 node
.value
->type
->accept(*this);
83 node
.value
->accept(*this);
85 node
.value
->type
->accept(*this);
86 out_
<< " * %" << node
.name
<< std::endl
;
90 LLVMGeneratorVisitor::visit(const AssignExp
& node
)
92 out_
<< " %" << node
.dest
->name
<< " = ";
93 node
.value
->accept(*this);
97 #define GEN_BINARY_EXP_EXT(Name, Type, Instr) \
99 LLVMGeneratorVisitor::Name(const Type & node) \
102 node.type->accept(*this); \
103 node.left->accept(*this); \
105 node.right->accept(*this); \
108 #define GEN_BINARY_EXP(Type, Instr) GEN_BINARY_EXP_EXT(visit, Type, Instr)
110 GEN_BINARY_EXP(AddExp
, "add")
111 GEN_BINARY_EXP(SubExp
, "sub")
112 GEN_BINARY_EXP(MulExp
, "mul")
113 GEN_BINARY_EXP_EXT(visitUDivExp
, DivExp
, "udiv")
114 GEN_BINARY_EXP_EXT(visitSDivExp
, DivExp
, "sdiv")
115 GEN_BINARY_EXP_EXT(visitFDivExp
, DivExp
, "fdiv")
116 GEN_BINARY_EXP_EXT(visitUModExp
, ModExp
, "urem")
117 GEN_BINARY_EXP_EXT(visitSModExp
, ModExp
, "srem")
118 GEN_BINARY_EXP_EXT(visitFModExp
, ModExp
, "frem")
120 GEN_BINARY_EXP(AndExp
, "and")
121 GEN_BINARY_EXP(OrExp
, "or")
122 GEN_BINARY_EXP(XorExp
, "xor")
124 GEN_BINARY_EXP(ShlExp
, "shl")
125 GEN_BINARY_EXP(AShrExp
, "ashr")
126 GEN_BINARY_EXP(LShrExp
, "lshr")
128 /// @todo check this is correct.
129 #define GEN_CMP_EXP(Type, Instr) \
131 LLVMGeneratorVisitor::visit(const Type & node) \
133 if (node.type->nodeType == FloatType::nodeTypeId() || \
134 node.type->nodeType == DoubleType::nodeTypeId()) \
139 if (node.nodeType == LtExp::nodeTypeId() || \
140 node.nodeType == LtEqExp::nodeTypeId() || \
141 node.nodeType == GtExp::nodeTypeId() || \
142 node.nodeType == GtEqExp::nodeTypeId()) \
144 if (node.type->nodeType == IntegerType::nodeTypeId()) \
146 IntegerType * itype = reinterpret_cast<IntegerType *>(node.type); \
147 out_ << (itype->isSigned ? "s" : "u"); \
149 else if (node.type->nodeType == BoolType::nodeTypeId()) \
154 node.type->accept(*this); \
155 node.left->accept(*this); \
157 node.right->accept(*this); \
160 GEN_CMP_EXP(EqExp
, "eq")
161 GEN_CMP_EXP(NeqExp
, "ne")
162 GEN_CMP_EXP(LtExp
, "lt")
163 GEN_CMP_EXP(LtEqExp
, "le")
164 GEN_CMP_EXP(GtExp
, "gt")
165 GEN_CMP_EXP(GtEqExp
, "ge")
167 #define GEN_BINARY_BOOL_EXP(Type, Op) \
169 LLVMGeneratorVisitor::visit(const Type & node) \
172 node.left->accept(*this); \
174 node.right->accept(*this); \
177 GEN_BINARY_BOOL_EXP(AndAndExp
, "and ")
178 GEN_BINARY_BOOL_EXP(OrOrExp
, "or ")
180 #define GEN_DIV_MOD_EXP(Name) \
182 LLVMGeneratorVisitor::visit(const Name##Exp & node) \
184 if (node.type->nodeType == BoolType::nodeTypeId()) \
185 visitU##Name##Exp(node); \
186 else if (node.type->nodeType == FloatType::nodeTypeId() || \
187 node.type->nodeType == DoubleType::nodeTypeId()) \
188 visitF##Name##Exp(node); \
189 else if (node.type->nodeType == IntegerType::nodeTypeId()) \
191 IntegerType * type = reinterpret_cast<IntegerType *>(node.type); \
192 type->isSigned ? visitS##Name##Exp(node) : visitU##Name##Exp(node); \
202 // LLVMGeneratorVisitor::visit(const EqExp & node)
208 LLVMGeneratorVisitor::visit(const IdExp
& node
)
210 out_
<< "%" << node
.name
;
214 LLVMGeneratorVisitor::visit(const TmpResultExp
& node
)
216 out_
<< "%" << node
.name
;
220 LLVMGeneratorVisitor::visit(const NumberExp
& node
)
222 if (node
.type
->nodeType
== FloatType::nodeTypeId())
223 /// @todo find the right way to print floating point numbers
224 out_
<< std::setprecision(1000) << (float)node
.number
;
226 out_
<< std::setprecision(1000) << node
.number
;
230 LLVMGeneratorVisitor::visit(const Label
& node
)
232 out_
<< " br label %" << node
.name
<< " ; dummy branch to start a block" << std::endl
233 << node
.name
<< ":" << std::endl
;
237 LLVMGeneratorVisitor::visit(const Goto
& node
)
239 out_
<< " br label %" << node
.label
<< std::endl
;
243 LLVMGeneratorVisitor::visit(const If
& node
)
245 assert(node
.ifTrue
->nodeType
== Label::nodeTypeId());
246 assert(node
.ifFalse
->nodeType
== Label::nodeTypeId());
248 Label
* trueLabel
= reinterpret_cast<Label
*>(node
.ifTrue
);
249 Label
* falseLabel
= reinterpret_cast<Label
*>(node
.ifFalse
);
252 node
.cond
->accept(*this);
253 out_
<< ", label %" << trueLabel
->name
<< ", label %"
254 << falseLabel
->name
<< std::endl
;
258 LLVMGeneratorVisitor::visit(const Type
& /*node*/)
260 //assert_msg(false, "we should never reach this code");
264 LLVMGeneratorVisitor::visit(const NumberType
& /*node*/)
266 assert_msg(false, "we should never reach this code");
270 LLVMGeneratorVisitor::visit(const BoolType
& /*node*/)
276 LLVMGeneratorVisitor::visit(const IntegerType
& node
)
278 out_
<< " i" << node
.size
<< " ";
282 LLVMGeneratorVisitor::visit(const FloatType
& /*node*/)
288 LLVMGeneratorVisitor::visit(const DoubleType
& /*node*/)
294 LLVMGeneratorVisitor::visit(const CastExp
& node
)
296 Type
* from
= node
.exp
->type
;
297 Type
* to
= node
.type
;
301 castTableKey_t key
= std::make_pair(from
->nodeType
, to
->nodeType
);
302 assert(castTable_
.count(key
) > 0);
303 (this->*castTable_
[key
])(node
);
307 LLVMGeneratorVisitor::castBoolToBool(const CastExp
& node
)
309 out_
<< "add i1 0, ";
310 node
.exp
->accept(*this);
314 #define SIMPLE_NUMBER_CAST(Type1, Type2, CastInstr, DestType) \
316 LLVMGeneratorVisitor::cast##Type1##To##Type2(const CastExp & node) \
319 node.exp->accept(*this); \
324 SIMPLE_NUMBER_CAST(Bool
, Float
, "uitofp i1 ", " to float")
325 SIMPLE_NUMBER_CAST(Bool
, Double
, "uitofp i1 ", " to double")
326 SIMPLE_NUMBER_CAST(Float
, Double
, "fpext float ", " to double")
329 LLVMGeneratorVisitor::castBoolToInteger(const CastExp
& node
)
331 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
335 out_
<< "add i1 0, ";
336 node
.exp
->accept(*this);
341 node
.exp
->accept(*this);
348 LLVMGeneratorVisitor::castIntegerToInteger(const CastExp
& node
)
350 IntegerType
* from
= reinterpret_cast<IntegerType
*>(node
.exp
->type
);
351 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
353 if (from
->size
== to
->size
)
355 out_
<< "add i" << to
->size
<< " 0, ";
356 node
.exp
->accept(*this);
360 if (from
->size
> to
->size
)
362 else if (from
->isSigned
)
366 out_
<< " i" << from
->size
<< " ";
367 node
.exp
->accept(*this);
368 out_
<< " to i" << to
->size
;
371 #define INTEGER_TO_FLOAT(Float, Str) \
373 LLVMGeneratorVisitor::castIntegerTo##Float(const CastExp & node) \
375 IntegerType * from = \
376 reinterpret_cast<IntegerType *>(node.exp->type); \
378 out_ << (from->isSigned ? "sitofp " : "uitofp "); \
379 from->accept(*this); \
380 node.exp->accept(*this); \
381 out_ << " to " Str; \
384 INTEGER_TO_FLOAT(Float
, "float")
385 INTEGER_TO_FLOAT(Double
, "double")
388 LLVMGeneratorVisitor::castIntegerToBool(const ast::CastExp
& node
)
391 node
.exp
->type
->accept(*this);
393 node
.exp
->accept(*this);
396 #define FLOAT_TO_BOOL(Type, Str) \
398 LLVMGeneratorVisitor::cast##Type##ToBool(const ast::CastExp & node) \
400 /** @todo throw a warning */ \
401 assert_msg(false, "casting float to bool is a non sense."); \
404 FLOAT_TO_BOOL(Float
, "float")
405 FLOAT_TO_BOOL(Double
, "double")