commit eecbe645ffee51c58fc1be60dc935c7de3a0e58b
parent 54a775e2819f31d961757550e5a24804a8caac29
Author: erai <erai@omiltem.net>
Date: Mon, 27 Jan 2025 22:47:59 +0000
ir calling convention
Diffstat:
M | cc0.c | | | 269 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
M | ir.om | | | 256 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ |
2 files changed, 350 insertions(+), 175 deletions(-)
diff --git a/cc0.c b/cc0.c
@@ -12,7 +12,7 @@ struct my_decl;
struct my_file;
struct my_fixup;
struct my_irblock;
-struct my_ircomp;
+struct my_irfunc;
struct my_irlabel;
struct my_irloopctx;
struct my_irop;
@@ -126,15 +126,18 @@ struct my_irblock {
struct my_irblock* my_alt;
unsigned long my_mark;
};
-struct my_ircomp {
+struct my_irfunc {
struct my_compiler* my_c;
struct my_alloc* my_a;
+ unsigned char* my_name;
struct my_irloopctx* my_loopctx;
struct my_irblock* my_top;
struct my_irblock* my_cur;
- struct my_irlabel* my_labels;
- struct my_irvar* my_vars;
- unsigned long my_numvars;
+ struct my_irlabel* my_labels_tree;
+ struct my_irvar* my_vars_tree;
+ struct my_irvar** my_vars;
+ unsigned long my_vars_len;
+ unsigned long my_vars_cap;
};
struct my_irlabel {
unsigned char* my_name;
@@ -154,6 +157,9 @@ struct my_irop {
unsigned long my_n;
unsigned char* my_s;
struct my_type* my_t;
+ unsigned char* my_filename;
+ unsigned long my_lineno;
+ unsigned long my_colno;
};
struct my_irvar {
unsigned char* my_name;
@@ -300,36 +306,37 @@ enum {
my_EINTR = 4,
my_EPIPE = 32,
my_EXACTLY_ONE = 1,
- my_IOP_ADD = 10,
- my_IOP_AND = 11,
- my_IOP_ARG = 6,
- my_IOP_BRANCH = 28,
- my_IOP_CALL = 26,
+ my_IOP_ADD = 11,
+ my_IOP_AND = 12,
+ my_IOP_ARG = 8,
+ my_IOP_BRANCH = 29,
+ my_IOP_CALL = 27,
my_IOP_CONST = 2,
- my_IOP_DIV = 14,
- my_IOP_EQ = 20,
+ my_IOP_DIV = 15,
+ my_IOP_EQ = 21,
my_IOP_FUNC = 1,
- my_IOP_GE = 23,
- my_IOP_GT = 22,
- my_IOP_JUMP = 27,
- my_IOP_LE = 25,
+ my_IOP_GE = 24,
+ my_IOP_GT = 23,
+ my_IOP_JUMP = 28,
+ my_IOP_LE = 26,
my_IOP_LOAD = 4,
- my_IOP_LSH = 16,
- my_IOP_LT = 24,
- my_IOP_MOD = 15,
- my_IOP_MUL = 18,
- my_IOP_NE = 21,
- my_IOP_NEG = 8,
- my_IOP_NOT = 9,
- my_IOP_OR = 12,
- my_IOP_REF = 7,
- my_IOP_RETURN = 29,
- my_IOP_RSH = 17,
+ my_IOP_LSH = 17,
+ my_IOP_LT = 25,
+ my_IOP_MOD = 16,
+ my_IOP_MUL = 19,
+ my_IOP_NE = 22,
+ my_IOP_NEG = 9,
+ my_IOP_NOT = 10,
+ my_IOP_OR = 13,
+ my_IOP_REF = 6,
+ my_IOP_RETURN = 30,
+ my_IOP_RETVAL = 7,
+ my_IOP_RSH = 18,
my_IOP_STORE = 5,
my_IOP_STR = 3,
- my_IOP_SUB = 19,
+ my_IOP_SUB = 20,
my_IOP_VAR = 0,
- my_IOP_XOR = 13,
+ my_IOP_XOR = 14,
my_LOOK_AND = 2,
my_LOOK_NORMAL = 0,
my_LOOK_NOT = 1,
@@ -645,7 +652,7 @@ void( my_add_symbol)(struct my_assembler* my_c,unsigned char* my_name,struct my_
void( my_addfixup)(struct my_assembler* my_c,struct my_label* my_l);
unsigned char*( my_alloc)(struct my_alloc* my_c,unsigned long my_size);
unsigned long( my_any)(struct my_peg* my_c);
-void( my_args_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n);
+void( my_args_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
void( my_as_emit)(struct my_assembler* my_a,unsigned long my_b);
void( my_as_jmp)(struct my_assembler* my_a,unsigned long my_op,struct my_label* my_l);
void( my_as_modm)(struct my_assembler* my_a,unsigned long my_op,unsigned long my_b,unsigned long my_i,unsigned long my_s,unsigned long my_d);
@@ -743,7 +750,7 @@ void( my_emit_ud)(struct my_assembler* my_c);
void( my_emit_xor)(struct my_assembler* my_c);
void( my_enter)(struct my_peg* my_c,unsigned long my_tag);
void( my_exit)(unsigned long my_n);
-struct my_irop*( my_expr_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n);
+struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
void( my_fail)(struct my_peg* my_c);
void( my_fclose)(struct my_file* my_f);
void( my_fdputc)(unsigned long my_fd,unsigned long my_ch);
@@ -767,37 +774,38 @@ void( my_fputh)(struct my_file* my_out,unsigned long my_n);
void( my_fputs)(struct my_file* my_f,unsigned char* my_s);
unsigned char*( my_freadall)(struct my_file* my_f,unsigned long* my_size);
void( my_free)(struct my_alloc* my_a,unsigned char* my_p);
-void( my_func_to_ir)(struct my_compiler* my_c,struct my_node* my_n);
+struct my_irfunc*( my_func_to_ir)(struct my_compiler* my_c,struct my_node* my_n);
unsigned long( my_get)(struct my_peg* my_c);
unsigned long( my_hex2int)(unsigned char* my_s,unsigned long my_len,unsigned long* my_ok);
unsigned long( my_hexdig)(unsigned long my_ch,unsigned long* my_ok);
unsigned long( my_hoist_locals)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n,unsigned long my_offset);
-void( my_iraddarg)(struct my_ircomp* my_ic,unsigned char* my_name,struct my_type* my_t);
-void( my_iraddop)(struct my_ircomp* my_ic,struct my_irop* my_o);
-void( my_iraddvar)(struct my_ircomp* my_ic,unsigned char* my_name,struct my_type* my_t);
-void( my_irbranch)(struct my_ircomp* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next);
-struct my_irop*( my_ircall)(struct my_ircomp* my_ic,struct my_node* my_n);
-struct my_irblock*( my_irfind_block)(struct my_ircomp* my_ic,unsigned char* my_name,unsigned long my_make);
-struct my_irvar*( my_irfind_var)(struct my_ircomp* my_ic,unsigned char* my_name,unsigned long my_make);
-void( my_irjump)(struct my_ircomp* my_ic,struct my_irblock* my_to,struct my_irblock* my_next);
-void( my_irreturn)(struct my_ircomp* my_ic,struct my_irop* my_value);
-void( my_labels_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n);
+void( my_iraddarg)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t);
+void( my_iraddop)(struct my_irfunc* my_ic,struct my_irop* my_o);
+void( my_iraddvar)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t);
+void( my_irbranch)(struct my_irfunc* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next);
+struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n);
+struct my_irblock*( my_irfind_block)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make);
+struct my_irvar*( my_irfind_var)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make);
+void( my_irjump)(struct my_irfunc* my_ic,struct my_irblock* my_to,struct my_irblock* my_next);
+void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value);
+void( my_labels_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
void( my_layout_struct)(struct my_compiler* my_c,struct my_decl* my_d);
void( my_layout_union)(struct my_compiler* my_c,struct my_decl* my_d);
void( my_leave)(struct my_peg* my_c,unsigned long my_tag);
unsigned long( my_literal)(struct my_peg* my_c,unsigned char* my_s);
-void( my_locals_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n);
+void( my_locals_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
void( my_main)(unsigned long my_argc,unsigned char** my_argv,unsigned char** my_envp);
void( my_mark_expr_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n);
void( my_mark_func_used)(struct my_compiler* my_c,struct my_decl* my_d);
void( my_mark_stmt_used)(struct my_compiler* my_c,struct my_decl* my_d,struct my_node* my_n);
void( my_memcpy)(unsigned char* my_dest,unsigned char* my_src,unsigned long my_size);
void( my_memset)(unsigned char* my_dest,unsigned long my_c,unsigned long my_size);
-struct my_irblock*( my_mkirblock)(struct my_ircomp* my_ic);
-struct my_irop*( my_mkirconst)(struct my_ircomp* my_ic,unsigned long my_n);
-struct my_irop*( my_mkirop)(struct my_ircomp* my_ic,unsigned long my_kind,struct my_irop* my_a,struct my_irop* my_b);
-struct my_irop*( my_mkirstr)(struct my_ircomp* my_ic,unsigned char* my_s);
-struct my_irop*( my_mkirtmp)(struct my_ircomp* my_ic);
+struct my_irblock*( my_mkirblock)(struct my_irfunc* my_ic);
+struct my_irop*( my_mkirconst)(struct my_irfunc* my_ic,unsigned long my_n);
+struct my_irop*( my_mkirop)(struct my_irfunc* my_ic,unsigned long my_kind,struct my_irop* my_a,struct my_irop* my_b);
+struct my_irop*( my_mkirstr)(struct my_irfunc* my_ic,unsigned char* my_s);
+struct my_irop*( my_mkirtmp)(struct my_irfunc* my_ic);
+struct my_irvar*( my_mkirvar)(struct my_irfunc* my_ic);
struct my_label*( my_mklabel)(struct my_assembler* my_c);
struct my_node*( my_mknode)(struct my_parser* my_c,unsigned long my_kind,struct my_node* my_a,struct my_node* my_b);
struct my_node*( my_mknode0)(struct my_parser* my_c,unsigned long my_kind);
@@ -978,7 +986,7 @@ struct my_assembler*( my_setup_assembler)(struct my_alloc* my_a);
struct my_parser*( my_setup_parser)(struct my_alloc* my_a);
struct my_peg_compiler*( my_setup_peg)(struct my_alloc* my_a,unsigned char* my_prefix);
void( my_show_node)(struct my_file* my_out,struct my_node* my_n);
-void( my_stmt_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n);
+void( my_stmt_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n);
unsigned long( my_strcmp)(unsigned char* my_a,unsigned char* my_b);
unsigned long( my_strlen)(unsigned char* my_s);
unsigned long( my_syscall)(unsigned long my_n,unsigned long my_a1,unsigned long my_a2,unsigned long my_a3,unsigned long my_a4,unsigned long my_a5,unsigned long my_a6);
@@ -1427,7 +1435,7 @@ unsigned long( my_any)(struct my_peg* my_c){
}
return 1UL;
}
-void( my_args_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n){
+void( my_args_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
unsigned char* my_name = 0;
struct my_type* my_t = 0;
while (1) {
@@ -2829,6 +2837,9 @@ void( my_ctranslate_zero)(struct my_compiler* my_c,struct my_type* my_ty){
(my_v)=((my_find)((my_c),(((my_ty)->my_st)->my_name),((((my_n)->my_a)->my_a)->my_s),(0UL)));
(my_ctranslate_zero)((my_c),((my_v)->my_member_type));
(my_n)=((my_n)->my_b);
+ if (my_n) {
+ (my_fputs)(((my_c)->my_cout),((unsigned char *)", "));
+ }
}
(my_fputs)(((my_c)->my_cout),((unsigned char *)"}"));
} else if ((unsigned long)(((long)((my_ty)->my_kind))==((long)(my_TY_UNION)))) {
@@ -4380,7 +4391,7 @@ void( my_enter)(struct my_peg* my_c,unsigned long my_tag){
void( my_exit)(unsigned long my_n){
(my_syscall)((60UL),(my_n),(0UL),(0UL),(0UL),(0UL),(0UL));
}
-struct my_irop*( my_expr_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n){
+struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
struct my_irop* my_a = 0;
struct my_irop* my_b = 0;
struct my_irop* my_c = 0;
@@ -4987,26 +4998,29 @@ unsigned char*( my_freadall)(struct my_file* my_f,unsigned long* my_size){
}
void( my_free)(struct my_alloc* my_a,unsigned char* my_p){
}
-void( my_func_to_ir)(struct my_compiler* my_c,struct my_node* my_n){
- struct my_ircomp my_ic = {00000000};
+struct my_irfunc*( my_func_to_ir)(struct my_compiler* my_c,struct my_node* my_n){
+ struct my_irfunc* my_ic = 0;
struct my_irop* my_value = 0;
struct my_type* my_t = 0;
if ((unsigned long)(!(my_n))) {
- return;
+ return (void *)0;
}
- ((my_ic).my_c)=(my_c);
- ((my_ic).my_a)=((my_c)->my_a);
- ((my_ic).my_top)=((my_mkirblock)((&(my_ic))));
- ((my_ic).my_cur)=((my_ic).my_top);
- (my_args_to_ir)((&(my_ic)),((((my_n)->my_a)->my_b)->my_a));
- (my_locals_to_ir)((&(my_ic)),((my_n)->my_b));
- (my_labels_to_ir)((&(my_ic)),((my_n)->my_b));
- (my_stmt_to_ir)((&(my_ic)),((my_n)->my_b));
+ (my_ic)=((struct my_irfunc*)(my_alloc)(((my_c)->my_a),(88UL)));
+ ((my_ic)->my_c)=(my_c);
+ ((my_ic)->my_a)=((my_c)->my_a);
+ ((my_ic)->my_top)=((my_mkirblock)((my_ic)));
+ ((my_ic)->my_cur)=((my_ic)->my_top);
+ ((my_ic)->my_name)=((((my_n)->my_a)->my_a)->my_s);
+ (my_args_to_ir)((my_ic),((((my_n)->my_a)->my_b)->my_a));
+ (my_locals_to_ir)((my_ic),((my_n)->my_b));
+ (my_labels_to_ir)((my_ic),((my_n)->my_b));
+ (my_stmt_to_ir)((my_ic),((my_n)->my_b));
(my_t)=((my_prototype)((my_c),(((my_n)->my_a)->my_b)));
if ((unsigned long)(((long)(((my_t)->my_val)->my_kind))==((long)(my_TY_VOID)))) {
- (my_value)=((my_mkirconst)((&(my_ic)),(0UL)));
- (my_irreturn)((&(my_ic)),(my_value));
+ (my_value)=((my_mkirconst)((my_ic),(0UL)));
+ (my_irreturn)((my_ic),(my_value));
}
+ return my_ic;
}
unsigned long( my_get)(struct my_peg* my_c){
unsigned long my_ch = 0;
@@ -5130,10 +5144,10 @@ unsigned long( my_hoist_locals)(struct my_compiler* my_c,struct my_decl* my_d,st
((my_v)->my_var_offset)=((unsigned long)(-(unsigned long)(my_offset)));
return my_offset;
}
-void( my_iraddarg)(struct my_ircomp* my_ic,unsigned char* my_name,struct my_type* my_t){
+void( my_iraddarg)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t){
(my_irfind_var)((my_ic),(my_name),(1UL));
}
-void( my_iraddop)(struct my_ircomp* my_ic,struct my_irop* my_o){
+void( my_iraddop)(struct my_irfunc* my_ic,struct my_irop* my_o){
struct my_irblock* my_cur = 0;
struct my_irop** my_ops = 0;
unsigned long my_i = 0;
@@ -5159,10 +5173,10 @@ void( my_iraddop)(struct my_ircomp* my_ic,struct my_irop* my_o){
(((my_cur)->my_ops)[(my_cur)->my_ops_len])=(my_o);
((my_cur)->my_ops_len)=((unsigned long)(((unsigned long)((my_cur)->my_ops_len))+((unsigned long)(1UL))));
}
-void( my_iraddvar)(struct my_ircomp* my_ic,unsigned char* my_name,struct my_type* my_t){
+void( my_iraddvar)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t){
(my_irfind_var)((my_ic),(my_name),(1UL));
}
-void( my_irbranch)(struct my_ircomp* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next){
+void( my_irbranch)(struct my_irfunc* my_ic,struct my_irop* my_cond,struct my_irblock* my_alt,struct my_irblock* my_next){
struct my_irblock* my_cur = 0;
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_BRANCH),(my_cond),((void *)0)));
@@ -5178,7 +5192,7 @@ void( my_irbranch)(struct my_ircomp* my_ic,struct my_irop* my_cond,struct my_irb
}
((my_ic)->my_cur)=(my_next);
}
-struct my_irop*( my_ircall)(struct my_ircomp* my_ic,struct my_node* my_n){
+struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){
struct my_irop* my_o = 0;
struct my_irop* my_a = 0;
struct my_irop* my_b = 0;
@@ -5186,25 +5200,62 @@ struct my_irop*( my_ircall)(struct my_ircomp* my_ic,struct my_node* my_n){
struct my_irblock* my_next = 0;
struct my_irblock* my_cur = 0;
struct my_node* my_arg = 0;
+ struct my_irop** my_tmp = 0;
+ struct my_irop* my_fp = 0;
unsigned long my_i = 0;
+ unsigned long my_count = 0;
+ (my_fp)=((my_mkirtmp)((my_ic)));
+ (my_b)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
+ (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_fp),((void *)0)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ ((my_o)->my_t)=(((my_n)->my_a)->my_t);
+ (my_iraddop)((my_ic),(my_o));
+ (my_arg)=((my_n)->my_b);
+ (my_count)=(0UL);
+ while (1) {
+ if ((unsigned long)(!(my_arg))) {
+ break;
+ }
+ (my_count)=((unsigned long)(((unsigned long)(my_count))+((unsigned long)(1UL))));
+ (my_arg)=((my_arg)->my_b);
+ }
+ (my_tmp)=((struct my_irop**)(my_alloc)(((my_ic)->my_a),((unsigned long)(((long)(8UL))*((long)(my_count))))));
(my_arg)=((my_n)->my_b);
(my_i)=(0UL);
while (1) {
if ((unsigned long)(!(my_arg))) {
break;
}
- (my_a)=((my_expr_to_ir)((my_ic),((my_arg)->my_a)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_ARG),(my_a),((void *)0)));
+ ((my_tmp)[my_i])=((my_mkirtmp)((my_ic)));
+ (my_b)=((my_expr_to_ir)((my_ic),((my_arg)->my_a)));
+ (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),((my_tmp)[my_i]),((void *)0)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b)));
+ ((my_o)->my_t)=(((my_arg)->my_a)->my_t);
+ (my_iraddop)((my_ic),(my_o));
+ (my_arg)=((my_arg)->my_b);
+ (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
+ }
+ (my_arg)=((my_n)->my_b);
+ (my_i)=(0UL);
+ while (1) {
+ if ((unsigned long)(((long)(my_i))==((long)(my_count)))) {
+ break;
+ }
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_ARG),((my_tmp)[my_i]),((void *)0)));
((my_o)->my_n)=(my_i);
((my_o)->my_t)=(((my_arg)->my_a)->my_t);
(my_iraddop)((my_ic),(my_o));
(my_arg)=((my_arg)->my_b);
(my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
}
- (my_b)=((my_expr_to_ir)((my_ic),((my_n)->my_a)));
+ (my_free)(((my_ic)->my_a),((unsigned char*)my_tmp));
(my_ret)=((my_mkirtmp)((my_ic)));
- (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_ret),((void *)0)));
- (my_o)=((my_mkirop)((my_ic),(my_IOP_CALL),(my_a),(my_b)));
+ (my_b)=((my_mkirop)((my_ic),(my_IOP_REF),(my_ret),((void *)0)));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_RETVAL),(my_b),((void *)0)));
+ ((my_o)->my_t)=((my_n)->my_t);
+ (my_iraddop)((my_ic),(my_o));
+ (my_o)=((my_mkirop)((my_ic),(my_IOP_CALL),(my_fp),((void *)0)));
+ ((my_o)->my_n)=(my_count);
(my_iraddop)((my_ic),(my_o));
(my_next)=((my_mkirblock)((my_ic)));
(my_cur)=((my_ic)->my_cur);
@@ -5218,11 +5269,11 @@ struct my_irop*( my_ircall)(struct my_ircomp* my_ic,struct my_node* my_n){
((my_ic)->my_cur)=(my_next);
return my_ret;
}
-struct my_irblock*( my_irfind_block)(struct my_ircomp* my_ic,unsigned char* my_name,unsigned long my_make){
+struct my_irblock*( my_irfind_block)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make){
struct my_irlabel** my_link = 0;
struct my_irlabel* my_l = 0;
unsigned long my_dir = 0;
- (my_link)=(&((my_ic)->my_labels));
+ (my_link)=(&((my_ic)->my_labels_tree));
while (1) {
(my_l)=(*(my_link));
if ((unsigned long)(!(my_l))) {
@@ -5251,11 +5302,11 @@ struct my_irblock*( my_irfind_block)(struct my_ircomp* my_ic,unsigned char* my_n
(*(my_link))=(my_l);
return (my_l)->my_block;
}
-struct my_irvar*( my_irfind_var)(struct my_ircomp* my_ic,unsigned char* my_name,unsigned long my_make){
+struct my_irvar*( my_irfind_var)(struct my_irfunc* my_ic,unsigned char* my_name,unsigned long my_make){
struct my_irvar** my_link = 0;
struct my_irvar* my_v = 0;
unsigned long my_dir = 0;
- (my_link)=(&((my_ic)->my_vars));
+ (my_link)=(&((my_ic)->my_vars_tree));
while (1) {
(my_v)=(*(my_link));
if ((unsigned long)(!(my_v))) {
@@ -5276,16 +5327,12 @@ struct my_irvar*( my_irfind_var)(struct my_ircomp* my_ic,unsigned char* my_name,
if ((unsigned long)(!(my_make))) {
return (void *)0;
}
- (my_v)=((struct my_irvar*)(my_alloc)(((my_ic)->my_a),(32UL)));
+ (my_v)=((my_mkirvar)((my_ic)));
((my_v)->my_name)=(my_name);
- ((my_v)->my_left)=((void *)0);
- ((my_v)->my_right)=((void *)0);
- ((my_v)->my_n)=((my_ic)->my_numvars);
- ((my_ic)->my_numvars)=((unsigned long)(((unsigned long)((my_ic)->my_numvars))+((unsigned long)(1UL))));
(*(my_link))=(my_v);
return my_v;
}
-void( my_irjump)(struct my_ircomp* my_ic,struct my_irblock* my_to,struct my_irblock* my_next){
+void( my_irjump)(struct my_irfunc* my_ic,struct my_irblock* my_to,struct my_irblock* my_next){
struct my_irblock* my_cur = 0;
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_JUMP),((void *)0),((void *)0)));
@@ -5300,7 +5347,7 @@ void( my_irjump)(struct my_ircomp* my_ic,struct my_irblock* my_to,struct my_irbl
}
((my_ic)->my_cur)=(my_next);
}
-void( my_irreturn)(struct my_ircomp* my_ic,struct my_irop* my_value){
+void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value){
struct my_irblock* my_cur = 0;
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_RETURN),(my_value),((void *)0)));
@@ -5314,7 +5361,7 @@ void( my_irreturn)(struct my_ircomp* my_ic,struct my_irop* my_value){
}
((my_ic)->my_cur)=((void *)0);
}
-void( my_labels_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n){
+void( my_labels_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
unsigned long my_kind = 0;
unsigned char* my_name = 0;
if ((unsigned long)(!(my_n))) {
@@ -5480,7 +5527,7 @@ unsigned long( my_literal)(struct my_peg* my_c,unsigned char* my_s){
}
return 1UL;
}
-void( my_locals_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n){
+void( my_locals_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
unsigned char* my_name = 0;
struct my_type* my_t = 0;
unsigned long my_kind = 0;
@@ -5758,7 +5805,7 @@ void( my_memset)(unsigned char* my_dest,unsigned long my_c,unsigned long my_size
(my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
}
}
-struct my_irblock*( my_mkirblock)(struct my_ircomp* my_ic){
+struct my_irblock*( my_mkirblock)(struct my_irfunc* my_ic){
struct my_irblock* my_b = 0;
(my_b)=((struct my_irblock*)(my_alloc)(((my_ic)->my_a),(56UL)));
((my_b)->my_ops)=((void *)0);
@@ -5769,36 +5816,64 @@ struct my_irblock*( my_mkirblock)(struct my_ircomp* my_ic){
((my_b)->my_alt)=((void *)0);
return my_b;
}
-struct my_irop*( my_mkirconst)(struct my_ircomp* my_ic,unsigned long my_n){
+struct my_irop*( my_mkirconst)(struct my_irfunc* my_ic,unsigned long my_n){
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_CONST),((void *)0),((void *)0)));
((my_o)->my_n)=(my_n);
return my_o;
}
-struct my_irop*( my_mkirop)(struct my_ircomp* my_ic,unsigned long my_kind,struct my_irop* my_a,struct my_irop* my_b){
+struct my_irop*( my_mkirop)(struct my_irfunc* my_ic,unsigned long my_kind,struct my_irop* my_a,struct my_irop* my_b){
struct my_irop* my_o = 0;
- (my_o)=((struct my_irop*)(my_alloc)(((my_ic)->my_a),(48UL)));
+ (my_o)=((struct my_irop*)(my_alloc)(((my_ic)->my_a),(72UL)));
((my_o)->my_kind)=(my_kind);
((my_o)->my_a)=(my_a);
((my_o)->my_b)=(my_b);
((my_o)->my_n)=(0UL);
((my_o)->my_s)=((void *)0);
((my_o)->my_t)=((void *)0);
+ ((my_o)->my_filename)=(((my_ic)->my_c)->my_filename);
+ ((my_o)->my_lineno)=(((my_ic)->my_c)->my_lineno);
+ ((my_o)->my_colno)=(((my_ic)->my_c)->my_colno);
return my_o;
}
-struct my_irop*( my_mkirstr)(struct my_ircomp* my_ic,unsigned char* my_s){
+struct my_irop*( my_mkirstr)(struct my_irfunc* my_ic,unsigned char* my_s){
struct my_irop* my_o = 0;
(my_o)=((my_mkirop)((my_ic),(my_IOP_STR),((void *)0),((void *)0)));
((my_o)->my_s)=(my_s);
return my_o;
}
-struct my_irop*( my_mkirtmp)(struct my_ircomp* my_ic){
+struct my_irop*( my_mkirtmp)(struct my_irfunc* my_ic){
struct my_irop* my_o = 0;
+ struct my_irvar* my_v = 0;
+ (my_v)=((my_mkirvar)((my_ic)));
(my_o)=((my_mkirop)((my_ic),(my_IOP_VAR),((void *)0),((void *)0)));
- ((my_o)->my_n)=((my_ic)->my_numvars);
- ((my_ic)->my_numvars)=((unsigned long)(((unsigned long)((my_ic)->my_numvars))+((unsigned long)(1UL))));
+ ((my_o)->my_n)=((my_v)->my_n);
return my_o;
}
+struct my_irvar*( my_mkirvar)(struct my_irfunc* my_ic){
+ struct my_irvar* my_v = 0;
+ struct my_irvar** my_tmp = 0;
+ unsigned long my_i = 0;
+ if ((unsigned long)(((long)((my_ic)->my_vars_len))==((long)((my_ic)->my_vars_cap)))) {
+ ((my_ic)->my_vars_cap)=((unsigned long)(((unsigned long)((unsigned long)(((long)((my_ic)->my_vars_cap))*((long)(2UL)))))+((unsigned long)(16UL))));
+ (my_tmp)=((struct my_irvar**)(my_alloc)(((my_ic)->my_a),((unsigned long)(((long)(8UL))*((long)((my_ic)->my_vars_cap))))));
+ (my_i)=(0UL);
+ while (1) {
+ if ((unsigned long)(((long)(my_i))==((long)((my_ic)->my_vars_len)))) {
+ break;
+ }
+ ((my_tmp)[my_i])=(((my_ic)->my_vars)[my_i]);
+ (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL))));
+ }
+ ((my_ic)->my_vars)=(my_tmp);
+ }
+ (my_i)=((my_ic)->my_vars_len);
+ (my_v)=((struct my_irvar*)(my_alloc)(((my_ic)->my_a),(32UL)));
+ ((my_v)->my_n)=(my_i);
+ (((my_ic)->my_vars)[my_i])=(my_v);
+ ((my_ic)->my_vars_len)=((unsigned long)(((unsigned long)((my_ic)->my_vars_len))+((unsigned long)(1UL))));
+ return my_v;
+}
struct my_label*( my_mklabel)(struct my_assembler* my_c){
struct my_label* my_l = 0;
(my_l)=((struct my_label*)(my_alloc)(((my_c)->my_a),(24UL)));
@@ -10198,8 +10273,8 @@ void( my_show_node)(struct my_file* my_out,struct my_node* my_n){
}
(my_fputc)((my_out),(41));
}
-void( my_stmt_to_ir)(struct my_ircomp* my_ic,struct my_node* my_n){
- struct my_irloopctx my_loopctx = {000};
+void( my_stmt_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){
+ struct my_irloopctx my_loopctx = {0, 0, 0};
struct my_irblock* my_cond_body = 0;
struct my_irblock* my_cond_next = 0;
struct my_irblock* my_cond_out = 0;
diff --git a/ir.om b/ir.om
@@ -8,9 +8,12 @@ enum {
// Memory operations
IOP_LOAD,
IOP_STORE,
- IOP_ARG,
IOP_REF,
+ // Calling convention
+ IOP_RETVAL,
+ IOP_ARG,
+
// Unary arithmetic
IOP_NEG,
IOP_NOT,
@@ -49,6 +52,10 @@ struct irop {
n: int;
s: *byte;
t: *type;
+
+ filename: *byte;
+ lineno: int;
+ colno: int;
}
// A basic block is a sequence of expressions that end with a branch
@@ -82,18 +89,21 @@ struct irvar {
n: int;
}
-struct ircomp {
+struct irfunc {
c: *compiler;
a: *alloc;
+ name: *byte;
loopctx: *irloopctx;
top: *irblock;
cur: *irblock;
- labels: *irlabel;
- vars: *irvar;
- numvars: int;
+ labels_tree: *irlabel;
+ vars_tree: *irvar;
+ vars: **irvar;
+ vars_len: int;
+ vars_cap: int;
}
-func mkirblock(ic: *ircomp): *irblock {
+func mkirblock(ic: *irfunc): *irblock {
var b: *irblock;
b = alloc(ic.a, sizeof(*b)) as *irblock;
@@ -108,7 +118,7 @@ func mkirblock(ic: *ircomp): *irblock {
return b;
}
-func mkirop(ic: *ircomp, kind: int, a: *irop, b: *irop): *irop {
+func mkirop(ic: *irfunc, kind: int, a: *irop, b: *irop): *irop {
var o: *irop;
o = alloc(ic.a, sizeof(*o)) as *irop;
@@ -120,10 +130,14 @@ func mkirop(ic: *ircomp, kind: int, a: *irop, b: *irop): *irop {
o.s = nil;
o.t = nil;
+ o.filename = ic.c.filename;
+ o.lineno = ic.c.lineno;
+ o.colno = ic.c.colno;
+
return o;
}
-func mkirconst(ic: *ircomp, n: int): *irop {
+func mkirconst(ic: *irfunc, n: int): *irop {
var o: *irop;
o = mkirop(ic, IOP_CONST, nil, nil);
@@ -133,7 +147,7 @@ func mkirconst(ic: *ircomp, n: int): *irop {
return o;
}
-func mkirstr(ic: *ircomp, s: *byte): *irop {
+func mkirstr(ic: *irfunc, s: *byte): *irop {
var o: *irop;
o = mkirop(ic, IOP_STR, nil, nil);
@@ -143,24 +157,60 @@ func mkirstr(ic: *ircomp, s: *byte): *irop {
return o;
}
-func mkirtmp(ic: *ircomp): *irop {
- var o: *irop;
+func mkirvar(ic: *irfunc): *irvar {
+ var v: *irvar;
+ var tmp: **irvar;
+ var i: int;
- o = mkirop(ic, IOP_VAR, nil, nil);
+ if ic.vars_len == ic.vars_cap {
+ ic.vars_cap = ic.vars_cap * 2 + 16;
+
+ tmp = alloc(ic.a, sizeof(*tmp) * ic.vars_cap) as **irvar;
+
+ i = 0;
+ loop {
+ if i == ic.vars_len {
+ break;
+ }
+
+ tmp[i] = ic.vars[i];
+
+ i = i + 1;
+ }
+
+ ic.vars = tmp;
+ }
+
+ i = ic.vars_len;
+
+ v = alloc(ic.a, sizeof(*v)) as *irvar;
+
+ v.n = i;
+
+ ic.vars[i] = v;
+ ic.vars_len = ic.vars_len + 1;
- o.n = ic.numvars;
+ return v;
+}
- ic.numvars = ic.numvars + 1;
+func mkirtmp(ic: *irfunc): *irop {
+ var o: *irop;
+ var v: *irvar;
+
+ v = mkirvar(ic);
+
+ o = mkirop(ic, IOP_VAR, nil, nil);
+ o.n = v.n;
return o;
}
-func irfind_var(ic: *ircomp, name: *byte, make: int): *irvar {
+func irfind_var(ic: *irfunc, name: *byte, make: int): *irvar {
var link: **irvar;
var v: *irvar;
var dir: int;
- link = &ic.vars;
+ link = &ic.vars_tree;
loop {
v = *link;
@@ -187,29 +237,23 @@ func irfind_var(ic: *ircomp, name: *byte, make: int): *irvar {
return nil;
}
- v = alloc(ic.a, sizeof(*v)) as *irvar;
+ v = mkirvar(ic);
v.name = name;
- v.left = nil;
- v.right = nil;
- v.n = ic.numvars;
-
- ic.numvars = ic.numvars + 1;
-
*link = v;
return v;
}
-func iraddarg(ic: *ircomp, name: *byte, t: *type) {
+func iraddarg(ic: *irfunc, name: *byte, t: *type) {
irfind_var(ic, name, 1);
}
-func iraddvar(ic: *ircomp, name: *byte, t: *type) {
+func iraddvar(ic: *irfunc, name: *byte, t: *type) {
irfind_var(ic, name, 1);
}
-func ircall(ic: *ircomp, n: *node): *irop {
+func ircall(ic: *irfunc, n: *node): *irop {
var o: *irop;
var a: *irop;
var b: *irop;
@@ -217,9 +261,35 @@ func ircall(ic: *ircomp, n: *node): *irop {
var next: *irblock;
var cur: *irblock;
var arg: *node;
+ var tmp: **irop;
+ var fp: *irop;
var i: int;
+ var count: int;
- // Evaluate the arguments
+ // Evaluate the expression left to right starting with the function
+ fp = mkirtmp(ic);
+ b = expr_to_ir(ic, n.a);
+ a = mkirop(ic, IOP_REF, fp, nil);
+ o = mkirop(ic, IOP_STORE, a, b);
+ o.t = n.a.t;
+ iraddop(ic, o);
+
+ // Count the number of arguments
+ arg = n.b;
+ count = 0;
+ loop {
+ if !arg {
+ break;
+ }
+
+ count = count + 1;
+
+ arg = arg.b;
+ }
+
+ tmp = alloc(ic.a, sizeof(*tmp) * count) as **irop;
+
+ // Evaluate the arguments left to right
arg = n.b;
i = 0;
loop {
@@ -227,9 +297,31 @@ func ircall(ic: *ircomp, n: *node): *irop {
break;
}
+ // Create a temporary for this argument
+ tmp[i] = mkirtmp(ic);
+
// Compute the argument value
- a = expr_to_ir(ic, arg.a);
- o = mkirop(ic, IOP_ARG, a, nil);
+ b = expr_to_ir(ic, arg.a);
+
+ // Save the value
+ a = mkirop(ic, IOP_REF, tmp[i], nil);
+ o = mkirop(ic, IOP_STORE, a, b);
+ o.t = arg.a.t;
+ iraddop(ic, o);
+
+ arg = arg.b;
+ i = i + 1;
+ }
+
+ // Emit arg nodes just before the call left to right
+ arg = n.b;
+ i = 0;
+ loop {
+ if i == count {
+ break;
+ }
+
+ o = mkirop(ic, IOP_ARG, tmp[i], nil);
o.n = i;
o.t = arg.a.t;
iraddop(ic, o);
@@ -238,13 +330,18 @@ func ircall(ic: *ircomp, n: *node): *irop {
i = i + 1;
}
- // Compute the function pointer
- b = expr_to_ir(ic, n.a);
+ free(ic.a, tmp as *byte);
- // Emit the call
+ // Add a temporary for the return value
ret = mkirtmp(ic);
- a = mkirop(ic, IOP_REF, ret, nil);
- o = mkirop(ic, IOP_CALL, a, b);
+ b = mkirop(ic, IOP_REF, ret, nil);
+ o = mkirop(ic, IOP_RETVAL, b, nil);
+ o.t = n.t;
+ iraddop(ic, o);
+
+ // Emit the call
+ o = mkirop(ic, IOP_CALL, fp, nil);
+ o.n = count;
iraddop(ic, o);
// Link the return path
@@ -266,7 +363,7 @@ func ircall(ic: *ircomp, n: *node): *irop {
return ret;
}
-func expr_to_ir(ic: *ircomp, n: *node): *irop {
+func expr_to_ir(ic: *irfunc, n: *node): *irop {
var a: *irop;
var b: *irop;
var c: *irop;
@@ -558,7 +655,7 @@ func expr_to_ir(ic: *ircomp, n: *node): *irop {
}
}
-func iraddop(ic: *ircomp, o: *irop) {
+func iraddop(ic: *irfunc, o: *irop) {
var cur: *irblock;
var ops: **irop;
var i: int;
@@ -594,7 +691,7 @@ func iraddop(ic: *ircomp, o: *irop) {
cur.ops_len = cur.ops_len + 1;
}
-func irjump(ic: *ircomp, to: *irblock, next: *irblock) {
+func irjump(ic: *irfunc, to: *irblock, next: *irblock) {
var cur: *irblock;
var o: *irop;
@@ -614,7 +711,7 @@ func irjump(ic: *ircomp, to: *irblock, next: *irblock) {
ic.cur = next;
}
-func irbranch(ic: *ircomp, cond: *irop, alt: *irblock, next: *irblock) {
+func irbranch(ic: *irfunc, cond: *irop, alt: *irblock, next: *irblock) {
var cur: *irblock;
var o: *irop;
@@ -635,7 +732,7 @@ func irbranch(ic: *ircomp, cond: *irop, alt: *irblock, next: *irblock) {
ic.cur = next;
}
-func irreturn(ic: *ircomp, value: *irop) {
+func irreturn(ic: *irfunc, value: *irop) {
var cur: *irblock;
var o: *irop;
@@ -654,7 +751,7 @@ func irreturn(ic: *ircomp, value: *irop) {
ic.cur = nil;
}
-func stmt_to_ir(ic: *ircomp, n: *node) {
+func stmt_to_ir(ic: *irfunc, n: *node) {
var loopctx: irloopctx;
var cond_body: *irblock;
var cond_next: *irblock;
@@ -772,12 +869,12 @@ func stmt_to_ir(ic: *ircomp, n: *node) {
}
}
-func irfind_block(ic: *ircomp, name: *byte, make: int): *irblock {
+func irfind_block(ic: *irfunc, name: *byte, make: int): *irblock {
var link: **irlabel;
var l: *irlabel;
var dir: int;
- link = &ic.labels;
+ link = &ic.labels_tree;
loop {
l = *link;
@@ -816,7 +913,7 @@ func irfind_block(ic: *ircomp, name: *byte, make: int): *irblock {
return l.block;
}
-func labels_to_ir(ic: *ircomp, n: *node) {
+func labels_to_ir(ic: *irfunc, n: *node) {
var kind: int;
var name: *byte;
@@ -857,7 +954,7 @@ func labels_to_ir(ic: *ircomp, n: *node) {
}
}
-func args_to_ir(ic: *ircomp, n: *node) {
+func args_to_ir(ic: *irfunc, n: *node) {
var name: *byte;
var t: *type;
@@ -876,7 +973,7 @@ func args_to_ir(ic: *ircomp, n: *node) {
}
}
-func locals_to_ir(ic: *ircomp, n: *node) {
+func locals_to_ir(ic: *irfunc, n: *node) {
var name: *byte;
var t: *type;
var kind: int;
@@ -921,39 +1018,40 @@ func locals_to_ir(ic: *ircomp, n: *node) {
}
}
-func func_to_ir(c: *compiler, n: *node) {
- var ic: ircomp;
+func func_to_ir(c: *compiler, n: *node): *irfunc {
+ var ic: *irfunc;
var value: *irop;
var t: *type;
if !n {
- return;
+ return nil;
}
+ ic = alloc(c.a, sizeof(*ic)) as *irfunc;
+
ic.c = c;
ic.a = c.a;
- ic.top = mkirblock(&ic);
+ ic.top = mkirblock(ic);
ic.cur = ic.top;
- args_to_ir(&ic, n.a.b.a);
+ ic.name = n.a.a.s;
+
+ args_to_ir(ic, n.a.b.a);
- locals_to_ir(&ic, n.b);
+ locals_to_ir(ic, n.b);
- labels_to_ir(&ic, n.b);
+ labels_to_ir(ic, n.b);
- stmt_to_ir(&ic, n.b);
+ stmt_to_ir(ic, n.b);
t = prototype(c, n.a.b);
if t.val.kind == TY_VOID {
- value = mkirconst(&ic, 0);
- irreturn(&ic, value);
+ value = mkirconst(ic, 0);
+ irreturn(ic, value);
}
- //fputs(nil, "\n");
- //fputs(nil, n.a.a.s);
- //fputs(nil, "\n");
- //irshow(nil, ic.top);
+ return ic;
}
// Depth-first reset all the marks
@@ -1005,16 +1103,20 @@ func irshow4(out: *file, o: *irop) {
fputs(out, " ");
irshow4(out, o.b);
fputs(out, ")");
+ } else if kind == IOP_REF {
+ fputs(out, "(ref ");
+ irshow4(out, o.a);
+ fputs(out, ")");
+ } else if kind == IOP_RETVAL {
+ fputs(out, "(retval ");
+ irshow4(out, o.a);
+ fputs(out, ")");
} else if kind == IOP_ARG {
fputs(out, "(arg ");
fputd(out, o.n);
fputs(out, " ");
irshow4(out, o.a);
fputs(out, ")");
- } else if kind == IOP_REF {
- fputs(out, "(ref ");
- irshow4(out, o.a);
- fputs(out, ")");
} else if kind == IOP_NEG {
fputs(out, "(neg ");
irshow4(out, o.a);
@@ -1122,8 +1224,6 @@ func irshow4(out: *file, o: *irop) {
} else if kind == IOP_CALL {
fputs(out, "(call ");
irshow4(out, o.a);
- fputs(out, " ");
- irshow4(out, o.b);
fputs(out, ")");
} else if kind == IOP_JUMP {
fputs(out, "(jump)");
@@ -1193,23 +1293,23 @@ func irshow(out: *file, b: *irblock) {
irreset(b);
}
-// value numbering
-// flow control graph simplification
-// loop detection
-
+// line numbers
+// evaluator
+// instruction selection
+// register allocation
+// assemble from ir
// inline
// intrinsics
-
// common subexpression
// constant folding
+// flow control graph simplification
// dead code
-// unrolling
-// strength reduction
-
-// register allocation
-// instruction selection
-
// c generator from ir
-// assemble from ir
-// proof check from ir
// type check with ir
+// parse to ir
+// value numbering
+// loop detection
+// unrolling
+// strength reduction / algebra
+// loop motion / fusion
+// proof check from ir