From 87d8329bf334039ff85cac0f833f63f4b9b8ceca Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Mon, 17 May 2010 17:16:35 +0200 Subject: [PATCH] codea: optimierungen mit lea --- codea/code.bfe | 31 ++++++++++++++++++++++++++++++- codea/parser.y | 8 +++++--- codea/tree.c | 28 ++++++++++++++++++++++------ codea/tree.h | 12 ++++++++++-- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/codea/code.bfe b/codea/code.bfe index 6ae2bfb..d022976 100644 --- a/codea/code.bfe +++ b/codea/code.bfe @@ -2,13 +2,16 @@ #define BFEHAX #define KID_REG(A) bnode->kids[A]->reg +#define KIDKID_REG(A,B) bnode->kids[A]->kids[B]->reg #define KID_VAL(A) bnode->kids[A]->val +#define KIDKID_VAL(A,B) bnode->kids[A]->kids[B]->val #define BN_REG bnode->reg #define BN_VAL bnode->val /* falls ein parameter auf der "leseseite" ist, soll das statt ein weiteres * register verwendet werden */ #define KIDREG2PARM(A) if(bnode->kids[A]->param_index > -1) { bnode->kids[A]->reg = param_reg(bnode->kids[A]->param_index); } +#define KIDKIDREG2PARM(A,B) if(bnode->kids[A]->kids[B]->param_index > -1) { bnode->kids[A]->kids[B]->reg = param_reg(bnode->kids[A]->kids[B]->param_index); } #define KIDREG2ID(A) if(bnode->kids[A]->op == O_ID && bnode->kids[A]->param_index > -1) move(param_reg(bnode->kids[A]->param_index), bnode->kids[A]->reg); @@ -78,10 +81,23 @@ void gen_eqless(struct treenode *bnode, char *op, short e0, short e1) printf("\tand $1, %%%s\n", BN_REG); } +void gen_lea(struct treenode *bnode, short e) +{ + printf("\t//gen_lea(e: %i)\n", e); + KIDREG2PARM(0); + if(e) { + KIDKIDREG2PARM(1,0); + printf("\tlea (%%%s,%%%s,%d), %%%s\n", KID_REG(0), KIDKID_REG(1,0), -1 * KIDKID_VAL(1,1), BN_REG); + } else { + KIDKIDREG2PARM(1,1); + printf("\tlea (%%%s,%%%s,%d), %%%s\n", KID_REG(0), KIDKID_REG(1,1), -1 * KIDKID_VAL(1,0), BN_REG); + } +} + %} %start begin -%term O_RET=1 O_NULL=2 O_SUB=3 O_MUL=4 O_OR=5 O_LESS=6 O_EQ=7 O_ID=8 O_ADD=9 O_NUM=10 O_FIELD=11 +%term O_RET=1 O_NULL=2 O_SUB=3 O_MUL=4 O_OR=5 O_LESS=6 O_EQ=7 O_ID=8 O_ADD=9 O_NUM=10 O_FIELD=11 O_MTWO=12 O_MFOUR=13 O_MEIGHT=14 O_MONE=15 %% @@ -97,6 +113,15 @@ expr: imm # 1 # moveimm(BN_VAL, BN_REG); expr: O_SUB(expr,expr) # 1 # gen_e_eno(bnode, "subq"); expr: O_SUB(expr,imm) # 2 # gen_e_imm(bnode, "subq"); expr: O_SUB(imm,expr) # 2 # gen_imm_eno(bnode, "subq"); +expr: O_SUB(O_ID,O_MUL(O_MONE,expr)) # 1 # gen_lea(bnode,0); +expr: O_SUB(O_ID,O_MUL(O_MTWO,expr)) # 1 # gen_lea(bnode,0); +expr: O_SUB(O_ID,O_MUL(O_MFOUR,expr)) # 1 # gen_lea(bnode,0); +expr: O_SUB(O_ID,O_MUL(O_MEIGHT,expr)) # 1 # gen_lea(bnode,0); + +expr: O_SUB(O_ID,O_MUL(expr,O_MONE)) # 1 # gen_lea(bnode,1); +expr: O_SUB(O_ID,O_MUL(expr,O_MTWO)) # 1 # gen_lea(bnode,1); +expr: O_SUB(O_ID,O_MUL(expr,O_MFOUR)) # 1 # gen_lea(bnode,1); +expr: O_SUB(O_ID,O_MUL(expr,O_MEIGHT)) # 1 # gen_lea(bnode,1); expr: O_ADD(expr,expr) # 1 # gen_e_eno(bnode, "addq"); expr: O_ADD(expr,imm) # 2 # gen_e_imm(bnode, "addq"); @@ -132,6 +157,10 @@ imm: O_MUL(imm,imm) # 0 # BN_VAL = KID_VAL(0) * KID_VAL(1); imm: O_LESS(imm,imm) # 0 # BN_VAL = KID_VAL(0) < KID_VAL(1) ? 1 : 0; imm: O_EQ(imm,imm) # 0 # BN_VAL = KID_VAL(0) = KID_VAL(1) ? 1 : 0; imm: O_NUM # 0 # +imm: O_MONE # 0 # +imm: O_MTWO # 0 # +imm: O_MFOUR # 0 # +imm: O_MEIGHT # 0 # %% diff --git a/codea/parser.y b/codea/parser.y index b5a7e7d..b3b3726 100644 --- a/codea/parser.y +++ b/codea/parser.y @@ -236,9 +236,11 @@ Expr: @reg { /* TODO */ - @Term.node@->reg = @Expr.node@->reg; - @Term.node@->skip = 0; - @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip, @Expr.gparamges@); + if(!(@Expr.node@->kids[0] == TREENULL && @Expr.node@->kids[1] == TREENULL)) { + @Term.node@->reg = @Expr.node@->reg; + @Term.node@->skip = 0; + @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip, @Expr.gparamges@); + } } @} diff --git a/codea/tree.c b/codea/tree.c index 7e7c715..098f975 100644 --- a/codea/tree.c +++ b/codea/tree.c @@ -22,16 +22,21 @@ static struct treenode *_new_plain(int op) struct treenode *new_node(int op, struct treenode *l, struct treenode *r, int exprcount) { - struct treenode *new = _new_plain(op); + struct treenode *new = TREENULL; #ifdef DDTREE fprintf(stderr, "new_node: %i (%s)\n", op, o_names[op]); #endif - - new->kids[0] = l; - new->kids[1] = r; + if(op == O_SUB && l != TREENULL && r != TREENULL && l->op == O_NUM && r->op == O_NUM) { + new = new_number(l->val - r->val, exprcount); + free(l); free(r); + } else { + new = _new_plain(op); + new->kids[0] = l; + new->kids[1] = r; + new->exprcount = exprcount; + } new->name = (char *)NULL; - new->exprcount = exprcount; return new; } @@ -61,10 +66,21 @@ struct treenode *new_field(char *name, struct treenode *l, struct treenode *r, i struct treenode *new_number(long val, int exprcount) { - struct treenode *new = _new_plain(O_NUM); + struct treenode *new; /* TODO: maximal groesse? */ #define BUFMAX 40 char *t = (char*) malloc(BUFMAX); + if(val == -2) { + new = _new_plain(O_MTWO); + } else if(val == -4) { + new = _new_plain(O_MFOUR); + } else if(val == -8) { + new = _new_plain(O_MEIGHT); + } else if(val == -1) { + new = _new_plain(O_MONE); + } else { + new = _new_plain(O_NUM); + } #ifdef DDTREE fprintf(stderr, "new_number: %i\n", val); diff --git a/codea/tree.h b/codea/tree.h index f33d1e0..f88851f 100644 --- a/codea/tree.h +++ b/codea/tree.h @@ -20,7 +20,11 @@ enum { O_ID, O_ADD, O_NUM, - O_FIELD + O_FIELD, + O_MTWO, + O_MFOUR, + O_MEIGHT, + O_MONE }; static char *o_names[] = { @@ -35,7 +39,11 @@ static char *o_names[] = { "O_ID", "O_ADD", "O_NUM", - "O_FIELD" + "O_FIELD", + "O_MTWO", + "O_MFOUR", + "O_MEIGHT", + "O_MONE" }; struct treenode { -- 2.25.1