#define KID_VAL(A) bnode->kids[A]->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); }
#include <stdio.h>
void gen_e_imm(struct treenode *bnode, char *instr)
{
- printf("\t%s $%li, %%%s\n", instr, KID_VAL(1), KID_REG(0));
- move(KID_REG(0), BN_REG);
+ /* man kann sich ein move der konstante bei der multiplikation ersparen */
+ if(strcmp(instr, "imulq") == 0) {
+ printf("\timulq $%li, %%%s, %%%s\n", KID_VAL(1), KID_REG(0), BN_REG);
+ } else {
+ printf("\t%s $%li, %%%s\n", instr, KID_VAL(1), KID_REG(0));
+ move(KID_REG(0), BN_REG);
+ }
}
void gen_imm_eno(struct treenode *bnode, char *instr)
{
- moveimm(KID_VAL(0), BN_REG);
KIDREG2PARM(1);
- printf("\tsubq %%%s, %%%s\n", KID_REG(1), BN_REG);
+ /* man kann sich ein move der konstante bei der multiplikation ersparen */
+ if(strcmp(instr, "imulq") == 0) {
+ printf("\timulq $%li, %%%s, %%%s\n", KID_VAL(0), KID_REG(1), BN_REG);
+ } else {
+ moveimm(KID_VAL(0), BN_REG);
+ printf("\t%s %%%s, %%%s\n", instr, KID_REG(1), BN_REG);
+ }
}
%}
expr: O_SUB(expr,exprno) # 1 # gen_e_eno(bnode, "subq");
expr: O_SUB(expr,imm) # 2 # gen_e_imm(bnode, "subq");
-expr: O_SUB(imm,exprno) # 3 # gen_imm_eno(bnode, "subq");
+expr: O_SUB(imm,exprno) # 2 # gen_imm_eno(bnode, "subq");
expr: O_ADD(expr,exprno) # 1 # gen_e_eno(bnode, "addq");
expr: O_ADD(imm,expr) # 2 # gen_e_imm(bnode, "addq");
expr: O_MUL(expr,exprno) # 1 # gen_e_eno(bnode, "imulq");
-expr: O_MUL(expr,imm) # 2 # gen_e_imm(bnode, "imulq");
+expr: O_MUL(expr,imm) # 1 # gen_e_imm(bnode, "imulq");
+expr: O_MUL(imm,exprno) # 1 # gen_imm_eno(bnode, "imulq");
expr: O_OR(expr,exprno) # 1 # gen_e_eno(bnode, "orq");
expr: O_OR(expr,imm) # 2 # gen_e_imm(bnode, "orq");