os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit c497784654927b8bdc2c893ccef54332f6600a4f
parent ff1a009f88d2eff66c17da40a34ad8773f4e507d
Author: erai <erai@omiltem.net>
Date:   Sun,  2 Feb 2025 17:45:24 +0000

basic identities in folding

Diffstat:
Mcc0.c | 482+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Mir.om | 326+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
2 files changed, 599 insertions(+), 209 deletions(-)

diff --git a/cc0.c b/cc0.c @@ -773,12 +773,16 @@ void( my_irblock_dead_expr)(struct my_irfunc* my_ic,struct my_irblock* my_b); void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b); 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_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct my_irop* my_o); +struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irop* my_o); 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); void( my_irjump)(struct my_irfunc* my_ic,struct my_irblock* my_to,struct my_irblock* my_next); void( my_irreset)(struct my_irblock* my_b); void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value); +void( my_irshow)(struct my_file* my_out,struct my_irblock* my_b); +void( my_irshow2)(struct my_file* my_out,struct my_irblock* my_b,unsigned long* my_id); +void( my_irshow3)(struct my_file* my_out,struct my_irblock* my_b); +void( my_irshow4)(struct my_file* my_out,struct my_irop* my_o); 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); @@ -794,6 +798,7 @@ void( my_memcpy)(unsigned char* my_dest,unsigned char* my_src,unsigned long my_s void( my_memset)(unsigned char* my_dest,unsigned long my_c,unsigned long my_size); 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_mkirfold)(struct my_irfunc* my_ic,struct my_irop* my_s,unsigned long my_n); struct my_irop*( my_mkirfunc)(struct my_irfunc* my_ic,unsigned char* my_name); 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,unsigned long my_slen); @@ -3866,8 +3871,7 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){ } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_ASSIGN)))) { (my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a))); (my_b)=((my_expr_to_ir)((my_ic),((my_n)->my_b))); - (my_d)=((my_mkirop)((my_ic),(my_IOP_REF),(my_a),((void *)0))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_d),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); ((my_o)->my_t)=((my_n)->my_t); return my_o; } else if ((unsigned long)(((long)(my_kind))==((long)(my_N_POS)))) { @@ -3891,15 +3895,13 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){ (my_e)=((my_mkirtmp)((my_ic),((my_n)->my_t))); (my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a))); (my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(0UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_next)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(1UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_out)); @@ -3912,24 +3914,21 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){ (my_e)=((my_mkirtmp)((my_ic),((my_n)->my_t))); (my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_a))); (my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(1UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_next)); (my_bool_next)=((my_mkirblock)((my_ic))); (my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_b))); (my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_final)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(1UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_next)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(0UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_out)); @@ -3944,15 +3943,13 @@ struct my_irop*( my_expr_to_ir)(struct my_irfunc* my_ic,struct my_node* my_n){ (my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_body)); (my_a)=((my_expr_to_ir)((my_ic),((my_n)->my_b))); (my_irbranch)((my_ic),(my_a),(my_bool_next),(my_bool_final)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(1UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_next)); - (my_a)=((my_mkirop)((my_ic),(my_IOP_REF),(my_e),((void *)0))); (my_b)=((my_mkirconst)((my_ic),(0UL))); - (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_a),(my_b))); + (my_o)=((my_mkirop)((my_ic),(my_IOP_STORE),(my_e),(my_b))); ((my_o)->my_t)=((my_n)->my_t); (my_iraddop)((my_ic),(my_o)); (my_irjump)((my_ic),(my_bool_out),(my_bool_out)); @@ -4524,6 +4521,9 @@ void( my_ir_optimize)(struct my_irfunc* my_ic){ (my_irblock_fold)((my_ic),(((my_ic)->my_blocks)[my_i])); (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); } + if ((unsigned long)(((long)((my_strcmp)(((my_ic)->my_name),((unsigned char *)"reconstruct_dec"))))==((long)(0UL)))) { + (my_irshow)(((void *)0),(((my_ic)->my_blocks)[0UL])); + } } void( my_iraddarg)(struct my_irfunc* my_ic,unsigned char* my_name,struct my_type* my_t){ struct my_irvar** my_iv = 0; @@ -4595,6 +4595,7 @@ void( my_irblock_dead_expr)(struct my_irfunc* my_ic,struct my_irblock* my_b){ void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b){ unsigned long my_i = 0; struct my_irop* my_o = 0; + struct my_irop* my_ret = 0; if ((unsigned long)(!((my_b)->my_done))) { return; } @@ -4603,10 +4604,23 @@ void( my_irblock_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b){ if ((unsigned long)(((long)(my_i))==((long)((my_b)->my_ops_len)))) { break; } - (my_o)=((my_irexpr_fold)((my_ic),(my_b),(((my_b)->my_ops)[my_i]))); + (my_o)=((my_irexpr_fold)((my_ic),(((my_b)->my_ops)[my_i]))); (((my_b)->my_ops)[my_i])=(my_o); (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); } + (my_i)=((unsigned long)(((unsigned long)(my_i))-((unsigned long)(1UL)))); + (my_o)=(((my_b)->my_ops)[my_i]); + if ((unsigned long)(((unsigned long)(((long)((my_o)->my_kind))==((long)(my_IOP_BRANCH))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_CONST)))))) { + (my_ret)=((my_mkirop)((my_ic),(my_IOP_JUMP),((void *)0),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + (((my_b)->my_ops)[my_i])=(my_ret); + if ((unsigned long)(!((my_o)->my_n))) { + ((my_b)->my_out)=((my_b)->my_alt); + } + ((my_b)->my_alt)=((void *)0); + } } 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; @@ -4653,8 +4667,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){ } (my_fp)=((my_mkirtmp)((my_ic),(((my_n)->my_a)->my_t))); (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_mkirop)((my_ic),(my_IOP_STORE),(my_fp),(my_b))); ((my_o)->my_t)=(((my_n)->my_a)->my_t); (my_iraddop)((my_ic),(my_o)); (my_arg)=((my_n)->my_b); @@ -4675,8 +4688,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){ } ((my_tmp)[my_i])=((my_mkirtmp)((my_ic),(((my_arg)->my_a)->my_t))); (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_mkirop)((my_ic),(my_IOP_STORE),((my_tmp)[my_i]),(my_b))); ((my_o)->my_t)=(((my_arg)->my_a)->my_t); (my_iraddop)((my_ic),(my_o)); (my_arg)=((my_arg)->my_b); @@ -4697,8 +4709,7 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){ } (my_free)(((my_ic)->my_a),((unsigned char*)my_tmp)); (my_ret)=((my_mkirtmp)((my_ic),((my_n)->my_t))); - (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_mkirop)((my_ic),(my_IOP_RETVAL),(my_ret),((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))); @@ -4716,107 +4727,159 @@ struct my_irop*( my_ircall)(struct my_irfunc* my_ic,struct my_node* my_n){ ((my_ic)->my_cur)=(my_next); return my_ret; } -struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct my_irop* my_o){ +struct my_irop*( my_irexpr_fold)(struct my_irfunc* my_ic,struct my_irop* my_o){ + struct my_irop* my_a = 0; + struct my_irop* my_b = 0; + struct my_irop* my_c = 0; + unsigned long my_n = 0; unsigned long my_kind = 0; - (my_kind)=((my_o)->my_kind); + struct my_irop* my_ret = 0; if ((my_o)->my_a) { - ((my_o)->my_a)=((my_irexpr_fold)((my_ic),(my_b),((my_o)->my_a))); + (my_a)=((my_irexpr_fold)((my_ic),((my_o)->my_a))); } else { return my_o; } if ((my_o)->my_b) { - ((my_o)->my_b)=((my_irexpr_fold)((my_ic),(my_b),((my_o)->my_b))); + (my_b)=((my_irexpr_fold)((my_ic),((my_o)->my_b))); } - if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_LOAD)))))) { - ((((my_o)->my_a)->my_a)->my_t)=((my_o)->my_t); - return ((my_o)->my_a)->my_a; + (my_kind)=((my_o)->my_kind); + if ((unsigned long)(((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF))))&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_LOAD))))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD))))&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_REF)))))))) { + (my_ret)=((my_mkirop)((my_ic),(((my_a)->my_a)->my_kind),(((my_a)->my_a)->my_a),(((my_a)->my_a)->my_b))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + ((my_ret)->my_t)=((my_o)->my_t); + ((my_ret)->my_n)=(((my_a)->my_a)->my_n); + return my_ret; } - if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD))))&&((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_REF)))))) { - ((((my_o)->my_a)->my_a)->my_t)=((my_o)->my_t); - return ((my_o)->my_a)->my_a; - } - if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))!=((long)(my_IOP_CONST)))) { - return my_o; + if ((unsigned long)(((long)((my_a)->my_kind))!=((long)(my_IOP_CONST)))) { + goto my_out; } if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NEG)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(-(unsigned long)(((my_o)->my_a)->my_n))); - return (my_o)->my_a; + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(-(unsigned long)((my_a)->my_n)))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(~(unsigned long)((my_a)->my_n)))); } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(~(unsigned long)(((my_o)->my_a)->my_n))); - return (my_o)->my_a; + if ((unsigned long)(((unsigned long)(!(my_b)))||((unsigned long)(((long)((my_b)->my_kind))!=((long)(my_IOP_CONST)))))) { + goto my_out; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_BRANCH)))) { - if ((unsigned long)(!(((my_o)->my_a)->my_n))) { - ((my_b)->my_out)=((my_b)->my_alt); + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))+((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))|((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))^((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))/((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))%((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))<<((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))>>((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))*((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((unsigned long)((my_a)->my_n))-((unsigned long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))==((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))!=((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))>((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))>=((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))<((long)((my_b)->my_n))))); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) { + return (my_mkirfold)((my_ic),(my_o),((unsigned long)(((long)((my_a)->my_n))<=((long)((my_b)->my_n))))); + } else { + goto my_out; } - ((my_o)->my_kind)=(my_IOP_JUMP); - return my_o; +my_out: + if ((unsigned long)((my_a)&&((unsigned long)(((long)((my_a)->my_kind))==((long)(my_IOP_CONST)))))) { + (my_n)=((my_a)->my_n); + if ((unsigned long)(((long)(my_n))==((long)(0UL)))) { + if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))))))) { + return my_b; } - if ((unsigned long)(((unsigned long)(!((my_o)->my_b)))||((unsigned long)(((long)(((my_o)->my_b)->my_kind))!=((long)(my_IOP_CONST)))))) { - return my_o; + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) { + (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_b),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + return my_ret; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))+((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))))))))) { + return (my_mkirfold)((my_ic),(my_o),(0UL)); } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))|((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + } else if ((unsigned long)(((long)(my_n))==((long)(1UL)))) { + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { + return my_b; + } + } else if ((unsigned long)(((long)(my_n))==((long)((unsigned long)(-(unsigned long)(1UL)))))) { + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { + (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_b),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + return my_ret; } if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))^((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + (my_ret)=((my_mkirop)((my_ic),(my_IOP_NOT),(my_b),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + return my_ret; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))/((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) { + return my_b; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))%((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))<<((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))>>((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)((my_b)&&((unsigned long)(((long)((my_b)->my_kind))==((long)(my_IOP_CONST)))))) { + (my_n)=((my_b)->my_n); + if ((unsigned long)(((long)(my_n))==((long)(0UL)))) { + if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB))))||((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))))))))))))) { + return my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))*((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))))) { + return (my_mkirfold)((my_ic),(my_o),(0UL)); } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((unsigned long)(((my_o)->my_a)->my_n))-((unsigned long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; - } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))==((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + } else if ((unsigned long)(((long)(my_n))==((long)(1UL)))) { + if ((unsigned long)(((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV))))||((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))))) { + return my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))!=((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + } else if ((unsigned long)(((long)(my_n))==((long)((unsigned long)(-(unsigned long)(1UL)))))) { + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { + (my_ret)=((my_mkirop)((my_ic),(my_IOP_NEG),(my_a),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + return my_ret; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))>((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) { + (my_ret)=((my_mkirop)((my_ic),(my_IOP_NOT),(my_a),((void *)0))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + return my_ret; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))>=((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) { + return my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))<((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; } - if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) { - (((my_o)->my_a)->my_n)=((unsigned long)(((long)(((my_o)->my_a)->my_n))<=((long)(((my_o)->my_b)->my_n)))); - return (my_o)->my_a; } + if ((unsigned long)(((unsigned long)(((long)((my_o)->my_a))==((long)(my_a))))&&((unsigned long)(((long)((my_o)->my_b))==((long)(my_b)))))) { return my_o; + } + (my_ret)=((my_mkirop)((my_ic),(my_kind),(my_a),(my_b))); + ((my_ret)->my_filename)=((my_o)->my_filename); + ((my_ret)->my_lineno)=((my_o)->my_lineno); + ((my_ret)->my_colno)=((my_o)->my_colno); + ((my_ret)->my_t)=((my_o)->my_t); + ((my_ret)->my_n)=((my_o)->my_n); + return my_ret; } 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; @@ -4911,6 +4974,212 @@ void( my_irreturn)(struct my_irfunc* my_ic,struct my_irop* my_value){ } ((my_ic)->my_cur)=((void *)0); } +void( my_irshow)(struct my_file* my_out,struct my_irblock* my_b){ + unsigned long my_id = 0; + (my_id)=(1UL); + (my_irshow2)((my_out),(my_b),(&(my_id))); + (my_irreset)((my_b)); +} +void( my_irshow2)(struct my_file* my_out,struct my_irblock* my_b,unsigned long* my_id){ + if ((unsigned long)(!(my_b))) { + return; + } + if ((my_b)->my_mark) { + return; + } + ((my_b)->my_mark)=(*(my_id)); + (*(my_id))=((unsigned long)(((unsigned long)(*(my_id)))+((unsigned long)(1UL)))); + (my_irshow3)((my_out),(my_b)); + if ((my_b)->my_out) { + (my_irshow2)((my_out),((my_b)->my_out),(my_id)); + } + if ((my_b)->my_alt) { + (my_irshow2)((my_out),((my_b)->my_alt),(my_id)); + } +} +void( my_irshow3)(struct my_file* my_out,struct my_irblock* my_b){ + unsigned long my_i = 0; + (my_fputd)((my_out),((my_b)->my_mark)); + (my_fputs)((my_out),((unsigned char *)"{\012")); + (my_i)=(0UL); + while (1) { + if ((unsigned long)(((long)(my_i))==((long)((my_b)->my_ops_len)))) { + break; + } + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),(((my_b)->my_ops)[my_i])); + (my_fputs)((my_out),((unsigned char *)"\012")); + (my_i)=((unsigned long)(((unsigned long)(my_i))+((unsigned long)(1UL)))); + } + (my_fputs)((my_out),((unsigned char *)"}\012")); +} +void( my_irshow4)(struct my_file* my_out,struct my_irop* my_o){ + unsigned long my_kind = 0; + if ((unsigned long)(!(my_o))) { + (my_fputs)((my_out),((unsigned char *)"(nil)")); + return; + } + (my_kind)=((my_o)->my_kind); + if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_VAR)))) { + (my_fputs)((my_out),((unsigned char *)"(var ")); + (my_fputd)((my_out),((my_o)->my_n)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_FUNC)))) { + (my_fputs)((my_out),((unsigned char *)"(func ")); + (my_fputs)((my_out),((my_o)->my_s)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_CONST)))) { + (my_fputs)((my_out),((unsigned char *)"(const ")); + (my_fputd)((my_out),((my_o)->my_n)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STR)))) { + (my_fputs)((my_out),((unsigned char *)"(str)")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LOAD)))) { + (my_fputs)((my_out),((unsigned char *)"(load ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STORE)))) { + (my_fputs)((my_out),((unsigned char *)"(store ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_REF)))) { + (my_fputs)((my_out),((unsigned char *)"(ref ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RETVAL)))) { + (my_fputs)((my_out),((unsigned char *)"(retval ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ARG)))) { + (my_fputs)((my_out),((unsigned char *)"(arg ")); + (my_fputd)((my_out),((my_o)->my_n)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NEG)))) { + (my_fputs)((my_out),((unsigned char *)"(neg ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NOT)))) { + (my_fputs)((my_out),((unsigned char *)"(not ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_ADD)))) { + (my_fputs)((my_out),((unsigned char *)"(add ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_AND)))) { + (my_fputs)((my_out),((unsigned char *)"(and ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_OR)))) { + (my_fputs)((my_out),((unsigned char *)"(or ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_XOR)))) { + (my_fputs)((my_out),((unsigned char *)"(xor ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_DIV)))) { + (my_fputs)((my_out),((unsigned char *)"(div ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MOD)))) { + (my_fputs)((my_out),((unsigned char *)"(mod ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LSH)))) { + (my_fputs)((my_out),((unsigned char *)"(lsh ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RSH)))) { + (my_fputs)((my_out),((unsigned char *)"(rsh ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_MUL)))) { + (my_fputs)((my_out),((unsigned char *)"(mul ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_SUB)))) { + (my_fputs)((my_out),((unsigned char *)"(sub ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_EQ)))) { + (my_fputs)((my_out),((unsigned char *)"(eq ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_NE)))) { + (my_fputs)((my_out),((unsigned char *)"(ne ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GT)))) { + (my_fputs)((my_out),((unsigned char *)"(gt ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_GE)))) { + (my_fputs)((my_out),((unsigned char *)"(ge ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LT)))) { + (my_fputs)((my_out),((unsigned char *)"(lt ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_LE)))) { + (my_fputs)((my_out),((unsigned char *)"(le ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)" ")); + (my_irshow4)((my_out),((my_o)->my_b)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_CALL)))) { + (my_fputs)((my_out),((unsigned char *)"(call ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_JUMP)))) { + (my_fputs)((my_out),((unsigned char *)"(jump)")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_BRANCH)))) { + (my_fputs)((my_out),((unsigned char *)"(branch ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_RETURN)))) { + (my_fputs)((my_out),((unsigned char *)"(return ")); + (my_irshow4)((my_out),((my_o)->my_a)); + (my_fputs)((my_out),((unsigned char *)")")); + } else { + (my_die)(((unsigned char *)"invalid iop")); + } +} 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; @@ -5428,6 +5697,15 @@ struct my_irop*( my_mkirconst)(struct my_irfunc* my_ic,unsigned long my_n){ ((my_o)->my_n)=(my_n); return my_o; } +struct my_irop*( my_mkirfold)(struct my_irfunc* my_ic,struct my_irop* my_s,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_filename)=((my_s)->my_filename); + ((my_o)->my_lineno)=((my_s)->my_lineno); + ((my_o)->my_colno)=((my_s)->my_colno); + ((my_o)->my_n)=(my_n); + return my_o; +} struct my_irop*( my_mkirfunc)(struct my_irfunc* my_ic,unsigned char* my_name){ struct my_irop* my_o = 0; (my_o)=((my_mkirop)((my_ic),(my_IOP_FUNC),((void *)0),((void *)0))); @@ -6065,7 +6343,13 @@ void( my_output_irretval)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct return; } (my_as_modrr)(((my_ic)->my_s),(my_OP_MOVE),(my_R_RDI),(my_R_RAX)); - (my_output_irexpr)((my_ic),(my_b),((my_op)->my_a)); + if ((unsigned long)(((long)(((my_op)->my_a)->my_kind))==((long)(my_IOP_LOAD)))) { + (my_output_irexpr)((my_ic),(my_b),(((my_op)->my_a)->my_a)); + } else if ((unsigned long)(((long)(((my_op)->my_a)->my_kind))==((long)(my_IOP_VAR)))) { + (my_as_modrm)(((my_ic)->my_s),(my_OP_LEA),(my_R_RAX),(my_R_RBP),(0UL),(0UL),((((my_ic)->my_vars)[((my_op)->my_a)->my_n])->my_offset)); + } else { + (my_die)(((unsigned char *)"invalid store")); + } if ((unsigned long)(((long)(((my_op)->my_t)->my_kind))==((long)(my_TY_BYTE)))) { (my_as_modrm)(((my_ic)->my_s),(my_OP_STOREB),(my_R_RDI),(my_R_RAX),(0UL),(0UL),(0UL)); } else if ((my_type_isprim)(((my_op)->my_t))) { @@ -6083,7 +6367,13 @@ void( my_output_irstmt)(struct my_irfunc* my_ic,struct my_irblock* my_b,struct m (((my_ic)->my_s)->my_lineno)=((my_o)->my_lineno); (my_kind)=((my_o)->my_kind); if ((unsigned long)(((long)(my_kind))==((long)(my_IOP_STORE)))) { - (my_output_irexpr)((my_ic),(my_b),((my_o)->my_a)); + if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_LOAD)))) { + (my_output_irexpr)((my_ic),(my_b),(((my_o)->my_a)->my_a)); + } else if ((unsigned long)(((long)(((my_o)->my_a)->my_kind))==((long)(my_IOP_VAR)))) { + (my_as_modrm)(((my_ic)->my_s),(my_OP_LEA),(my_R_RAX),(my_R_RBP),(0UL),(0UL),((((my_ic)->my_vars)[((my_o)->my_a)->my_n])->my_offset)); + } else { + (my_die)(((unsigned char *)"invalid store")); + } (my_as_opr)(((my_ic)->my_s),(my_OP_PUSHR),(my_R_RAX)); (my_output_irexpr)((my_ic),(my_b),((my_o)->my_b)); (my_as_opr)(((my_ic)->my_s),(my_OP_POPR),(my_R_RDI)); diff --git a/ir.om b/ir.om @@ -335,8 +335,7 @@ func ircall(ic: *irfunc, n: *node): *irop { // Evaluate the expression left to right starting with the function fp = mkirtmp(ic, n.a.t); b = expr_to_ir(ic, n.a); - a = mkirop(ic, IOP_REF, fp, nil); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, fp, b); o.t = n.a.t; iraddop(ic, o); @@ -370,8 +369,7 @@ func ircall(ic: *irfunc, n: *node): *irop { 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 = mkirop(ic, IOP_STORE, tmp[i], b); o.t = arg.a.t; iraddop(ic, o); @@ -400,8 +398,7 @@ func ircall(ic: *irfunc, n: *node): *irop { // Add a temporary for the return value ret = mkirtmp(ic, n.t); - b = mkirop(ic, IOP_REF, ret, nil); - o = mkirop(ic, IOP_RETVAL, b, nil); + o = mkirop(ic, IOP_RETVAL, ret, nil); o.t = n.t; iraddop(ic, o); @@ -541,8 +538,7 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop { } else if kind == N_ASSIGN { a = expr_to_ir(ic, n.a); b = expr_to_ir(ic, n.b); - d = mkirop(ic, IOP_REF, a, nil); - o = mkirop(ic, IOP_STORE, d, b); + o = mkirop(ic, IOP_STORE, a, b); o.t = n.t; return o; } else if kind == N_POS { @@ -568,16 +564,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop { a = expr_to_ir(ic, n.a); irbranch(ic, a, bool_next, bool_body); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 0); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_next); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 1); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_out); @@ -593,9 +587,8 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop { a = expr_to_ir(ic, n.a); irbranch(ic, a, bool_next, bool_body); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 1); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_next); @@ -605,16 +598,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop { a = expr_to_ir(ic, n.b); irbranch(ic, a, bool_next, bool_final); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 1); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_next); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 0); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_out); @@ -633,16 +624,14 @@ func expr_to_ir(ic: *irfunc, n: *node): *irop { a = expr_to_ir(ic, n.b); irbranch(ic, a, bool_next, bool_final); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 1); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_next); - a = mkirop(ic, IOP_REF, e, nil); b = mkirconst(ic, 0); - o = mkirop(ic, IOP_STORE, a, b); + o = mkirop(ic, IOP_STORE, e, b); o.t = n.t; iraddop(ic, o); irjump(ic, bool_out, bool_out); @@ -1719,7 +1708,14 @@ func output_irstmt(ic: *irfunc, b: *irblock, o: *irop) { kind = o.kind; if kind == IOP_STORE { // Evaluate the address - output_irexpr(ic, b, o.a); + if o.a.kind == IOP_LOAD { + output_irexpr(ic, b, o.a.a); + } else if o.a.kind == IOP_VAR { + as_modrm(ic.s, OP_LEA, R_RAX, R_RBP, 0, 0, ic.vars[o.a.n].offset); + } else { + die("invalid store"); + } + as_opr(ic.s, OP_PUSHR, R_RAX); // Evaluate the value @@ -1875,7 +1871,13 @@ func output_irretval(ic: *irfunc, b: *irblock, o: *irop) { as_modrr(ic.s, OP_MOVE, R_RDI, R_RAX); // Compute the address - output_irexpr(ic, b, op.a); + if op.a.kind == IOP_LOAD { + output_irexpr(ic, b, op.a.a); + } else if op.a.kind == IOP_VAR { + as_modrm(ic.s, OP_LEA, R_RAX, R_RBP, 0, 0, ic.vars[op.a.n].offset); + } else { + die("invalid store"); + } // Execute the store if op.t.kind == TY_BYTE { @@ -2123,139 +2125,217 @@ func irblock_dead_expr(ic: *irfunc, b: *irblock) { b.ops_len = j; } -func irexpr_fold(ic: *irfunc, b: *irblock, o: *irop): *irop { - var kind: int; +func mkirfold(ic: *irfunc, s: *irop, n: int): *irop { + var o: *irop; - kind = o.kind; + o = mkirop(ic, IOP_CONST, nil, nil); + + o.filename = s.filename; + o.lineno = s.lineno; + o.colno = s.colno; + o.n = n; + + return o; +} + +func irexpr_fold(ic: *irfunc, o: *irop): *irop { + var a: *irop; + var b: *irop; + var c: *irop; + var n: int; + var kind: int; + var ret: *irop; + // Recursive fold the first operand if o.a { - o.a = irexpr_fold(ic, b, o.a); + a = irexpr_fold(ic, o.a); } else { + // If the op has zero operands, there's nothing to do. return o; } + // Recursive fold the second operand if o.b { - o.b = irexpr_fold(ic, b, o.b); + b = irexpr_fold(ic, o.b); } - if kind == IOP_REF && o.a.kind == IOP_LOAD { - o.a.a.t = o.t; - return o.a.a; - } + kind = o.kind; - if kind == IOP_LOAD && o.a.kind == IOP_REF { - o.a.a.t = o.t; - return o.a.a; + // Eliminate *& and &* redundant operations + if (kind == IOP_REF && a.kind == IOP_LOAD) || (kind == IOP_LOAD && a.kind == IOP_REF) { + // This could be a type pun, so make a new op with a new type + ret = mkirop(ic, a.a.kind, a.a.a, a.a.b); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + ret.t = o.t; + ret.n = a.a.n; + return ret; } - if o.a.kind != IOP_CONST { - return o; + // Check if a is a constant + if a.kind != IOP_CONST { + goto out; } + // Simplify unary operations if kind == IOP_NEG { - o.a.n = -o.a.n; - return o.a; - } - - if kind == IOP_NOT { - o.a.n = ~o.a.n; - return o.a; - } - - if kind == IOP_BRANCH { - if !o.a.n { - b.out = b.alt; - } - o.kind = IOP_JUMP; - return o; + return mkirfold(ic, o, -a.n); + } else if kind == IOP_NOT { + return mkirfold(ic, o, ~a.n); } - if !o.b || o.b.kind != IOP_CONST { - return o; + // Check if b is a constant + if !b || b.kind != IOP_CONST { + goto out; } + // Simplify binary operations if kind == IOP_ADD { - o.a.n = o.a.n + o.b.n; - return o.a; - } - - if kind == IOP_OR { - o.a.n = o.a.n | o.b.n; - return o.a; + return mkirfold(ic, o, a.n + b.n); + } else if kind == IOP_OR { + return mkirfold(ic, o, a.n | b.n); + } else if kind == IOP_XOR { + return mkirfold(ic, o, a.n ^ b.n); + } else if kind == IOP_DIV { + return mkirfold(ic, o, a.n / b.n); + } else if kind == IOP_MOD { + return mkirfold(ic, o, a.n % b.n); + } else if kind == IOP_LSH { + return mkirfold(ic, o, a.n << b.n); + } else if kind == IOP_RSH { + return mkirfold(ic, o, a.n >> b.n); + } else if kind == IOP_MUL { + return mkirfold(ic, o, a.n * b.n); + } else if kind == IOP_SUB { + return mkirfold(ic, o, a.n - b.n); + } else if kind == IOP_EQ { + return mkirfold(ic, o, a.n == b.n); + } else if kind == IOP_NE { + return mkirfold(ic, o, a.n != b.n); + } else if kind == IOP_GT { + return mkirfold(ic, o, a.n > b.n); + } else if kind == IOP_GE { + return mkirfold(ic, o, a.n >= b.n); + } else if kind == IOP_LT { + return mkirfold(ic, o, a.n < b.n); + } else if kind == IOP_LE { + return mkirfold(ic, o, a.n <= b.n); + } else { + goto out; } - if kind == IOP_XOR { - o.a.n = o.a.n ^ o.b.n; - return o.a; - } +out: - if kind == IOP_DIV { - o.a.n = o.a.n / o.b.n; - return o.a; - } + // Do some simple algebraic identities on a + if a && a.kind == IOP_CONST { + n = a.n; - if kind == IOP_MOD { - o.a.n = o.a.n % o.b.n; - return o.a; - } + if n == 0 { + if kind == IOP_ADD || kind == IOP_OR || kind == IOP_XOR { + return b; + } - if kind == IOP_LSH { - o.a.n = o.a.n << o.b.n; - return o.a; - } + if kind == IOP_SUB { + ret = mkirop(ic, IOP_NEG, b, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + return ret; + } - if kind == IOP_RSH { - o.a.n = o.a.n >> o.b.n; - return o.a; - } + if kind == IOP_AND || kind == IOP_MUL || kind == IOP_LSH || kind == IOP_RSH { + return mkirfold(ic, o, 0); + } + } else if n == 1 { + if kind == IOP_MUL { + return b; + } + } else if n == -1 { + if kind == IOP_MUL { + ret = mkirop(ic, IOP_NEG, b, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + return ret; + } - if kind == IOP_MUL { - o.a.n = o.a.n * o.b.n; - return o.a; - } + if kind == IOP_XOR { + ret = mkirop(ic, IOP_NOT, b, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + return ret; + } - if kind == IOP_SUB { - o.a.n = o.a.n - o.b.n; - return o.a; + if kind == IOP_AND { + return b; + } + } } - if kind == IOP_EQ { - o.a.n = o.a.n == o.b.n; - return o.a; - } + // Do some simple algebraic identities on b + if b && b.kind == IOP_CONST { + n = b.n; - if kind == IOP_NE { - o.a.n = o.a.n != o.b.n; - return o.a; - } + if n == 0 { + if ( + kind == IOP_ADD || kind == IOP_OR || kind == IOP_XOR + || kind == IOP_SUB || kind == IOP_LSH || kind == IOP_RSH + ) { + return a; + } - if kind == IOP_GT { - o.a.n = o.a.n > o.b.n; - return o.a; - } + if kind == IOP_AND || kind == IOP_MUL { + return mkirfold(ic, o, 0); + } + } else if n == 1 { + if kind == IOP_DIV || kind == IOP_MUL { + return a; + } + } else if n == -1 { + if kind == IOP_MUL { + ret = mkirop(ic, IOP_NEG, a, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + return ret; + } - if kind == IOP_GE { - o.a.n = o.a.n >= o.b.n; - return o.a; - } + if kind == IOP_XOR { + ret = mkirop(ic, IOP_NOT, a, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + return ret; + } - if kind == IOP_LT { - o.a.n = o.a.n < o.b.n; - return o.a; + if kind == IOP_AND { + return a; + } + } } - if kind == IOP_LE { - o.a.n = o.a.n <= o.b.n; - return o.a; + // If neither side folded, then just return the op unmodified + if o.a == a && o.b == b { + return o; } - return o; + // Otherwise, make a new one with the folded operands + ret = mkirop(ic, kind, a, b); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + ret.t = o.t; + ret.n = o.n; + return ret; } // Fold constant expressions func irblock_fold(ic: *irfunc, b: *irblock) { var i: int; var o: *irop; + var ret: *irop; if !b.done { return; @@ -2267,11 +2347,31 @@ func irblock_fold(ic: *irfunc, b: *irblock) { break; } - o = irexpr_fold(ic, b, b.ops[i]); + o = irexpr_fold(ic, b.ops[i]); b.ops[i] = o; i = i + 1; } + + i = i - 1; + + o = b.ops[i]; + + // Fold constant branches into jumps + if o.kind == IOP_BRANCH && o.a.kind == IOP_CONST { + ret = mkirop(ic, IOP_JUMP, nil, nil); + ret.filename = o.filename; + ret.lineno = o.lineno; + ret.colno = o.colno; + + b.ops[i] = ret; + + if !o.n { + b.out = b.alt; + } + + b.alt = nil; + } } func ir_optimize(ic: *irfunc) {