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(IntegerType
, IntegerType
, castIntegerToInteger
);
31 //ADD_CAST_TABLE_ENTRY(FloatType, IntegerType, castIntegerFloat);
34 LLVMGeneratorVisitor::~LLVMGeneratorVisitor()
39 LLVMGeneratorVisitor::visit(const Function
& node
)
41 out_
<< "define void @" << node
.name
<< "() {" << std::endl
;
43 out_
<< " ret void" << std::endl
48 LLVMGeneratorVisitor::visit(const VarDecl
& node
)
52 out_
<< " %" << node
.name
<< " = alloca ";
53 node
.type
->accept(*this);
58 LLVMGeneratorVisitor::visit(const LoadVar
& node
)
62 out_
<< " %" << node
.to
<< " = load ";
63 node
.type
->accept(*this);
64 out_
<< " * %" << node
.name
<< std::endl
;
68 LLVMGeneratorVisitor::visit(const StoreVar
& node
)
71 assert(node
.value
->type
);
74 node
.value
->type
->accept(*this);
75 node
.value
->accept(*this);
77 node
.value
->type
->accept(*this);
78 out_
<< " * %" << node
.name
<< std::endl
;
82 LLVMGeneratorVisitor::visit(const AssignExp
& node
)
84 out_
<< " %" << node
.dest
->name
<< " = ";
85 node
.value
->accept(*this);
89 #define GEN_BINARY_EXP(Type, Instr) \
91 LLVMGeneratorVisitor::visit(const Type & node) \
94 node.type->accept(*this); \
95 node.left->accept(*this); \
97 node.right->accept(*this); \
100 GEN_BINARY_EXP(AddExp
, "add")
101 GEN_BINARY_EXP(SubExp
, "sub")
102 GEN_BINARY_EXP(MulExp
, "mul")
103 GEN_BINARY_EXP(DivExp
, "sdiv") /// @todo play with udiv and sdiv instructions
104 GEN_BINARY_EXP(ModExp
, "srem") /// @todo play with urem and srem instructions
106 GEN_BINARY_EXP(AndExp
, "and")
107 GEN_BINARY_EXP(OrExp
, "or")
108 GEN_BINARY_EXP(XorExp
, "xor")
110 GEN_BINARY_EXP(ShlExp
, "shl")
111 GEN_BINARY_EXP(AShrExp
, "ashr")
112 GEN_BINARY_EXP(LShrExp
, "lshr")
114 GEN_BINARY_EXP(EqExp
, "icmp eq")
115 GEN_BINARY_EXP(NeqExp
, "icmp ne")
116 GEN_BINARY_EXP(LtExp
, "icmp slt")
117 GEN_BINARY_EXP(LtEqExp
, "icmp sle")
118 GEN_BINARY_EXP(GtExp
, "icmp sgt")
119 GEN_BINARY_EXP(GtEqExp
, "icmp sge")
122 // LLVMGeneratorVisitor::visit(const EqExp & node)
128 LLVMGeneratorVisitor::visit(const IdExp
& node
)
130 out_
<< "%" << node
.name
;
134 LLVMGeneratorVisitor::visit(const TmpResultExp
& node
)
136 out_
<< "%" << node
.name
;
140 LLVMGeneratorVisitor::visit(const NumberExp
& node
)
142 if (node
.type
->nodeType
== FloatType::nodeTypeId())
143 out_
<< std::setprecision(1000) << (float)node
.number
;
145 out_
<< std::setprecision(1000) << node
.number
;
149 LLVMGeneratorVisitor::visit(const Label
& node
)
151 out_
<< " br label %" << node
.name
<< " ; dummy branch to start a block" << std::endl
152 << node
.name
<< ":" << std::endl
;
156 LLVMGeneratorVisitor::visit(const Goto
& node
)
158 out_
<< " br label %" << node
.label
<< std::endl
;
162 LLVMGeneratorVisitor::visit(const If
& node
)
164 assert(node
.ifTrue
->nodeType
== Label::nodeTypeId());
165 assert(node
.ifFalse
->nodeType
== Label::nodeTypeId());
167 Label
* trueLabel
= reinterpret_cast<Label
*>(node
.ifTrue
);
168 Label
* falseLabel
= reinterpret_cast<Label
*>(node
.ifFalse
);
171 node
.cond
->accept(*this);
172 out_
<< ", label %" << trueLabel
->name
<< ", label %"
173 << falseLabel
->name
<< std::endl
;
177 LLVMGeneratorVisitor::visit(const Type
& /*node*/)
179 //assert_msg(false, "we should never reach this code");
183 LLVMGeneratorVisitor::visit(const NumberType
& /*node*/)
185 assert_msg(false, "we should never reach this code");
189 LLVMGeneratorVisitor::visit(const BoolType
& node
)
195 LLVMGeneratorVisitor::visit(const IntegerType
& node
)
197 out_
<< " i" << node
.size
<< " ";
201 LLVMGeneratorVisitor::visit(const FloatType
& /*node*/)
207 LLVMGeneratorVisitor::visit(const CastExp
& node
)
209 Type
* from
= node
.exp
->type
;
210 Type
* to
= node
.type
;
214 castTableKey_t key
= std::make_pair(from
->nodeType
, to
->nodeType
);
215 assert(castTable_
.count(key
) > 0);
216 (this->*castTable_
[key
])(node
);
220 LLVMGeneratorVisitor::castBoolToBool(const CastExp
& node
)
222 out_
<< "add i1 0, ";
223 node
.exp
->accept(*this);
228 LLVMGeneratorVisitor::castIntegerToInteger(const CastExp
& node
)
230 IntegerType
* from
= reinterpret_cast<IntegerType
*>(node
.exp
->type
);
231 IntegerType
* to
= reinterpret_cast<IntegerType
*>(node
.type
);
233 if (from
->size
== to
->size
)
235 out_
<< "add i" << to
->size
<< " 0, ";
236 node
.exp
->accept(*this);
240 if (from
->size
> to
->size
)
242 else if (from
->isSigned
)
246 out_
<< " i" << from
->size
<< " ";
247 node
.exp
->accept(*this);
248 out_
<< " to i" << to
->size
;