From 2d7a57dd7dec94f4436b8494bed78bb80b064235 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Wed, 9 Jun 2010 20:21:29 +0200 Subject: [PATCH] ppc: erster testfall geht \o/ (codea_abgabe_a.0) --- .gitignore | 10 ++++++ gesamt_ppc/chelper.c | 27 ++++++--------- gesamt_ppc/chelper.h | 3 +- gesamt_ppc/code.bfe | 78 +++++++++++++++++++++++++------------------- gesamt_ppc/parser.y | 6 ++-- 5 files changed, 69 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index 83d6c6c..c006fba 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ oxout.* *.trace *.swp +cscope.out +tags + #asma asma/asma @@ -49,5 +52,12 @@ gesamt/parser.h gesamt/scanner.c gesamt/code.c +#gesamt_ppc +gesamt_ppc/gesamt +gesamt_ppc/parser.c +gesamt_ppc/parser.h +gesamt_ppc/scanner.c +gesamt_ppc/code.c + #weitere eintragen... torero/torero.log diff --git a/gesamt_ppc/chelper.c b/gesamt_ppc/chelper.c index dd345b0..ce1ab67 100644 --- a/gesamt_ppc/chelper.c +++ b/gesamt_ppc/chelper.c @@ -8,9 +8,8 @@ #define DDCHELP #endif -#define REGLEN 4 -static char *regs64[] = {"rax", "r10", "r11", "r9"}; -static char *regs8l[] = {"al", "r10b", "r11b", "r9b"}; +#define REGLEN 5 +static char *regsppc[] = {"14", "15", "16", "17", "18"}; /* ja, dirty.. */ static char *akt_func_name = (char*) NULL; @@ -19,7 +18,7 @@ static char need_stack = 0; void func_header(char *s, int vars, int parms, int call) { printf("\t.globl %1$s\n\t.type %1$s, @function\n%1$s:\n", s); - printf("\t//vars: %i, parms: %i, call(bool): %i\n", vars, parms, call); + printf("\t#vars: %i, parms: %i, call(bool): %i\n", vars, parms, call); akt_func_name = s; need_stack = (vars || parms) && call; @@ -37,14 +36,14 @@ void func_footer(void) { if(need_stack) printf("\tleave\n"); - printf("\tret\n\n\n"); + printf("\tblr\n\n\n"); } void move(char *src, char *dst) { if(src == (char*) NULL) return; if(strcmp(src,dst) != 0) { - printf("\tmovq %%%s, %%%s\n", src, dst); + printf("\tmr %s, %s\n", dst, src); } } @@ -59,33 +58,27 @@ char *next_reg(char *s, int params) { int i = 0; if (s != (char*) NULL) { - while(strcmp(s, regs64[i]) != 0) { + while(strcmp(s, regsppc[i]) != 0) { i = (i+1) % REGLEN; } i = (i+1) % REGLEN; } #ifdef DDCHELP - fprintf(stderr, "next_reg(): %s (bei %i parameter)\n", regs64[i], params); + fprintf(stderr, "next_reg(): %s (bei %i parameter)\n", regsppc[i], params); #endif - return regs64[i]; + return regsppc[i]; } char *reg_64to8l(char *s) { - int i = 0; - if (s != (char*) NULL) { - while(strcmp(s, regs64[i]) != 0) { - i = (i+1) % REGLEN; - } - return regs8l[i]; - } fprintf(stderr, "reg_64to8l(): sollte nicht passieren\n"); exit(4); + return ""; } char *param_reg(int num) { - char *regs[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"}; + char *regs[] = {"3", "4", "5", "6", "7", "8", "9"}; return regs[num]; } diff --git a/gesamt_ppc/chelper.h b/gesamt_ppc/chelper.h index ea7481b..004dcdb 100644 --- a/gesamt_ppc/chelper.h +++ b/gesamt_ppc/chelper.h @@ -1,11 +1,12 @@ #ifndef __CHELPER_H #define __CHELPER_H +#define VARBEGIN 5 void func_header(char *s, int vars, int parms, int call); char *get_func_name(void); void func_footer(void); char *next_reg(char *s, int params); -char *reg_64to8l(char *s); char *param_reg(int num); +char *reg_64to8l(char *s); void move(char *src, char *dest); #endif diff --git a/gesamt_ppc/code.bfe b/gesamt_ppc/code.bfe index 33979ba..cf14116 100644 --- a/gesamt_ppc/code.bfe +++ b/gesamt_ppc/code.bfe @@ -11,6 +11,10 @@ #define KIDKID_VAL(A,B) bnode->kids[A]->kids[B]->val #define KIDKIDKID_VAL(A,B,C) bnode->kids[A]->kids[B]->kids[C]->val +#define KID_PARM(A) bnode->kids[A]->param_index +#define KIDKID_PARM(A,B) bnode->kids[A]->kids[B]->param_index +#define KIDKIDKID_PARM(A,B,C) bnode->kids[A]->kids[B]->kids[C]->param_index + /* macros zum zugriff des aktuellen knotens */ #define BN_REG bnode->reg #define BN_VAL bnode->val @@ -33,26 +37,32 @@ void gen_e_eno(struct treenode *bnode, char *instr) { - printf("\t//gen_e_eno(%s)\n", 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)); + 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(1), KID_REG(0)); +#endif } void gen_id_eno(struct treenode *bnode) { - printf("\t//gen_id_eno\n"); + printf("\t#gen_id_eno\n"); KIDKIDREG2PARM(1,0); KIDKIDREG2PARM(1,1); KIDREG2PARM(0); move(KID_REG(0), BN_REG); - printf("\tsubq %%%s, %%%s\n", KIDKID_REG(1,1), BN_REG); - printf("\tsubq %%%s, %%%s\n", KIDKID_REG(1,0), BN_REG); + printf("\tsubf %%%s, %%%s\n", KIDKID_REG(1,1), BN_REG); + printf("\tsubf %%%s, %%%s\n", KIDKID_REG(1,0), BN_REG); } void gen_e_field(struct treenode *bnode, char *instr) { - printf("\t//gen_e_field(%s)\n", 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)); @@ -60,7 +70,7 @@ void gen_e_field(struct treenode *bnode, char *instr) void gen_field_imm(struct treenode *bnode) { - printf("\t//gen_field_imm\n"); + printf("\t#gen_field_imm\n"); KIDKIDREG2PARM(0,0); KIDREG2ID(1); printf("\timulq $%d, %d(%%%s), %%%s\n", KID_VAL(1), bnode->kids[0]->soffset * 8, KIDKID_REG(0, 0), BN_REG); @@ -68,19 +78,19 @@ void gen_field_imm(struct treenode *bnode) void gen_e_imm(struct treenode *bnode, char *instr) { - printf("\t//gen_e_imm(%s)\n", instr); + printf("\t#gen_e_imm(%s)\n", instr); KIDREG2PARM(0); KIDREG2ID(1); /* man kann sich ein move der konstante bei der multiplikation ersparen */ if(strcmp(instr, "imulq") == 0) { if(KID_VAL(1) == 1 && strcmp(KID_REG(0), BN_REG) == 0) { - printf("\t//multiplikation mit 1 wegoptimiert\n"); + printf("\t#multiplikation mit 1 wegoptimiert\n"); } else { printf("\timulq $%d, %%%s, %%%s\n", KID_VAL(1), KID_REG(0), BN_REG); } } else { - if(strcmp(instr, "subq") == 0 && KID_VAL(1) == 0) { - printf("\t//subtraktion mit 0 wegoptimiert\n"); + if(strcmp(instr, "subf") == 0 && KID_VAL(1) == 0) { + printf("\t#subtraktion mit 0 wegoptimiert\n"); move(KID_REG(0), BN_REG); } else { move(KID_REG(0), BN_REG); @@ -91,23 +101,23 @@ void gen_e_imm(struct treenode *bnode, char *instr) void gen_imm_field(struct treenode *bnode) { - printf("\t//gen_imm_field\n"); + printf("\t#gen_imm_field\n"); KIDREG2ID(0); KIDKIDREG2PARM(1, 0); moveimm(KID_VAL(0), BN_REG); - printf("\tsubq %d(%%%s), %%%s\n", bnode->kids[1]->soffset * 8, KIDKID_REG(1, 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); + printf("\t#gen_imm_eno(%s)\n", instr); KIDREG2ID(0); KIDREG2PARM(1); /* man kann sich ein move der konstante bei der multiplikation ersparen */ if(strcmp(instr, "imulq") == 0) { if(KID_VAL(0) == 1 && strcmp(KID_REG(1), BN_REG) == 0) { - printf("\t//multiplikation mit 1 wegoptimiert\n"); + printf("\t#multiplikation mit 1 wegoptimiert\n"); } else { printf("\timulq $%d, %%%s, %%%s\n", KID_VAL(0), KID_REG(1), BN_REG); } @@ -118,7 +128,7 @@ void gen_imm_eno(struct treenode *bnode, char *instr) void gen_eqless(struct treenode *bnode, char *op, short e0, short e1, short deep) { - printf("\t//gen_eqless_%i%i @ %i\n", e0, e1, deep); + printf("\t#gen_eqless_%i%i @ %i\n", e0, e1, deep); if(e0) { KIDREG2PARM(0); } else { KIDREG2ID(0); } if(e1) { KIDREG2PARM(1); } else { KIDREG2ID(1); } @@ -148,7 +158,7 @@ void gen_eqless(struct treenode *bnode, char *op, short e0, short e1, short deep void gen_lea(struct treenode *bnode, short e) { - printf("\t//gen_lea(e= %i)\n", e); + printf("\t#gen_lea(e= %i)\n", e); KIDREG2PARM(0); if(e) { KIDKIDREG2PARM(1,0); @@ -162,16 +172,16 @@ void gen_lea(struct treenode *bnode, short e) void gen_subspecial(struct treenode *bnode, short e) { /* tritt z.b. bei snafu_05.0 auf */ - printf("\t//gen_subspecial(%i)\n", e); + printf("\t#gen_subspecial(%i)\n", e); KIDREG2ID(0); KIDKIDREG2PARM(1,0); if(e) { if(KIDKID_VAL(1,0) != 0) { - printf("\tsubq $%d, %%%s\n", KIDKID_VAL(1,0), BN_REG); + printf("\tsubf $%d, %%%s\n", KIDKID_VAL(1,0), BN_REG); } } else { - printf("\tsubq %%%s, %%%s\n", KIDKID_REG(1,0), BN_REG); + printf("\tsubf %%%s, %%%s\n", KIDKID_REG(1,0), BN_REG); } if(e) KIDKIDREG2PARM(1,1); printf("\taddq %%%s, %%%s\n", KIDKID_REG(1,1), BN_REG); @@ -190,18 +200,18 @@ void assign_var(struct treenode *bnode) void make_call(struct treenode *bnode) { int j; - printf("\t//params pushen\n"); + printf("\t#params pushen\n"); for(j = 0; j < bnode->soffset; j++) { printf("\txchg %%%s, %d(%%rsp)\n", param_reg(j), j*8); } - printf("\t//vars pushen\n"); - for(j = bnode->soffset; j < bnode->soffset + bnode->vars; j++) { + printf("\t#vars pushen\n"); + for(j = VARBEGIN; j > VARBEGIN - bnode->vars; j--) { printf("\tpushq %%%s\n", param_reg(j)); } /* TODO: schoener machen... */ if(strcmp(BN_REG, "rax")!=0) { - printf("\t//tmp register pushen\n"); + printf("\t#tmp register pushen\n"); printf("\tpushq %%rax\n"); if(strcmp(BN_REG, "r10")!=0) { printf("\tpushq %%r10\n"); @@ -217,7 +227,7 @@ void make_call(struct treenode *bnode) } /* vars poppen */ - for(j = bnode->soffset + bnode->vars - 1; j > bnode->soffset - 1; j--) { + for(j = VARBEGIN+1 - bnode->vars; j < VARBEGIN+1; j++) { printf("\tpopq %%%s\n", param_reg(j)); } @@ -229,7 +239,7 @@ void make_call(struct treenode *bnode) void prep_arg(struct treenode *bnode, int moveit) { - printf("\t//args-nr-> %i (%%%s) [moveit= %i]\n", bnode->soffset, param_reg(bnode->soffset), moveit); + printf("\t#args-nr-> %i (%%%s) [moveit= %i]\n", bnode->soffset, param_reg(bnode->soffset), moveit); if(moveit) { /* expr */ if((BN_REG == (char *) NULL) || (bnode->kids[1] != TREENULL && bnode->kids[1]->op == O_ID && bnode->kids[1]->kids[0] == TREENULL && bnode->kids[1]->kids[1] == TREENULL)) { if(bnode->kids[1]->name != (char *) NULL && strcmp(bnode->kids[1]->name,"this")!=0) { @@ -250,7 +260,7 @@ 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"); + 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)) { @@ -290,10 +300,10 @@ ifstat: O_IF(expr) # 2 # /* iburg beschummeln :/ */ printf("\ttest $-1, %%rax\n" ifstat: O_IF(O_BOOL(expr)) # 1 # /* dann braucht man kein test */ -ret: O_RET(retexpr) # 2 # printf("\t//o_ret(expr)\n"); move(BN_REG, "rax"); +ret: O_RET(retexpr) # 2 # printf("\t/*o_ret(expr)*/\n"); move(BN_REG, "3"); ret: O_EXPR(expr) # 0 # -retexpr: O_ID # 1 # printf("\t//retexpr\n"); if(bnode->param_index > -1) move(param_reg(bnode->param_index), BN_REG); +retexpr: O_ID # 1 # printf("\t/*retexpr*/\n"); if(bnode->param_index > -1) move(param_reg(bnode->param_index), BN_REG); retexpr: expr @@ -306,9 +316,9 @@ expr: O_ARG(expr,expr) # 1 # prep_arg(bnode, 1); 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, "subq"); -expr: O_SUB(expr,O_FIELD(expr)) # 2 # gen_e_field(bnode, "subq"); -expr: O_SUB(expr,imm) # 1 # gen_e_imm(bnode, "subq"); +expr: O_SUB(expr,expr) # 2 # gen_e_eno(bnode, "subf"); +expr: O_SUB(expr,O_FIELD(expr)) # 2 # gen_e_field(bnode, "subf"); +expr: O_SUB(expr,imm) # 1 # gen_e_imm(bnode, "subf"); expr: O_SUB(expr,O_SUB(O_ID,expr)) # 2 # gen_subspecial(bnode, 0); expr: O_SUB(expr,O_SUB(imm,expr)) # 2 # gen_subspecial(bnode, 1); @@ -361,8 +371,8 @@ expr: O_EQ(O_EQ(expr,O_NULL),O_NULL) # 3 # gen_eqless(bnode, "ne", 1, 0, 1); expr: O_EQ(O_EQ(O_EQ(expr,O_NULL),O_NULL),O_NULL) # 3 # gen_eqless(bnode, "e", 1, 0, 2); -expr: O_FIELD(expr) # 1 # printf("\t//field(expr)\n"); KIDREG2PARM(0); printf("\tmovq %d(%%%s), %%%s\n", bnode->soffset * 8, KID_REG(0), BN_REG); -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(expr) # 1 # printf("\t/* field(expr)*/\n"); KIDREG2PARM(0); printf("\tmovq %d(%%%s), %%%s\n", bnode->soffset * 8, KID_REG(0), BN_REG); +expr: O_FIELD(imm) # 1 # printf("\t/* field(imm)*/\n"); printf("\tmovq %d, %%%s\n", KID_VAL(0) + (bnode->soffset * 8), 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 4b45352..182a08d 100644 --- a/gesamt_ppc/parser.y +++ b/gesamt_ppc/parser.y @@ -65,7 +65,7 @@ Input: Program @{ @i @Program.f@ = tab_new(); - @gen printf("\t.text\n"); + @gen printf("\t.section\t\".text\"\n"); @} ; @@ -178,14 +178,14 @@ Statement: @{ /* tab_clone ist hier noetig, vgl. folgendes statement * > var x := x - 1; */ - @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1, @Statement.gparamges@ + @Statement.vars_in@, -1); + @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1, VARBEGIN - @Statement.vars_in@, -1); lblcountinout() @i @Statement.vars_out@ = @Statement.vars_in@ + 1; xxputsin(@Expr.s@,) - @i @Statement.node@ = new_node(O_ASSIGN, @Expr.node@, new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, @Statement.gparamges@ + @Statement.vars_in@)); + @i @Statement.node@ = new_node(O_ASSIGN, @Expr.node@, new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, VARBEGIN - @Statement.vars_in@)); @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); @gen write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); -- 2.25.1