From 421da3d27b727d92a3ee945751458448425f1e6d Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 1 May 2019 14:45:18 +0200 Subject: [PATCH] Add specialized instructions eq{Cc,Ii}, jmp_{eq,ne}{Cc,Ii}, put_{a,b}_jmp, and push_b_decI These are frequent pairs of instructions in the Ligretto and Trax examples in iTasks. --- src/ABC/Instructions.dcl | 9 ++++++ src/ABC/Optimise.icl | 27 +++++++++++++--- src/abc_instructions.c | 9 ++++++ src/abc_instructions.h | 9 ++++++ src/bcgen_instruction_table.c | 9 ++++++ src/bcgen_instructions.c | 58 +++++++++++++++++++++++++++++++++++ src/bcgen_instructions.h | 9 ++++++ src/parse_abc.c | 24 +++++++++++++++ src/parse_abc.h | 2 ++ test/functions.32.expected | 2 +- test/functions.64.expected | 2 +- tools/interpretergen.icl | 24 +++++++++++++++ 12 files changed, 177 insertions(+), 7 deletions(-) diff --git a/src/ABC/Instructions.dcl b/src/ABC/Instructions.dcl index b6de1a0..eef1df6 100644 --- a/src/ABC/Instructions.dcl +++ b/src/ABC/Instructions.dcl @@ -62,23 +62,29 @@ from StdFile import class <<< | Idup2_a !Int | Idup3_a !Int | Idup_a !Int + | IeqCc !Char + | IeqIi !Int | Iexchange_a !Int !Int | Ifill_a01_pop_rtn | Ijmp_b_false !Int !String | Ijmp_eqACio !StringLiteral !Int !String | Ijmp_eqC_b !Char !Int !String | Ijmp_eqC_b2 !Char !Char !Int !String !String + | Ijmp_eqCc !Char !String | Ijmp_eqD_b !String !Int !String | Ijmp_eqD_b2 !String !Int !String !String !Int !String | Ijmp_eqI !String | Ijmp_eqI_b !Int !Int !String | Ijmp_eqI_b2 !Int !Int !Int !String !String + | Ijmp_eqIi !Int !String | Ijmp_eq_desc !String !Int !Int !String | Ijmp_geI !String | Ijmp_ltI !String | Ijmp_neC_b !Char !Int !String + | Ijmp_neCc !Char !String | Ijmp_neI !String | Ijmp_neI_b !Int !Int !String + | Ijmp_neIi !Int !String | Ijmp_ne_desc !String !Int !Int !String | Ijmp_o_geI !Int !String | Ijmp_o_geI_arraysize_a !String !Int !Int !String @@ -103,12 +109,15 @@ from StdFile import class <<< | Ipush_ab !Int !Int | Ipush_arraysize_a !String !Int !Int !Int | Ipush_b2 !Int !Int + | Ipush_b_decI !Int | Ipush_b_incI !Int | Ipush_b_jsr !Int !String | Ipush_jsr_eval !Int | Ipush_update_a !Int !Int | Iput_a !Int + | Iput_a_jmp !Int !String | Iput_b !Int + | Iput_b_jmp !Int !String | Irepl_arg !Int !Int | Iselectoo !String !Int !Int !Int !Int | Iswap_a !Int diff --git a/src/ABC/Optimise.icl b/src/ABC/Optimise.icl index 14f3df5..b3de331 100644 --- a/src/ABC/Optimise.icl +++ b/src/ABC/Optimise.icl @@ -115,10 +115,12 @@ opt_abc1 [IIns "notB",Ijmp_true id:is] = opt_abc1 [Ijmp_false id:is] opt_abc1 [IpushC c,Ipush_b 0,IIns "eqC":is] = opt_abc1 [IpushB True:is] opt_abc1 [IpushC c,Ipush_b n,IIns "eqC":is] = [IeqC_b c (n-1):opt_abc1 is] opt_abc1 [Ipush_b n,IpushC c,IIns "eqC":is] = [IeqC_b c n :opt_abc1 is] +opt_abc1 [IpushC c, IIns "eqC":is] = [IeqCc c :opt_abc1 is] opt_abc1 [IpushI c,Ipush_b 0,IIns "eqI":is] = opt_abc1 [IpushB True:is] opt_abc1 [IpushI c,Ipush_b n,IIns "eqI":is] = [IeqI_b c (n-1):opt_abc1 is] opt_abc1 [Ipush_b n,IpushI c,IIns "eqI":is] = [IeqI_b c n :opt_abc1 is] +opt_abc1 [IpushI c, IIns "eqI":is] = [IeqIi c :opt_abc1 is] opt_abc1 [Ipush_b 1,Iupdate_b 1 2,Iupdatepop_b 0 1,i:is] | isCommutativeBStackInstruction i = opt_abc1 [i:is] @@ -227,6 +229,11 @@ opt_abc_new [IeqC_b c n,Ijmp_false l:is] = [Ijmp_neC_b c n l:opt_abc_new is] opt_abc_new [IeqI_b i n,Ijmp_true l:is] = [Ijmp_eqI_b i n l:opt_abc_new is] opt_abc_new [IeqI_b i n,Ijmp_false l:is] = [Ijmp_neI_b i n l:opt_abc_new is] +opt_abc_new [IeqIi c,Ijmp_true l:is] = [Ijmp_eqIi c l:opt_abc_new is] +opt_abc_new [IeqIi c,Ijmp_false l:is] = [Ijmp_neIi c l:opt_abc_new is] +opt_abc_new [IeqCc c,Ijmp_true l:is] = [Ijmp_eqCc c l:opt_abc_new is] +opt_abc_new [IeqCc c,Ijmp_false l:is] = [Ijmp_neCc c l:opt_abc_new is] + opt_abc_new [Ipush_b n,IpushI i,IIns "and%":is] = [IandIio i n:opt_abc_new is] opt_abc_new [IpushI i,IIns "and%":is] = [IandIi i:opt_abc_new is] opt_abc_new [IpushI i,Ipush_b n,IIns "and%":is] | n > 0 = [IandIio i (n-1):opt_abc_new is] @@ -263,11 +270,20 @@ opt_abc_new2 [Iupdate_a 0 d0,Iupdate_a 0 d1,Iupdate_a 0 d2:is] opt_abc_new2 [Iupdate_a 0 d0,Iupdate_a 0 d1:is] | d0==d1+1 = [Idup2_a d1:opt_abc_new2 is] -opt_abc_new2 [Iupdate_a 0 d0,Ipop_a 1:is] = [Iput_a d0:opt_abc_new2 is] -opt_abc_new2 [Iupdate_a 0 d0:is] = [Idup_a d0:opt_abc_new2 is] -opt_abc_new2 [Iupdate_b 0 d0,Ipop_b 1:is] = [Iput_b d0:opt_abc_new2 is] -opt_abc_new2 [Iupdatepop_a 0 1:is] = [Iput_a 1:opt_abc_new2 is] -opt_abc_new2 [Iupdatepop_b 0 1:is] = [Iput_b 1:opt_abc_new2 is] +opt_abc_new2 [Iupdate_a 0 d0,Ipop_a 1:is] = case is of + [a=:(Annotation _),Ijmp l:is] -> [a,Iput_a_jmp d0 l:opt_abc_new2 is] + _ -> [ Iput_a d0 :opt_abc_new2 is] +opt_abc_new2 [Iupdate_b 0 d0,Ipop_b 1:is] = case is of + [a=:(Annotation _),Ijmp l:is] -> [a,Iput_b_jmp d0 l:opt_abc_new2 is] + _ -> [ Iput_b d0 :opt_abc_new2 is] +opt_abc_new2 [Iupdatepop_a 0 1:is] = case is of + [a=:(Annotation _),Ijmp l:is] -> [a,Iput_a_jmp 1 l:opt_abc_new2 is] + _ -> [ Iput_a 1 :opt_abc_new2 is] +opt_abc_new2 [Iupdatepop_b 0 1:is] = case is of + [a=:(Annotation _),Ijmp l:is] -> [a,Iput_b_jmp 1 l:opt_abc_new2 is] + _ -> [ Iput_b 1 :opt_abc_new2 is] +opt_abc_new2 [Iupdate_a 0 d0:is] = [Idup_a d0:opt_abc_new2 is] + opt_abc_new2 [Ipush_a d0,Ijsr_eval 0:is] = [Ipush_jsr_eval d0:opt_abc_new2 is] opt_abc_new2 [Ipush_a s0,Ipush_a s1:is] | s0==s1 && s0>0 = [Ipush2_a s0:opt_abc_new2 is] @@ -325,6 +341,7 @@ opt_abc_new2 [Ipush_b s0,Ipush_b s1:is] opt_abc_new2 [Ipush_b sb,Ipush_a sa,Iselect d i0 i1:is] = [Iselectoo d i0 i1 sa sb:opt_abc_new2 is] opt_abc_new2 [Ipush_b sb,Ipush_a sa:is] = [Ipush_ab sa sb:opt_abc_new2 is] opt_abc_new2 [Ipush_b n,Ijmp_false l:is] = [Ijmp_b_false n l:opt_abc_new2 is] +opt_abc_new2 [Ipush_b n,IIns "decI":is] = [Ipush_b_decI n:opt_abc_new2 is] opt_abc_new2 [Ipush_b n,IIns "incI":is] = [Ipush_b_incI n:opt_abc_new2 is] opt_abc_new2 [Ipush_b n,IIns "ltI",Ijmp_false l:is] = [Ijmp_o_geI n l:opt_abc_new2 is] opt_abc_new2 [Ipush_b n,annot=:Annotation (Ad _ _ _),Ijsr l:is] = [annot,Ipush_b_jsr n l:opt_abc_new2 is] diff --git a/src/abc_instructions.c b/src/abc_instructions.c index c18bb1a..c49893e 100644 --- a/src/abc_instructions.c +++ b/src/abc_instructions.c @@ -174,10 +174,12 @@ const char *instruction_type (BC_WORD i) { case CeqC: return ""; case CeqC_a: return "nc"; case CeqC_b: return "nc"; + case CeqCc: return "c"; case CeqD_b: return "l"; case CeqI: return ""; case CeqI_a: return "ni"; case CeqI_b: return "ni"; + case CeqIi: return "i"; case CeqR: return ""; case CeqR_b: return "nr"; case Ceq_desc: return "nl"; @@ -695,17 +697,21 @@ const char *instruction_type (BC_WORD i) { case Cjmp_eqACio: return "nsl"; case Cjmp_eqC_b: return "ncl"; case Cjmp_eqC_b2: return "nclcl"; + case Cjmp_eqCc: return "cl"; case Cjmp_eqD_b: return "ll"; case Cjmp_eqD_b2: return "llll"; case Cjmp_eqI: return "l"; case Cjmp_eqI_b: return "nil"; case Cjmp_eqI_b2: return "nilil"; + case Cjmp_eqIi: return "il"; case Cjmp_eq_desc: return "nll"; case Cjmp_geI: return "l"; case Cjmp_ltI: return "l"; case Cjmp_neC_b: return "ncl"; + case Cjmp_neCc: return "cl"; case Cjmp_neI: return "l"; case Cjmp_neI_b: return "nil"; + case Cjmp_neIi: return "il"; case Cjmp_ne_desc: return "nll"; case Cjmp_o_geI: return "nl"; case Cjmp_o_geI_arraysize_a: return "nnl"; @@ -722,6 +728,7 @@ const char *instruction_type (BC_WORD i) { case Cpop_b_rtn: return "N"; case CpushD_a_jmp_eqD_b2: return "nllll"; case Cpush_a_jsr: return "nl"; + case Cpush_b_decI: return "n"; case Cpush_b_incI: return "n"; case Cpush_b_jsr: return "nl"; case Cpush_arraysize_a: return "n"; @@ -735,7 +742,9 @@ const char *instruction_type (BC_WORD i) { case Cpush3_b: return "n"; case Cpush_update_a: return "nn"; case Cput_a: return "n"; + case Cput_a_jmp: return "nl"; case Cput_b: return "n"; + case Cput_b_jmp: return "nl"; case CselectBOOLoo: return "nn"; case CselectCHARoo: return "nn"; case CselectINToo: return "nn"; diff --git a/src/abc_instructions.h b/src/abc_instructions.h index c341163..b01fab9 100644 --- a/src/abc_instructions.h +++ b/src/abc_instructions.h @@ -160,6 +160,7 @@ enum { INSTRUCTION(eqC) INSTRUCTION(eqC_a) INSTRUCTION(eqC_b) + INSTRUCTION(eqCc) INSTRUCTION(eqD_b) INSTRUCTION(eq_desc) INSTRUCTION(eq_desc_b) @@ -167,6 +168,7 @@ enum { INSTRUCTION(eqI) INSTRUCTION(eqI_a) INSTRUCTION(eqI_b) + INSTRUCTION(eqIi) INSTRUCTION(eqR) INSTRUCTION(eqR_b) INSTRUCTION(expR) @@ -682,17 +684,21 @@ enum { INSTRUCTION(jmp_eqACio) INSTRUCTION(jmp_eqC_b) INSTRUCTION(jmp_eqC_b2) + INSTRUCTION(jmp_eqCc) INSTRUCTION(jmp_eqD_b) INSTRUCTION(jmp_eqD_b2) INSTRUCTION(jmp_eqI) INSTRUCTION(jmp_eqI_b) INSTRUCTION(jmp_eqI_b2) + INSTRUCTION(jmp_eqIi) INSTRUCTION(jmp_eq_desc) INSTRUCTION(jmp_geI) INSTRUCTION(jmp_ltI) INSTRUCTION(jmp_neC_b) + INSTRUCTION(jmp_neCc) INSTRUCTION(jmp_neI) INSTRUCTION(jmp_neI_b) + INSTRUCTION(jmp_neIi) INSTRUCTION(jmp_ne_desc) INSTRUCTION(jmp_o_geI) INSTRUCTION(jmp_o_geI_arraysize_a) @@ -710,6 +716,7 @@ enum { INSTRUCTION(pop_b_rtn) INSTRUCTION(pushD_a_jmp_eqD_b2) INSTRUCTION(push_a_jsr) + INSTRUCTION(push_b_decI) INSTRUCTION(push_b_incI) INSTRUCTION(push_b_jsr) INSTRUCTION(push_arraysize_a) @@ -723,7 +730,9 @@ enum { INSTRUCTION(push3_b) INSTRUCTION(push_update_a) INSTRUCTION(put_a) + INSTRUCTION(put_a_jmp) INSTRUCTION(put_b) + INSTRUCTION(put_b_jmp) INSTRUCTION(selectBOOLoo) INSTRUCTION(selectCHARoo) INSTRUCTION(selectINToo) diff --git a/src/bcgen_instruction_table.c b/src/bcgen_instruction_table.c index 27ca8ec..5c222cc 100644 --- a/src/bcgen_instruction_table.c +++ b/src/bcgen_instruction_table.c @@ -104,9 +104,11 @@ void load_instruction_table(void) { put_instruction_name("eqC", parse_instruction, code_eqC ); put_instruction_name("eqC_a", parse_instruction_c_n, code_eqC_a ); put_instruction_name("eqC_b", parse_instruction_c_n, code_eqC_b ); + put_instruction_name("eqCc", parse_instruction_c, code_eqCc ); put_instruction_name("eqI", parse_instruction, code_eqI ); put_instruction_name("eqI_a", parse_instruction_i_n, code_eqI_a ); put_instruction_name("eqI_b", parse_instruction_i_n, code_eqI_b ); + put_instruction_name("eqIi", parse_instruction_i, code_eqIi ); put_instruction_name("eqR", parse_instruction, code_eqR ); put_instruction_name("eqR_b", parse_instruction_r_n, code_eqR_b ); put_instruction_name("eq_desc", parse_instruction_a_n_n, code_eq_desc ); @@ -276,17 +278,21 @@ void load_instruction_table(void) { put_instruction_name("jmp_eqACio", parse_instruction_s2_n_a, code_jmp_eqACio ); put_instruction_name("jmp_eqC_b", parse_instruction_c_n_a, code_jmp_eqC_b ); put_instruction_name("jmp_eqC_b2", parse_instruction_c_c_n_a_a, code_jmp_eqC_b2 ); + put_instruction_name("jmp_eqCc", parse_instruction_c_a, code_jmp_eqCc ); put_instruction_name("jmp_eqD_b", parse_instruction_a_n_a, code_jmp_eqD_b ); put_instruction_name("jmp_eqD_b2", parse_instruction_a_n_a_a_n_a, code_jmp_eqD_b2 ); put_instruction_name("jmp_eqI", parse_instruction_a, code_jmp_eqI ); put_instruction_name("jmp_eqI_b", parse_instruction_i_n_a, code_jmp_eqI_b ); put_instruction_name("jmp_eqI_b2", parse_instruction_i_i_n_a_a, code_jmp_eqI_b2 ); + put_instruction_name("jmp_eqIi", parse_instruction_i_a, code_jmp_eqIi ); put_instruction_name("jmp_eq_desc", parse_instruction_a_n_n_a, code_jmp_eq_desc ); put_instruction_name("jmp_geI", parse_instruction_a, code_jmp_geI ); put_instruction_name("jmp_ltI", parse_instruction_a, code_jmp_ltI ); put_instruction_name("jmp_neC_b", parse_instruction_c_n_a, code_jmp_neC_b ); + put_instruction_name("jmp_neCc", parse_instruction_c_a, code_jmp_neCc ); put_instruction_name("jmp_neI", parse_instruction_a, code_jmp_neI ); put_instruction_name("jmp_neI_b", parse_instruction_i_n_a, code_jmp_neI_b ); + put_instruction_name("jmp_neIi", parse_instruction_i_a, code_jmp_neIi ); put_instruction_name("jmp_ne_desc", parse_instruction_a_n_n_a, code_jmp_ne_desc ); put_instruction_name("jmp_o_geI", parse_instruction_n_a, code_jmp_o_geI ); put_instruction_name("jmp_o_geI_arraysize_a", parse_instruction_a_n_n_a, code_jmp_o_geI_arraysize_a ); @@ -306,6 +312,7 @@ void load_instruction_table(void) { put_instruction_name("pushD_a_jmp_eqD_b2", parse_instruction_n_a_n_a_a_n_a, code_pushD_a_jmp_eqD_b2 ); put_instruction_name("push_a_jsr", parse_instruction_n_a, code_push_a_jsr ); put_instruction_name("push_arraysize_a", parse_instruction_a_n_n_n, code_push_arraysize_a ); + put_instruction_name("push_b_decI", parse_instruction_n, code_push_b_decI ); put_instruction_name("push_b_incI", parse_instruction_n, code_push_b_incI ); put_instruction_name("push_b_jsr", parse_instruction_n_a, code_push_b_jsr ); put_instruction_name("push_jsr_eval", parse_instruction_n, code_push_jsr_eval ); @@ -318,7 +325,9 @@ void load_instruction_table(void) { put_instruction_name("push3_b", parse_instruction_n, code_push3_b ); put_instruction_name("push_update_a", parse_instruction_n_n, code_push_update_a ); put_instruction_name("put_a", parse_instruction_n, code_put_a ); + put_instruction_name("put_a_jmp", parse_instruction_n_a, code_put_a_jmp ); put_instruction_name("put_b", parse_instruction_n, code_put_b ); + put_instruction_name("put_b_jmp", parse_instruction_n_a, code_put_b_jmp ); put_instruction_name("selectoo", parse_instruction_a_n_n_n_n, code_selectoo ); put_instruction_name("update2_a", parse_instruction_n_n, code_update2_a ); put_instruction_name("update2_b", parse_instruction_n_n, code_update2_b ); diff --git a/src/bcgen_instructions.c b/src/bcgen_instructions.c index 499b701..8719969 100644 --- a/src/bcgen_instructions.c +++ b/src/bcgen_instructions.c @@ -421,6 +421,15 @@ void add_instruction_c(int16_t i,char n) { store_code_elem(1, n); } +void add_instruction_c_label(int16_t i,char n,char *label_name) { + if (list_code || i>max_implemented_instruction_n) + printf("%d\t%s %d %s\n",pgrm.code_size,instruction_name (i),(int)n,label_name); + + store_code_elem(BYTEWIDTH_INSTRUCTION, i); + store_code_elem(1, n); + store_code_label_value(label_name,0); +} + void add_instruction_w(int16_t i,int32_t n) { if (list_code || i>max_implemented_instruction_n) printf("%d\t%s %d\n",pgrm.code_size,instruction_name (i),(int)n); @@ -550,6 +559,15 @@ void add_instruction_i_w(int16_t i,int64_t n1,int32_t n2) { store_code_elem(2, n2); } +void add_instruction_i_label(int16_t i,int64_t n,char *label_name) { + if (list_code || i>max_implemented_instruction_n) + printf("%d\t%s %d %s\n",pgrm.code_size,instruction_name (i),(int)n,label_name); + + store_code_elem(BYTEWIDTH_INSTRUCTION, i); + store_code_elem(8, n); + store_code_label_value(label_name,0); +} + void add_instruction_w_c_label(int16_t i,int32_t n1,char n2,char *label_name) { if (list_code || i>max_implemented_instruction_n) printf("%d\t%s %d %d %s\n",pgrm.code_size,instruction_name (i),(int)n1,(int)n2,label_name); @@ -1500,6 +1518,10 @@ void code_eqC_b(int value,int b_offset) { add_instruction_w_c(CeqC_b,b_offset,value); } +void code_eqCc(int value) { + add_instruction_c(CeqCc,value); +} + void code_eqD_b(char descriptor_name[],int arity) { add_instruction_label_offset(CeqD_b,descriptor_name,(arity<<3)+2); } @@ -1516,6 +1538,10 @@ void code_eqI_a(CleanInt value,int a_offset) { add_instruction_w_i(CeqI_a,-a_offset,value); } +void code_eqIi(CleanInt value) { + add_instruction_i(CeqIi,value); +} + void code_eqR(void) { add_instruction(CeqR); } @@ -3575,6 +3601,10 @@ void code_jmp_eqC_b2(int value1,int value2,int b_offset,char label_name1[],char add_instruction_w_c_label_c_label(Cjmp_eqC_b2,b_offset,value1,label_name1,value2,label_name2); } +void code_jmp_eqCc(int value,char label_name[]) { + add_instruction_c_label(Cjmp_eqCc,value,label_name); +} + void code_jmp_eqD_b(char descriptor_name[],int arity,char label_name[]) { add_instruction_label_offset_label(Cjmp_eqD_b,descriptor_name,(arity<<3)+2,label_name); } @@ -3596,6 +3626,10 @@ void code_jmp_eqI_b2(CleanInt value1,CleanInt value2,int b_offset,char label_nam add_instruction_w_i_label_i_label(Cjmp_eqI_b2,b_offset,value1,label_name1,value2,label_name2); } +void code_jmp_eqIi(CleanInt value,char label_name[]) { + add_instruction_i_label(Cjmp_eqIi,value,label_name); +} + void code_jmp_eq_desc(char descriptor_name[],int arity,int a_offset,char label_name[]) { add_instruction_w_label_offset_label(Cjmp_eq_desc,-a_offset,descriptor_name,(arity<<3)+2,label_name); } @@ -3612,6 +3646,10 @@ void code_jmp_neC_b(int value,int b_offset,char label_name[]) { add_instruction_w_c_label(Cjmp_neC_b,b_offset,value,label_name); } +void code_jmp_neCc(int value,char label_name[]) { + add_instruction_c_label(Cjmp_neCc,value,label_name); +} + void code_jmp_neI(char label_name[]) { add_instruction_label(Cjmp_neI,label_name); } @@ -3620,6 +3658,10 @@ void code_jmp_neI_b(CleanInt value,int b_offset,char label_name[]) { add_instruction_w_i_label(Cjmp_neI_b,b_offset,value,label_name); } +void code_jmp_neIi(CleanInt value,char label_name[]) { + add_instruction_i_label(Cjmp_neIi,value,label_name); +} + void code_jmp_ne_desc(char descriptor_name[],int arity,int a_offset,char label_name[]) { add_instruction_w_label_offset_label(Cjmp_ne_desc,-a_offset,descriptor_name,(arity<<3)+2,label_name); } @@ -3789,6 +3831,10 @@ void code_push_ab(int a_offset,int b_offset) { add_instruction_w_w(Cpush_ab,-a_offset,b_offset); } +void code_push_b_decI(int b_offset) { + add_instruction_w(Cpush_b_decI,b_offset); +} + void code_push_b_incI(int b_offset) { add_instruction_w(Cpush_b_incI,b_offset); } @@ -3856,10 +3902,22 @@ void code_put_a(int a_offset) { add_instruction_w(Cput_a,-a_offset); } +void code_put_a_jmp(int a_offset, char label_name[]) { + last_d=0; + + add_instruction_w_label(Cput_a_jmp,-a_offset,label_name); +} + void code_put_b(int b_offset) { add_instruction_w(Cput_b,b_offset); } +void code_put_b_jmp(int b_offset, char label_name[]) { + last_d=0; + + add_instruction_w_label(Cput_b_jmp,b_offset,label_name); +} + void code_selectoo(char element_descriptor[],int a_size,int b_size,int a_offset,int b_offset) { switch(element_descriptor[0]) { case 'B': diff --git a/src/bcgen_instructions.h b/src/bcgen_instructions.h index 3449cc2..0d1ab9e 100644 --- a/src/bcgen_instructions.h +++ b/src/bcgen_instructions.h @@ -83,10 +83,12 @@ void code_eqB_b(int value, int b_offset); void code_eqC(void); void code_eqC_a(int value, int a_offset); void code_eqC_b(int value, int b_offset); +void code_eqCc(int value); void code_eqD_b(char descriptor_name[], int arity); void code_eqI(void); void code_eqI_a(CleanInt value, int a_offset); void code_eqI_b(CleanInt value, int b_offset); +void code_eqIi(CleanInt value); void code_eqR(void); void code_eqR_b(double value, int b_offset); void code_eq_desc(char descriptor_name[], int arity, int a_offset); @@ -253,17 +255,21 @@ void code_jmp_b_false(int b_offset, char label_name[]); void code_jmp_eqACio(char *string, int string_length, int a_offset, char label_name[]); void code_jmp_eqC_b(int value, int b_offset, char label_name[]); void code_jmp_eqC_b2(int value1, int value2, int b_offset, char label_name1[], char label_name2[]); +void code_jmp_eqCc(int value,char label_name[]); void code_jmp_eqD_b(char descriptor_name[], int arity, char label_name[]); void code_jmp_eqD_b2(char descriptor_name1[], int arity1, char label_name1[], char descriptor_name2[], int arity2, char label_name2[]); void code_jmp_eqI(char label_name[]); void code_jmp_eqI_b(CleanInt value, int b_offset, char label_name[]); void code_jmp_eqI_b2(CleanInt value1, CleanInt value2, int b_offset, char label_name1[], char label_name2[]); +void code_jmp_eqIi(CleanInt value,char label_name[]); void code_jmp_eq_desc(char descriptor_name[], int arity, int a_offset, char label_name[]); void code_jmp_geI(char label_name[]); void code_jmp_ltI(char label_name[]); void code_jmp_neC_b(int value, int b_offset, char label_name[]); +void code_jmp_neCc(int value,char label_name[]); void code_jmp_neI(char label_name[]); void code_jmp_neI_b(CleanInt value, int b_offset, char label_name[]); +void code_jmp_neIi(CleanInt value,char label_name[]); void code_jmp_ne_desc(char descriptor_name[], int arity, int a_offset, char label_name[]); void code_jmp_o_geI(int b_offset, char label_name[]); void code_jmp_o_geI_arraysize_a(char element_descriptor[], int b_offset, int a_offset, char label_name[]); @@ -284,6 +290,7 @@ void code_pushD_a_jmp_eqD_b2(int a_offset, char descriptor_name1[], int arity1, char descriptor_name2[], int arity2, char label_name2[]); void code_push_a_jsr(int a_offset, char label_name[]); void code_push_arraysize_a(char element_descriptor[], int a_size, int b_size, int a_offset); +void code_push_b_decI(int b_offset); void code_push_b_incI(int b_offset); void code_push_b_jsr(int b_offset, char label_name[]); void code_push_jsr_eval(int a_offset); @@ -296,7 +303,9 @@ void code_push3_a(int a_offset); void code_push3_b(int b_offset); void code_push_update_a(int a_offset_1, int a_offset_2); void code_put_a(int a_offset); +void code_put_a_jmp(int a_offset, char label_name[]); void code_put_b(int b_offset); +void code_put_b_jmp(int b_offset, char label_name[]); void code_selectoo(char element_descriptor[], int a_size, int b_size, int a_offset, int b_offset); void code_update2_a(int a_offset_1, int a_offset_2); void code_update2_b(int b_offset_1, int b_offset_2); diff --git a/src/parse_abc.c b/src/parse_abc.c index 2f67608..6bccca4 100644 --- a/src/parse_abc.c +++ b/src/parse_abc.c @@ -1078,6 +1078,18 @@ int parse_instruction_c (instruction *instruction) return 1; } +int parse_instruction_c_a (instruction *instruction) +{ + unsigned char c; + STRING a; + + if (!parse_character (&c)) + return 0; + parse_label (a); + instruction->code_function (c,a); + return 1; +} + int parse_instruction_c_c_n_a_a (instruction *instruction) { unsigned char c1,c2; @@ -1126,6 +1138,18 @@ int parse_instruction_i (instruction *instruction) return 1; } +int parse_instruction_i_a (instruction *instruction) +{ + CleanInt i; + STRING a; + + if (!parse_clean_integer (&i)) + return 0; + parse_label (a); + instruction->code_function (i,a); + return 1; +} + int parse_instruction_i_i_n_a_a (instruction *instruction) { CleanInt i1,i2; diff --git a/src/parse_abc.h b/src/parse_abc.h index 00f3944..fba892c 100644 --- a/src/parse_abc.h +++ b/src/parse_abc.h @@ -22,10 +22,12 @@ int parse_instruction_a_n_n_n_n_n(struct instruction*); int parse_instruction_b(struct instruction*); int parse_instruction_b_n(struct instruction*); int parse_instruction_c(struct instruction*); +int parse_instruction_c_a(struct instruction*); int parse_instruction_c_c_n_a_a(struct instruction*); int parse_instruction_c_n(struct instruction*); int parse_instruction_c_n_a(struct instruction*); int parse_instruction_i(struct instruction*); +int parse_instruction_i_a (instruction *instruction); int parse_instruction_r(struct instruction*); int parse_instruction_r_n (instruction *instruction); int parse_instruction_i_i_n_a_a(struct instruction*); diff --git a/test/functions.32.expected b/test/functions.32.expected index 14b631a..7297f53 100644 --- a/test/functions.32.expected +++ b/test/functions.32.expected @@ -1,3 +1,3 @@ (square.2,sub5.3,(sub5.3 0 10),sumints.4,reverse.5,foldr.6,ap1.7,ap3.8,map.9,repeat.10,([(IT1 37 '!'),(IT2 37 '!')],{InternalType2 (IT1 37 '!') 1,InternalType2 (IT2 37 '!') 2},[(InternalType2 (IT1 37 '!') 1),(InternalType2 (IT2 37 '!') 2)])) -halt at 55 +halt at 54 63 524225 524288 diff --git a/test/functions.64.expected b/test/functions.64.expected index a992626..b87c0f6 100644 --- a/test/functions.64.expected +++ b/test/functions.64.expected @@ -1,3 +1,3 @@ (square.2,sub5.3,(sub5.3 0 10),sumints.4,reverse.5,foldr.6,ap1.7,ap3.8,map.9,repeat.10,([(IT1 37 '!'),(IT2 37 '!')],{InternalType2 (IT1 37 '!') 1,InternalType2 (IT2 37 '!') 2},[(InternalType2 (IT1 37 '!') 1),(InternalType2 (IT2 37 '!') 2)])) -halt at 55 +halt at 54 63 262081 262144 diff --git a/tools/interpretergen.icl b/tools/interpretergen.icl index c4a4dbb..d0f56ff 100644 --- a/tools/interpretergen.icl +++ b/tools/interpretergen.icl @@ -1245,6 +1245,9 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t instr "eqI_b" (Just 2) $ B @ -1 .= (B @ to_int (Pc @ 1) ==. Pc @ 2) :. grow_b 1 + , alias "eqCc" $ + instr "eqIi" (Just 1) $ + B @ 0 .= (B @ 0 ==. Pc @ 1) , instr "eqR_b" (Just 2) $ B @ -1 .= (to_real (B @ to_int (Pc @ 1)) ==. to_real (Pc @ 2)) :. grow_b 1 @@ -3120,6 +3123,15 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t shrink_b 2 \\ (name,op) <- [("eq",(==.)),("ne",(<>.)),("ge",(>=.)),("lt",(<.))] ] ++ + [ instr ("jmp_"+++name+++type) (Just 2) $ + if_then (op (to_int (B @ 0)) (to_int (Pc @ 1))) ( + shrink_b 1 :. + Pc .= to_word_ptr (Pc @ 2) :. + end_instruction + ) :. + shrink_b 1 + \\ (name,op) <- [("eq",(==.)),("ne",(<>.))], type <- ["Cc","Ii"] + ] ++ [ instr ("jmp_"+++name+++"_desc") (Just 3) $ new_local (TPtr TWord) (to_word_ptr (A @ to_int (Pc @ 1))) \n -> if_then (op (n @ 0) (Pc @ 2)) ( @@ -3264,6 +3276,10 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t v .= B @ to_int (Pc @ 2) :. B @ -1 .= v :. grow_b 1 + , instr "push_b_decI" (Just 1) $ + new_local TWord (B @ to_int (Pc @ 1)) \v -> + B @ -1 .= v - lit_word 1 :. + grow_b 1 , instr "push_b_incI" (Just 1) $ new_local TWord (B @ to_int (Pc @ 1)) \v -> B @ -1 .= v + lit_word 1 :. @@ -3317,9 +3333,17 @@ all_instructions opts t = bootstrap $ collect_instructions opts $ map (\i -> i t , instr "put_a" (Just 1) $ A @ to_int (Pc @ 1) .= A @ 0 :. shrink_a 1 + , instr "put_a_jmp" Nothing $ + A @ to_int (Pc @ 1) .= A @ 0 :. + Pc .= to_word_ptr (Pc @ 2) :. + shrink_a 1 , instr "put_b" (Just 1) $ B @ to_int (Pc @ 1) .= B @ 0 :. shrink_b 1 + , instr "put_b_jmp" Nothing $ + B @ to_int (Pc @ 1) .= B @ 0 :. + Pc .= to_word_ptr (Pc @ 2) :. + shrink_b 1 , instr "selectoo" (Just 2) $ new_local (TPtr TWord) (to_word_ptr (A @ to_int (Pc @ 1))) \array -> A @ 1 .= array @ (lit_word 3 + B @ to_int (Pc @ 2)) :. -- GitLab