codea: optimierungen mit lea
authorBernhard Urban <lewurm@gmail.com>
Mon, 17 May 2010 15:16:35 +0000 (17:16 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 17 May 2010 15:16:35 +0000 (17:16 +0200)
codea/code.bfe
codea/parser.y
codea/tree.c
codea/tree.h

index 6ae2bfb63f0978cd1245a60acd8b7c1d9952fb21..d0229766f75639c796d5d08533b39b0491f8ef4b 100644 (file)
@@ -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 #
 
 %%
 
index b5a7e7d8fc7b0f5617be90720381076d6bb14012..b3b3726c781697c1d42ed2b62065141651ae78e5 100644 (file)
@@ -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@);
+                       }
                }
          @}
 
index 7e7c715fab3f69dce60e446701a4b591147ccb7b..098f975e14bb3442c29cc0951becc55d2c6dcfce 100644 (file)
@@ -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);
index f33d1e06edbc84d9afec504ebc1ddcf041c38a5a..f88851f0d32076977f87bf17d6af5e6a0d932a53 100644 (file)
@@ -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 {