#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);
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
%%
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");
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 #
%%
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;
}
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);