From f2400f107ac45d9539e4ea1d946f7c9033869336 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Thu, 10 Jun 2010 02:30:45 +0200 Subject: [PATCH] ppc: einige erkenntnisse aus den restlichen custom testfaellen @ testub10 --- gesamt_ppc/chelper.c | 11 +++- gesamt_ppc/code.bfe | 126 ++++++++++++++++--------------------------- gesamt_ppc/parser.y | 2 - 3 files changed, 56 insertions(+), 83 deletions(-) diff --git a/gesamt_ppc/chelper.c b/gesamt_ppc/chelper.c index 3f4776d..2e736ea 100644 --- a/gesamt_ppc/chelper.c +++ b/gesamt_ppc/chelper.c @@ -56,8 +56,15 @@ void move(char *src, char *dst) void moveimm(long imm, char *dst) { - /* TODO: 32 bits... */ - printf("\tli %s,%d\n", dst, imm); + if((imm > 65536-1) || (imm < -65536)) { + /* high word */ + printf("\tlis %s,%d@ha\n", dst, imm); + /* low word */ + printf("\taddi %s,%s,%d@l\n", dst, dst, imm); + } else { + /* just low word */ + printf("\tli %s,%d@l\n", dst, imm); + } } char *next_reg(char *s, int params) diff --git a/gesamt_ppc/code.bfe b/gesamt_ppc/code.bfe index 97dc269..e9234f9 100644 --- a/gesamt_ppc/code.bfe +++ b/gesamt_ppc/code.bfe @@ -38,15 +38,9 @@ void gen_e_eno(struct treenode *bnode, char *instr) { printf("\t#gen_e_eno(%s)\n", instr); -#if 0 - KIDREG2ID(0); - KIDREG2PARM(1); - printf("\t%s %s, %s\n", instr, KID_REG(1), KID_REG(0)); -#else KIDREG2PARM(0); KIDREG2PARM(1); printf("\t%s %s,%s,%s\n", instr, BN_REG, KID_REG(0), KID_REG(1)); -#endif } void gen_id_eno(struct treenode *bnode) @@ -60,22 +54,6 @@ void gen_id_eno(struct treenode *bnode) printf("\tsub %s,%s,%s\n", BN_REG, BN_REG, KIDKID_REG(1,0)); } -void gen_e_field(struct treenode *bnode, char *instr) -{ - printf("\t#gen_e_field(%s)\n", instr); - KIDREG2ID(0); - KIDKIDREG2PARM(1,0); - printf("\t%s %d(%%%s), %%%s\n", instr, bnode->kids[1]->soffset * 8, KIDKID_REG(1,0), KID_REG(0)); -} - -void gen_field_imm(struct treenode *bnode) -{ - printf("\t#gen_field_imm\n"); - KIDKIDREG2PARM(0,0); - KIDREG2ID(1); - printf("\tmullw $%d, %d(%%%s), %%%s\n", KID_VAL(1), bnode->kids[0]->soffset * 8, KIDKID_REG(0, 0), BN_REG); -} - void gen_e_imm(struct treenode *bnode, char *instr) { printf("\t#gen_e_imm(%s)\n", instr); @@ -86,33 +64,28 @@ void gen_e_imm(struct treenode *bnode, char *instr) if(KID_VAL(1) == 1 && strcmp(KID_REG(0), BN_REG) == 0) { printf("\t#multiplikation mit 1 wegoptimiert\n"); } else { - printf("\tmulli %s,%s,%d\n", BN_REG, KID_REG(0), KID_VAL(1)); + if(KID_VAL(1) > (65536)-1 || KID_VAL(1) < -65536) { + moveimm(KID_VAL(1), next_reg(BN_REG,0)); + printf("\tmullw %s,%s,%s\n", BN_REG, KID_REG(0), next_reg(BN_REG,0)); + } else { + printf("\tmulli %s,%s,%d\n", BN_REG, KID_REG(0), KID_VAL(1)); + } } } else { if(strcmp(instr, "sub") == 0 && KID_VAL(1) == 0) { printf("\t#subtraktion mit 0 wegoptimiert\n"); move(KID_REG(0), BN_REG); } else { -#if 0 - move(KID_REG(0), BN_REG); - printf("\t%s $%d, %%%s\n", instr, KID_VAL(1), BN_REG); -#else - printf("\t%si %s,%s,%d\n", instr, BN_REG, KID_REG(0), KID_VAL(1)); -#endif + if(KID_VAL(1) > (65536)-1 || KID_VAL(1) < -65536) { + moveimm(KID_VAL(1), next_reg(BN_REG,0)); + printf("\t%s %s,%s,%s\n", instr, BN_REG, KID_REG(0), next_reg(BN_REG,0)); + } else { + printf("\t%si %s,%s,%d\n", instr, BN_REG, KID_REG(0), KID_VAL(1)); + } } } } -void gen_imm_field(struct treenode *bnode) -{ - printf("\t#gen_imm_field\n"); - KIDREG2ID(0); - KIDKIDREG2PARM(1, 0); - - moveimm(KID_VAL(0), BN_REG); - printf("\tsubf %d(%%%s), %%%s\n", bnode->kids[1]->soffset * 8, KIDKID_REG(1, 0), BN_REG); -} - void gen_imm_eno(struct treenode *bnode, char *instr) { printf("\t#gen_imm_eno(%s)\n", instr); @@ -123,10 +96,16 @@ void gen_imm_eno(struct treenode *bnode, char *instr) if(KID_VAL(0) == 1 && strcmp(KID_REG(1), BN_REG) == 0) { printf("\t#multiplikation mit 1 wegoptimiert\n"); } else { - printf("\tmulli %s,%s,%d\n", BN_REG, KID_REG(1), KID_VAL(0)); + if(KID_VAL(0) > (65536)-1 || KID_VAL(0) < -65536) { + moveimm(KID_VAL(0), next_reg(BN_REG,0)); + printf("\tmullw %s,%s,%s\n", BN_REG, KID_REG(1), next_reg(BN_REG,0)); + } else { + printf("\tmulli %s,%s,%d\n", BN_REG, KID_REG(1), KID_VAL(0)); + } } } else { /* addq */ - printf("\taddi %s,%s,%d\n", BN_REG, BN_REG, KID_VAL(0)); + /* TODO: imm check einbauen */ + printf("\taddi %s,%s,%d\n", BN_REG, KID_REG(1), KID_VAL(0)); } } @@ -161,23 +140,28 @@ void gen_eqless(struct treenode *bnode, char *op, short e0, short e1, short deep printf("\tand $1, %%%s\n", BN_REG); #else if(e0) { KIDREG2PARM(0); } else { moveimm(KID_VAL(0), BN_REG); } - if(e1) { KIDREG2PARM(1); } else { if(KID_VAL(1) != 0) moveimm(KID_VAL(1), KID_REG(1)); } - if(strcmp(op,"e")==0 && KID_VAL(1) == 0 && KID_VAL(0) == 0) { + if(e1) { KIDREG2PARM(1); } + if(strcmp(op,"e")==0 && bnode->kids[1]->op == O_NULL) { /* not */ printf("\tcntlzw %s,%s\n", KID_REG(0), KID_REG(0)); printf("\tsrwi %s,%s,5\n", BN_REG, KID_REG(0)); - } else if(strcmp(op, "e")==0) { - /* eq */ - printf("\txor %s,%s,%s\n", BN_REG, KID_REG(0), KID_REG(1)); - printf("\tcntlzw %s,%s\n", BN_REG, BN_REG); - printf("\tsrwi %s,%s,5\n", BN_REG, BN_REG); - } else if(strcmp(op, "l")==0 || strcmp(op, "g")==0) { - /* less */ - printf("\tcmpw 7,%s,%s\n", KID_REG(1), KID_REG(0)); - printf("\tmfcr %s\n", BN_REG); - /* EQ, GT, LT */ - /* um (32-29)=3 nach rechts shiften und das LSB anschauen */ - printf("\trlwinm %s,%s,%i,31,31\n", BN_REG, BN_REG, strcmp(op,"l")==0 ? 30 : 30); + } else { + if(!e1) { + moveimm(KID_VAL(1), KID_REG(1)); + } + if(strcmp(op, "e")==0) { + /* eq */ + printf("\txor %s,%s,%s\n", BN_REG, KID_REG(0), KID_REG(1)); + printf("\tcntlzw %s,%s\n", BN_REG, BN_REG); + printf("\tsrwi %s,%s,5\n", BN_REG, BN_REG); + } else if(strcmp(op, "l")==0 || strcmp(op, "g")==0) { + /* less */ + printf("\tcmpw 7,%s,%s\n", KID_REG(1), KID_REG(0)); + printf("\tmfcr %s\n", BN_REG); + /* EQ, GT, LT */ + /* um (32-29)=3 nach rechts shiften und das LSB anschauen */ + printf("\trlwinm %s,%s,%i,31,31\n", BN_REG, BN_REG, strcmp(op,"l")==0 ? 30 : 30); + } } /* vergleich mit null und in CR0 speichern */ printf("\tcmpwi %s,0\n", BN_REG); @@ -191,12 +175,14 @@ void gen_subspecial(struct treenode *bnode, short e) KIDREG2ID(0); KIDKIDREG2PARM(1,0); + /* TODO: Loong@ codea_snafu_03.0 */ + if(e) { if(KIDKID_VAL(1,0) != 0) { printf("\tsubi %s,%s,%d\n", BN_REG, BN_REG, KIDKID_VAL(1,0)); } } else { - printf("\tsubf %%%s, %%%s\n", KIDKID_REG(1,0), BN_REG); + printf("\tsub %s,%s,%s\n", BN_REG, BN_REG, KIDKID_REG(1,0)); } if(e) KIDKIDREG2PARM(1,1); printf("\tadd %s,%s,%s\n", BN_REG, BN_REG, KIDKID_REG(1,1)); @@ -284,20 +270,6 @@ void prep_arg(struct treenode *bnode, int moveit) } } -void gen_sub_field(struct treenode *bnode) -{ - /* siehe intelli_03.0 @ gesamt */ - printf("\t#gen_sub_field\n"); - KIDKIDREG2PARM(1,0); - if(!(strcmp(bnode->kids[0]->kids[0]->kids[0]->name, bnode->kids[1]->kids[0]->name) == 0 && - bnode->kids[0]->kids[0]->soffset == bnode->kids[1]->soffset)) { - KIDKIDKIDREG2PARM(0,0,0); - printf("\tmov %s,%d(%s)\n", BN_REG, bnode->kids[0]->kids[0]->soffset * 8, KIDKIDKID_REG(0,0,0)); - printf("\tmov %s,%d(%s)\n", BN_REG, bnode->kids[1]->soffset * 8, KIDKID_REG(1,0)); - } - printf("\tsubi $%d, %d(%%%s)\n", bnode->kids[0]->kids[1]->val, bnode->kids[1]->soffset * 8, KIDKID_REG(1,0)); -} - %} %start begin @@ -312,7 +284,7 @@ begin: args # 0 # assign: O_ASSIGN(expr, O_ID) # 1 # KIDREG2PARM(1); printf("\tmr %s,%s\n", KID_REG(1), BN_REG); -assign: O_ASSIGN(imm, O_ID) # 1 # KIDREG2PARM(1); printf("\tli %s,%d\n", KID_REG(1), KID_VAL(0)); +assign: O_ASSIGN(imm, O_ID) # 1 # KIDREG2PARM(1); moveimm(KID_VAL(0), KID_REG(1)); assign: O_ASSIGN(O_ID, O_ID) # 1 # KIDREG2PARM(1); KIDREG2PARM(0); printf("\tmr %s,%s\n", KID_REG(1), KID_REG(0)); assign: O_ASSIGN(O_SUB(O_ID,O_NUM), O_ID) # 1 # assign_var(bnode); @@ -322,7 +294,8 @@ assign: O_ASSIGN(O_ID, O_FIELD(expr)) # 1 # KIDREG2PARM(0); KIDKIDREG2PARM(1,0); ifstat: O_IF(O_ID) # 1 # /* fuer faelle wie "if bla then" noetig */ KIDREG2PARM(0); printf("\tcmpwi %s,0\n", KID_REG(0)); -ifstat: O_IF(expr) # 2 # /* iburg beschummeln :/ */ printf("\ttest $-1, %%rax\n"); +ifstat: O_IF(O_BOOL(imm)) # 1 # printf("\tcmpwi %s,0\n", BN_REG); +ifstat: O_IF(expr) # 2 # /* iburg beschummeln :/ */ printf("\tcmpwi %s,0\n", BN_REG); ifstat: O_IF(O_BOOL(expr)) # 1 # /* dann braucht man kein test */ @@ -343,7 +316,6 @@ expr: O_ARG(O_ID,expr) # 1 # prep_arg(bnode, 0); expr: O_NOTHING # 0 # expr: O_SUB(expr,expr) # 2 # gen_e_eno(bnode, "sub"); -expr: O_SUB(expr,O_FIELD(expr)) # 2 # gen_e_field(bnode, "sub"); expr: O_SUB(expr,imm) # 1 # gen_e_imm(bnode, "sub"); expr: O_SUB(expr,O_SUB(O_ID,expr)) # 2 # gen_subspecial(bnode, 0); @@ -353,7 +325,7 @@ expr: O_SUB(expr, O_ADD(O_ID,expr)) # 1 # gen_id_eno(bnode); expr: O_ADD(expr,expr) # 1 # gen_e_eno(bnode, "add"); -expr: O_ADD(expr,imm) # 2 # gen_e_imm(bnode, "add"); +expr: O_ADD(expr,imm) # 1 # gen_e_imm(bnode, "add"); expr: O_ADD(imm,expr) # 1 # gen_imm_eno(bnode, "add"); @@ -361,21 +333,17 @@ expr: O_MUL(expr,expr) # 1 # gen_e_eno(bnode, "mullw"); expr: O_MUL(expr,imm) # 1 # gen_e_imm(bnode, "mullw"); expr: O_MUL(imm,expr) # 1 # gen_imm_eno(bnode, "mullw"); -expr: O_MUL(expr,O_FIELD(expr)) # 1 # gen_e_field(bnode, "mullw"); expr: O_OR(expr,expr) # 1 # gen_e_eno(bnode, "or"); expr: O_OR(expr,imm) # 2 # gen_e_imm(bnode, "or"); -expr: O_OR(expr,O_FIELD(expr)) # 2 # gen_e_field(bnode, "or"); expr: O_LESS(expr,expr) # 3 # gen_eqless(bnode, "l", 1, 1, 0); -expr: O_LESS(expr,O_FIELD(expr)) # 3 # gen_eqless(bnode, "l", 1, 1, 1); expr: O_LESS(expr,imm) # 3 # gen_eqless(bnode, "l", 1, 0, 0); expr: O_LESS(imm,expr) # 3 # gen_eqless(bnode, "g", 0, 1, 0); expr: O_EQ(expr,expr) # 3 # gen_eqless(bnode, "e", 1, 1, 0); -expr: O_EQ(expr,O_FIELD(expr)) # 3 # gen_eqless(bnode, "e", 1, 1, 1); expr: O_EQ(expr,imm) # 3 # gen_eqless(bnode, "e", 1, 0, 0); expr: O_EQ(imm,expr) # 3 # gen_eqless(bnode, "e", 0, 1, 0); expr: O_EQ(expr,O_NULL) # 3 # gen_eqless(bnode, "e", 1, 0, 0); @@ -385,7 +353,7 @@ expr: O_EQ(O_EQ(O_EQ(expr,O_NULL),O_NULL),O_NULL) # 3 # gen_eqless(bnode, "e", 1 expr: O_FIELD(expr) # 1 # printf("\t/* field(expr)*/\n"); KIDREG2PARM(0); printf("\tlwz %s, %d(%s)\n", BN_REG, bnode->soffset * 4, KID_REG(0)); -expr: O_FIELD(imm) # 1 # printf("\t/* field(imm)*/\n"); printf("\tmovq %d, %%%s\n", KID_VAL(0) + (bnode->soffset * 8), BN_REG); +expr: O_FIELD(imm) # 1 # printf("\t/* field(imm)*/\n"); moveimm(KID_VAL(0), BN_REG); printf("\tlwz %s,%d(%s)\n", BN_REG, bnode->soffset * 4, BN_REG); imm: O_ADD(imm,imm) # 0 # BN_VAL = KID_VAL(0) + KID_VAL(1); diff --git a/gesamt_ppc/parser.y b/gesamt_ppc/parser.y index ab8d442..e6fc7a5 100644 --- a/gesamt_ppc/parser.y +++ b/gesamt_ppc/parser.y @@ -254,7 +254,6 @@ Statement: @gen { printf(".%s_ifstart_%d:\n", get_func_name(), @Statement.lblcnt_in@); write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); - /* TODO: kann ich mir das test wirklich wegan and davor sparen? */ printf("\tbeq 0,.%s_ifelse_%d\n", get_func_name(), @Statement.lblcnt_in@); } @gen @revorder(1) printf(".%s_ifend_%d:\n", get_func_name(), @Statement.lblcnt_in@); @@ -280,7 +279,6 @@ Statement: @gen { printf(".%s_whilestart_%d:\n", get_func_name(), @Statement.lblcnt_in@); write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); - /* TODO: kann ich mir das test wirklich wegan and davor sparen? */ printf("\tbeq 0,.%s_whileend_%d\n", get_func_name(), @Statement.lblcnt_in@); } @gen @revorder(1) printf("\tb .%s_whilestart_%d\n.%s_whileend_%d:\n", get_func_name(), @Statement.lblcnt_in@, get_func_name(), @Statement.lblcnt_in@); -- 2.25.1