4 #include "llvm_codegen_visitor.h"
6 static int stack_size
= -1;
8 static void _print_boolean(struct AstNode
*node
);
9 static void _print_load(struct AstNode
*node
, Visitor
*visitor
);
10 static int _get_type_size(Type type
);
11 static int _process_expression(struct AstNode
*rnode
, Visitor
*visitor
);
16 Visitor
*visitor
= (Visitor
*) malloc (sizeof(Visitor
));
18 visitor
->visit_program
= &llvm_codegen_visit_program
;
19 visitor
->visit_programdecl
= &llvm_codegen_visit_programdecl
;
20 visitor
->visit_vardecl_list
= &llvm_codegen_visit_vardecl_list
;
21 visitor
->visit_vardecl
= &llvm_codegen_visit_vardecl
;
22 visitor
->visit_identifier_list
= &llvm_codegen_visit_identifier_list
;
23 visitor
->visit_procfunc_list
= &llvm_codegen_visit_procfunc_list
;
24 visitor
->visit_procedure
= &llvm_codegen_visit_procfunc
;
25 visitor
->visit_function
= &llvm_codegen_visit_procfunc
;
26 visitor
->visit_param_list
= &llvm_codegen_visit_param_list
;
27 visitor
->visit_parameter
= &llvm_codegen_visit_parameter
;
28 visitor
->visit_statement_list
= &llvm_codegen_visit_statement_list
;
29 visitor
->visit_printint_stmt
= &llvm_codegen_visit_printint_stmt
;
30 visitor
->visit_printchar_stmt
= &llvm_codegen_visit_printchar_stmt
;
31 visitor
->visit_printbool_stmt
= &llvm_codegen_visit_printbool_stmt
;
32 visitor
->visit_printline_stmt
= &llvm_codegen_visit_printline_stmt
;
33 visitor
->visit_assignment_stmt
= &llvm_codegen_visit_assignment_stmt
;
34 visitor
->visit_if_stmt
= &llvm_codegen_visit_if_stmt
;
35 visitor
->visit_while_stmt
= &llvm_codegen_visit_while_stmt
;
36 visitor
->visit_for_stmt
= &llvm_codegen_visit_for_stmt
;
37 visitor
->visit_rel_expr
= &llvm_codegen_visit_binary_expr
;
38 visitor
->visit_add_expr
= &llvm_codegen_visit_binary_expr
;
39 visitor
->visit_mul_expr
= &llvm_codegen_visit_binary_expr
;
40 visitor
->visit_notfactor
= &llvm_codegen_visit_notfactor
;
41 visitor
->visit_call
= &llvm_codegen_visit_call
;
42 visitor
->visit_callparam_list
= &llvm_codegen_visit_callparam_list
;
43 visitor
->visit_callparam
= &llvm_codegen_visit_callparam
;
44 visitor
->visit_identifier
= &llvm_codegen_visit_identifier
;
45 visitor
->visit_literal
= &llvm_codegen_visit_literal
;
46 visitor
->visit_add_op
= &llvm_codegen_visit_binary_op
;
47 visitor
->visit_mul_op
= &llvm_codegen_visit_binary_op
;
48 visitor
->visit_rel_op
= &llvm_codegen_visit_binary_op
;
49 visitor
->visit_not_op
= &llvm_codegen_visit_not_op
;
55 llvm_codegen_visit_program(struct _Visitor
*visitor
, struct AstNode
*node
)
57 struct AstNode
*child
;
59 printf("; Generated with toypasc\n");
60 for (child
= node
->children
;
61 child
!= NULL
&& child
->kind
!= STATEMENT_LIST
;
62 child
= child
->sibling
) {
63 ast_node_accept(child
, visitor
);
67 printf("; Definition of main function\n");
68 printf("define i32 @main () {\nentry:\n");
69 ast_node_accept(child
, visitor
);
70 printf(TAB
"ret i32 0\n}\n\n");
75 llvm_codegen_visit_programdecl(struct _Visitor
*visitor
, struct AstNode
*node
)
78 ast_node_accept(node
->children
, visitor
);
80 printf("; Declare the string constants as a global constants...\n");
81 printf("@bool_str = global [2 x i8*] [ "
82 "i8* getelementptr ([6 x i8]* @.false_str, i32 0, i32 0), "
83 "i8* getelementptr ([5 x i8]* @.true_str, i32 0, i32 0) ]\n");
84 printf("@.false_str = internal constant [6 x i8] c\"false\\00\"\n");
85 printf("@.true_str = internal constant [5 x i8] c\"true\\00\"\n");
86 printf("@.int_fmt = internal constant [3 x i8] c\"%%d\\00\"\n");
87 printf("@.bool_fmt = internal constant [3 x i8] c\"%%s\\00\"\n");
89 printf("\n; External declaration of functions\n");
90 printf("declare i32 @puts(i8 *)\n");
91 printf("declare i32 @putchar(i32)\n");
92 printf("declare i32 @printf(i8*, ...)\n\n");
96 llvm_codegen_visit_vardecl_list (struct _Visitor
*visitor
, struct AstNode
*node
)
98 ast_node_accept_children(node
->children
, visitor
);
99 if (node
->parent
->kind
== PROGRAM
)
104 llvm_codegen_visit_identifier_list (struct _Visitor
*visitor
, struct AstNode
*node
)
106 struct AstNode
*child
;
108 /* FIXME */ fprintf(stderr
, "Never reaches here?\n");
109 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
110 ast_node_accept(child
, visitor
);
111 if (child
->sibling
!= NULL
)
117 llvm_codegen_visit_procfunc_list (struct _Visitor
*visitor
, struct AstNode
*node
)
119 ast_node_accept_children(node
->children
, visitor
);
123 llvm_codegen_visit_procfunc (struct _Visitor
*visitor
, struct AstNode
*node
)
125 struct AstNode
*child
;
128 PRINT_TYPE(node
->type
);
131 child
= node
->children
; // Identifier
132 ast_node_accept(child
, visitor
);
136 child
= child
->sibling
;
137 if (child
->kind
== PARAM_LIST
) {
138 ast_node_accept(child
, visitor
);
139 child
= child
->sibling
;
145 if (child
->kind
== VARDECL_LIST
) {
146 ast_node_accept(child
, visitor
);
147 child
= child
->sibling
;
150 ast_node_accept(child
, visitor
);
153 PRINT_TYPE(node
->type
);
154 if (node
->kind
== FUNCTION
) {
156 PRINT_VALUE(node
->children
, node
->children
->symbol
->stack_index
);
163 llvm_codegen_visit_param_list (struct _Visitor
*visitor
, struct AstNode
*node
)
165 struct AstNode
*child
;
167 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
168 ast_node_accept(child
, visitor
);
169 if (child
->sibling
!= NULL
)
175 llvm_codegen_visit_statement_list (struct _Visitor
*visitor
, struct AstNode
*node
)
177 struct AstNode
*child
;
181 for (child
= node
->children
; child
!= NULL
; child
= child
->sibling
) {
182 ast_node_accept(child
, visitor
);
188 llvm_codegen_visit_binary_expr (struct _Visitor
*visitor
, struct AstNode
*node
)
192 struct AstNode
*lnode
= node
->children
;
193 struct AstNode
*op
= lnode
->sibling
;
194 struct AstNode
*rnode
= op
->sibling
;
196 int __process_binexpr_node(struct AstNode
*node
) {
197 if (node
->kind
== IDENTIFIER
) {
198 if (node
->symbol
->is_global
) {
199 if (symbol_is_procfunc(node
->symbol
))
200 return node
->symbol
->stack_index
;
202 _print_load(node
, visitor
);
206 } else if (!IS_LITERAL(node
->kind
)) {
207 ast_node_accept(node
, visitor
);
214 void __print_operand(struct AstNode
*node
, int index
) {
216 printf("%%%d", index
);
217 else if (node
->symbol
!= NULL
&& symbol_is_procfunc(node
->symbol
))
220 ast_node_accept(node
, visitor
);
223 /* Construcao mais simples */
224 if (IS_LITERAL(lnode
->kind
) && IS_LITERAL(rnode
->kind
)) {
225 ast_node_accept(op
, visitor
);
227 PRINT_TYPE(lnode
->type
);
229 ast_node_accept(lnode
, visitor
);
231 ast_node_accept(rnode
, visitor
);
234 /* Construcoes complexas */
236 lindex
= __process_binexpr_node(lnode
);
237 rindex
= __process_binexpr_node(rnode
);
239 ast_node_accept(op
, visitor
);
241 PRINT_TYPE(lnode
->type
);
244 __print_operand(lnode
, lindex
);
246 __print_operand(rnode
, rindex
);
255 llvm_codegen_visit_callparam_list (struct _Visitor
*visitor
, struct AstNode
*node
)
257 ast_node_accept(node
->children
, visitor
);
261 llvm_codegen_visit_callparam (struct _Visitor
*visitor
, struct AstNode
*node
)
263 ast_node_accept(node
->children
, visitor
);
267 llvm_codegen_visit_identifier (struct _Visitor
*visitor
, struct AstNode
*node
)
269 Symbol
*sym
= node
->symbol
;
271 if (sym
->is_global
|| node
->parent
->kind
== CALL
)
272 printf("@%s", sym
->name
);
274 else if (!sym
->is_global
&& node
->parent
->kind
== PARAMETER
&&
275 sym
->stack_index
== -1)
276 printf("%%%s", sym
->name
);
278 else if (sym
->stack_index
> -1)
279 printf("%%%d", sym
->stack_index
);
286 llvm_codegen_visit_literal (struct _Visitor
*visitor
, struct AstNode
*node
)
288 printf("%d", node
->value
.integer
);
292 llvm_codegen_visit_vardecl (struct _Visitor
*visitor
, struct AstNode
*node
)
294 struct AstNode
*child
;
296 child
= node
->children
;
298 for (child
= child
->children
; child
!= NULL
; child
= child
->sibling
) {
299 if (node
->parent
->parent
->kind
== PROGRAM
) {
300 ast_node_accept(child
, visitor
);
301 printf(" = global i%d 0\n", _get_type_size(child
->type
));
303 child
->symbol
->stack_index
= -1;
309 llvm_codegen_visit_parameter (struct _Visitor
*visitor
, struct AstNode
*node
)
311 PRINT_TYPE(node
->type
);
313 ast_node_accept(node
->children
, visitor
);
317 llvm_codegen_visit_printint_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
320 struct AstNode
*child
= node
->children
;
322 index
= _process_expression(child
, visitor
);
324 printf(TAB
"call i32 (i8* noalias , ...)* bitcast (i32 (i8*, ...)* \n");
325 printf(TAB TAB
"@printf to i32 (i8* noalias, ...)*)\n");
326 printf(TAB TAB
"( i8* getelementptr ");
327 printf("([3 x i8]* @.int_fmt, i32 0, i32 0) noalias ,\n");
328 printf(TAB TAB
"i32 ");
329 PRINT_VALUE(child
, index
);
336 llvm_codegen_visit_printchar_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
339 struct AstNode
*child
= node
->children
;
341 index
= _process_expression(child
, visitor
);
343 printf(TAB
"call i32 @putchar ( i32 ");
344 PRINT_VALUE(child
, index
);
350 llvm_codegen_visit_printbool_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
353 struct AstNode
*child
= node
->children
;
355 index
= _process_expression(child
, visitor
);
358 printf(TAB
"load i8** getelementptr ([2 x i8*]* @bool_str, i32 0, i32 %d )"
359 ", align 4\n", ast_node_get_value_as_int(child
));
361 printf(TAB
"getelementptr [2 x i8*]* @bool_str, i32 0, i32 %%%d\n",
364 printf(TAB
"load i8** %%%d, align 4\n", stack_size
);
368 printf(TAB
"call i32 (i8* noalias , ...)* bitcast (i32 (i8*, ...)* \n");
369 printf(TAB TAB
"@printf to i32 (i8* noalias , ...)*)\n");
370 printf(TAB TAB
"( i8* getelementptr ");
371 printf("([3 x i8]* @.bool_fmt, i32 0, i32 0) noalias , \n");
372 printf(TAB TAB
"i8* %%%d )\n", stack_size
);
377 llvm_codegen_visit_printline_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
379 printf(TAB
"call i32 @putchar( i32 10 )\n");
384 llvm_codegen_visit_assignment_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
387 struct AstNode
*lnode
= node
->children
;
388 struct AstNode
*rnode
= lnode
->sibling
;
390 /* FIXME * */printf("; [Assignment][%s] %s(%d/%d) = %d\n", rnode
->name
,
391 lnode
->symbol
->name
, lnode
->symbol
->stack_index
,
392 stack_size
, ast_node_get_value_as_int(rnode
));
396 rindex
= _process_expression(rnode
, visitor
);
399 if (lnode
->symbol
->is_global
&& !symbol_is_procfunc(lnode
->symbol
)) {
401 PRINT_TYPE(lnode
->type
);
403 PRINT_VALUE(rnode
, rindex
);
405 PRINT_TYPE(lnode
->type
);
407 ast_node_accept(lnode
, visitor
);
408 printf(", align 4\n");
410 } else if (rindex
== -1) {
411 /*lnode->symbol->stack_index = -1;
412 lnode->symbol->value.integer = rnode->value.integer;
413 lnode->value.integer = rnode->value.integer;*/
415 PRINT_TYPE(lnode
->type
);
417 PRINT_VALUE(rnode
, rindex
);
420 lnode
->symbol
->stack_index
= stack_size
;
423 lnode
->symbol
->stack_index
= rindex
;
426 /* FIXME */ printf("; [Assignment][%s] %s(%d/%d) = %d\n", rnode
->name
,
427 lnode
->symbol
->name
, lnode
->symbol
->stack_index
,
428 stack_size
, ast_node_get_value_as_int(rnode
));
433 llvm_codegen_visit_if_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
436 struct AstNode
*expr
= node
->children
;
437 struct AstNode
*cmd1
= expr
->sibling
;
438 struct AstNode
*cmd2
= cmd1
->sibling
;
440 printf("; if evaluation, line %d\n", node
->linenum
);
442 index
= _process_expression(expr
, visitor
);
445 PRINT_VALUE(expr
, index
);
446 printf(", label %%cond_true_%x, label ", node
);
449 printf("%%cond_next_%x\n", node
);
451 printf("%%cond_false_%x\n", node
);
453 printf("\ncond_true_%x:\n", node
);
454 ast_node_accept(cmd1
, visitor
);
455 printf(TAB
"br label %%cond_next_%x\n", node
);
458 printf("\ncond_false_%x:\n", node
);
459 ast_node_accept(cmd2
, visitor
);
460 printf(TAB
"br label %%cond_next_%x\n", node
);
463 printf("\ncond_next_%x:\n", node
);
467 llvm_codegen_visit_while_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
469 struct AstNode
*child
;
473 child
= node
->children
; // Expression
474 ast_node_accept(child
, visitor
);
477 child
= child
->sibling
; // Statements
478 ast_node_accept(child
, visitor
);
484 llvm_codegen_visit_for_stmt (struct _Visitor
*visitor
, struct AstNode
*node
)
487 struct AstNode
*asgn
= node
->children
;
488 struct AstNode
*expr
= asgn
->sibling
;
489 struct AstNode
*stmt
= expr
->sibling
;
491 printf("; for evaluation, line %d\n", node
->linenum
);
494 ast_node_accept(asgn
, visitor
);
497 %tmp714 = icmp sgt i32 %tmp512, 0 ; <i1> [#uses=1]
498 br i1 %tmp714, label %bb.preheader, label %bb9
500 index
= _process_expression(expr
, visitor
);
503 PRINT_VALUE(expr
, index
);
504 printf(", label %%bb_%x.preheader, label %%bb_%x\n", node
, node
);
507 bb.preheader: ; preds = %entry
508 %b.promoted = load i32* @b, align 4 ; <i32> [#uses=1]
511 printf("\nbb_%x.preheader:\n", node
);
515 bb: ; preds = %bb, %bb.preheader
516 %ITERADOR.010.0 = phi i32 [ 0, %bb.preheader ], [ %tmp3, %bb ] ; <i32> [#uses=2]
517 %tmp3 = add i32 %ITERADOR.010.0, 1 ; <i32> [#uses=2]
518 %tmp7 = icmp slt i32 %tmp3, %tmp512 ; <i1> [#uses=1]
519 br i1 %tmp7, label %bb, label %bb9.loopexit
523 bb9.loopexit: ; preds = %bb
524 %b.tmp.0 = add i32 %ITERADOR.010.0, %b.promoted ; <i32> [#uses=1]
525 %tmp1 = add i32 %b.tmp.0, 1 ; <i32> [#uses=1]
526 store i32 %tmp1, i32* @b, align 4
531 bb9: ; preds = %bb9.loopexit, %entry
535 printf("\ncond_true_%x:\n", node
);
536 ast_node_accept(stmt
, visitor
);
537 printf(TAB
"br label %%cond_next_%x\n", node
);
539 printf("\ncond_next_%x:\n", node
);
543 llvm_codegen_visit_notfactor (struct _Visitor
*visitor
, struct AstNode
*node
)
545 ast_node_accept_children(node
->children
, visitor
);
549 llvm_codegen_visit_call (struct _Visitor
*visitor
, struct AstNode
*node
)
553 struct AstNode *temp, *child = node->children;
555 index = _process_expression(child, visitor);
557 temp= child->sibling;
559 for (temp = temp->children; temp != NULL; temp = temp->sibling) {
560 PRINT_TYPE(child->type);
562 ast_node_accept(child, visitor);
563 if (child->sibling != NULL)
569 PRINT_TYPE(child->symbol->type);
571 ast_node_accept(child, visitor);
577 struct AstNode
*child
= node
->children
;
580 PRINT_TYPE(child
->symbol
->type
);
582 ast_node_accept(child
, visitor
);
585 child
= child
->sibling
;
587 for (child
= child
->children
; child
!= NULL
; child
= child
->sibling
) {
588 PRINT_TYPE(child
->type
);
590 ast_node_accept(child
, visitor
);
591 if (child
->sibling
!= NULL
)
601 llvm_codegen_visit_simplenode (struct _Visitor
*visitor
, struct AstNode
*node
)
603 ast_node_accept_children(node
->children
, visitor
);
607 llvm_codegen_visit_binary_op (struct _Visitor
*visitor
, struct AstNode
*node
)
609 /* FIXME *printf("; %%%d = \n", stack_size + 1);*/
610 switch (node
->kind
) {
618 printf(TAB
"icmp eq");
621 printf(TAB
"icmp ne");
624 printf(TAB
"icmp slt");
627 printf(TAB
"icmp sgt");
630 printf(TAB
"icmp sle");
633 printf(TAB
"icmp sge");
645 printf(" %s ", node->name);*/
650 llvm_codegen_visit_not_op (struct _Visitor
*visitor
, struct AstNode
*node
)
652 printf(" !", node
->name
);
656 _print_boolean(struct AstNode
*node
)
658 printf("%bool_str = getelementptr [");
659 if (node
->value
.boolean
)
660 printf("5 x i8]* @.true");
662 printf("6 x i8]* @.false");
663 printf("_str, i32 0, i32 0\n");
667 _print_load(struct AstNode
*node
, Visitor
*visitor
)
670 PRINT_TYPE(node
->type
);
672 ast_node_accept(node
, visitor
);
673 printf(", align 4\n");
678 _get_type_size(Type type
)
693 _process_expression(struct AstNode
*rnode
, Visitor
*visitor
)
695 if (!IS_LITERAL(rnode
->kind
)) {
696 if (rnode
->kind
!= IDENTIFIER
) {
697 ast_node_accept(rnode
, visitor
);
700 } else if (rnode
->symbol
->is_global
) {
701 _print_load(rnode
, visitor
);
705 return rnode
->symbol
->stack_index
;