fixed cast bool, bool
[ozulis.git] / src / ast / llvm-generator-visitor.cc
blob79c22fdc218c5852a3987e89eecd001f68b0dae6
1 #include <iomanip>
3 #include <core/assert.hh>
5 #include "llvm-generator-visitor.hh"
7 namespace ast
9 LLVMGeneratorVisitor::LLVMGeneratorVisitor(std::ostream & out)
10 : super_t(),
11 castTable_(),
12 out_(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) \
21 do { \
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; \
27 } while (0)
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()
38 void
39 LLVMGeneratorVisitor::visit(const Function & node)
41 out_ << "define void @" << node.name << "() {" << std::endl;
42 super_t::visit(node);
43 out_ << " ret void" << std::endl
44 << "}" << std::endl;
47 void
48 LLVMGeneratorVisitor::visit(const VarDecl & node)
50 assert(node.type);
52 out_ << " %" << node.name << " = alloca ";
53 node.type->accept(*this);
54 out_ << std::endl;
57 void
58 LLVMGeneratorVisitor::visit(const LoadVar & node)
60 assert(node.type);
62 out_ << " %" << node.to << " = load ";
63 node.type->accept(*this);
64 out_ << " * %" << node.name << std::endl;
67 void
68 LLVMGeneratorVisitor::visit(const StoreVar & node)
70 assert(node.value);
71 assert(node.value->type);
73 out_ << " store ";
74 node.value->type->accept(*this);
75 node.value->accept(*this);
76 out_ << ", ";
77 node.value->type->accept(*this);
78 out_ << " * %" << node.name << std::endl;
81 void
82 LLVMGeneratorVisitor::visit(const AssignExp & node)
84 out_ << " %" << node.dest->name << " = ";
85 node.value->accept(*this);
86 out_ << std::endl;
89 #define GEN_BINARY_EXP(Type, Instr) \
90 void \
91 LLVMGeneratorVisitor::visit(const Type & node) \
92 { \
93 out_ << Instr" "; \
94 node.type->accept(*this); \
95 node.left->accept(*this); \
96 out_ << ", "; \
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")
121 // void
122 // LLVMGeneratorVisitor::visit(const EqExp & node)
123 // {
125 // }
127 void
128 LLVMGeneratorVisitor::visit(const IdExp & node)
130 out_ << "%" << node.name;
133 void
134 LLVMGeneratorVisitor::visit(const TmpResultExp & node)
136 out_ << "%" << node.name;
139 void
140 LLVMGeneratorVisitor::visit(const NumberExp & node)
142 if (node.type->nodeType == FloatType::nodeTypeId())
143 out_ << std::setprecision(1000) << (float)node.number;
144 else
145 out_ << std::setprecision(1000) << node.number;
148 void
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;
155 void
156 LLVMGeneratorVisitor::visit(const Goto & node)
158 out_ << " br label %" << node.label << std::endl;
161 void
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);
170 out_ << " br i1 ";
171 node.cond->accept(*this);
172 out_ << ", label %" << trueLabel->name << ", label %"
173 << falseLabel->name << std::endl;
176 void
177 LLVMGeneratorVisitor::visit(const Type & /*node*/)
179 //assert_msg(false, "we should never reach this code");
182 void
183 LLVMGeneratorVisitor::visit(const NumberType & /*node*/)
185 assert_msg(false, "we should never reach this code");
188 void
189 LLVMGeneratorVisitor::visit(const BoolType & node)
191 out_ << " i1 ";
194 void
195 LLVMGeneratorVisitor::visit(const IntegerType & node)
197 out_ << " i" << node.size << " ";
200 void
201 LLVMGeneratorVisitor::visit(const FloatType & /*node*/)
203 out_ << " float ";
206 void
207 LLVMGeneratorVisitor::visit(const CastExp & node)
209 Type * from = node.exp->type;
210 Type * to = node.type;
212 assert(from);
213 assert(to);
214 castTableKey_t key = std::make_pair(from->nodeType, to->nodeType);
215 assert(castTable_.count(key) > 0);
216 (this->*castTable_[key])(node);
219 void
220 LLVMGeneratorVisitor::castBoolToBool(const CastExp & node)
222 out_ << "add i1 0, ";
223 node.exp->accept(*this);
224 return;
227 void
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);
237 return;
240 if (from->size > to->size)
241 out_ << "trunc";
242 else if (from->isSigned)
243 out_ << "sext";
244 else
245 out_ << "zext";
246 out_ << " i" << from->size << " ";
247 node.exp->accept(*this);
248 out_ << " to i" << to->size;