}
}
+void moveimm(long imm, char *dst)
+{
+ char buf[100];
+ sprintf(buf, "$%li", imm);
+ printf("\tmovq %s, %%%s\n", buf, dst);
+}
+
void ret(void)
{
printf("\tret\n");
%{
#define BFEHAX
+#define KIDR(A) bnode->kids[A]->reg
+#define KIDV(A) bnode->kids[A]->val
+#define BNR bnode->reg
+#define BNV bnode->val
+
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
%}
%start begin
-%term O_RET=1 O_NOT=2 O_SUB=3 O_MUL=4 O_OR=5 O_LESS=6 O_EQ=7 O_ID=8 O_ADD=9
+%term O_RET=1 O_NOT=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
%%
begin: ret # 0 # printf("// end\n");
-ret: O_RET(expr) # 1 # move(bnode->reg, "rax"); ret();
+ret: O_RET(expr) # 2 # move(BNR, "rax"); ret();
-expr: O_ID # 1 # if(bnode->param_index > -1) move(param_reg(bnode->param_index), bnode->reg);
-expr: O_SUB(expr,expr) # 1 # printf("\tsubq %%%s, %%%s\n", bnode->kids[0]->reg, bnode->kids[1]->reg);
-expr: O_ADD(expr,expr) # 1 # printf("\taddq %%%s, %%%s\n", bnode->kids[1]->reg, bnode->kids[0]->reg);
+expr: O_ID # 1 # if(bnode->param_index > -1) move(param_reg(bnode->param_index), BNR);
+expr: imm # 1 # moveimm(BNV, BNR);
-%%
+expr: O_SUB(expr,expr) # 1 # fprintf(stderr, "osub0\n"); printf("\tsubq %%%s, %%%s\n", KIDR(0), KIDR(1));
+expr: O_SUB(imm,expr) # 2 # fprintf(stderr, "osub1\n"); printf("\tsubq $%li, %%%s\n", KIDV(0), KIDR(1)); move(KIDR(1), BNR);
+expr: O_SUB(expr,imm) # 3 # fprintf(stderr, "osub2\n"); moveimm(KIDV(1), BNR); printf("\tsubq %%%s, %%%s\n", KIDR(0), BNR);
+
+expr: O_ADD(expr,expr) # 1 # printf("\taddq %%%s, %%%s\n", KIDR(1), KIDR(0));
+expr: O_ADD(imm,expr) # 1 # printf("\taddq $%li, %%%s\n", KIDV(1), KIDR(0)); move(KIDR(0), BNR);
+expr: O_ADD(expr,imm) # 1 # printf("\taddq $%li, %%%s\n", KIDV(0), KIDR(1)); move(KIDR(1), BNR);
+imm: O_ADD(imm,imm) # 0 # BNV = KIDV(0)+KIDV(1);
+imm: O_SUB(imm,imm) # 0 # BNV = KIDV(1)-KIDV(0);
+imm: O_NUM # 0 #
+
+%%
+
/* vim: filetype=c
*/
@end
@autoinh s
-@autosyn node
+@autosyn node imm
@attributes { char *name; } IDENT
@attributes { long val; } NUM
@attributes { struct symbol *f; int parms; } Parms
@attributes { struct symbol *f; } FeldID Structdef Program
@attributes { struct symbol *s; } Methoddef Statseq Exprs
-@attributes { struct symbol *s; struct treenode *node; } Expr Minusterm
-@attributes { struct symbol *s; struct treenode *node; } Lexpr Multerm Orterm Term Feld
+@attributes { struct symbol *s; struct treenode *node; short imm; } Expr Minusterm Term
+@attributes { struct symbol *s; struct treenode *node; } Lexpr Multerm Orterm Feld
@attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement
@traversal @postorder c
| Term Minusterm
@{
@i @Expr.node@ = new_node(O_SUB, @Minusterm.node@, @Term.node@);
-
- @reg {@Term.node@->reg = @Expr.node@->reg;
- @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip);
- fprintf(stderr, "2at-expr_: Term.node \"%s\", Minusterm.node \"%s\"\n", @Term.node@->reg, @Minusterm.node@->reg);
+ @i @Expr.imm@ = @Term.imm@ && @Minusterm.imm@;
+
+ @reg {
+ /* TODO */
+ if(@Minusterm.imm@) {
+ @Minusterm.node@->reg = @Expr.node@->reg;
+ @Term.node@->reg = next_reg(@Minusterm.node@->reg, @Expr.node@->skip);
+ @Minusterm.node@->skip = 1;
+ } else {
+ @Term.node@->reg = @Expr.node@->reg;
+ @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip);
}
+ }
@}
| Term Multerm
| Term '<' Term
@{
@i @Expr.node@ = TREENULL; fprintf(stderr, "w00t6\n");
+ /* das is bloedsinn atm */ @i @Expr.imm@ = @Term.0.imm@ && @Term.1.imm@;
@}
| Term '=' Term
@{
@i @Expr.node@ = TREENULL; fprintf(stderr, "w00t7\n");
+ /* das is bloedsinn atm */ @i @Expr.imm@ = @Term.0.imm@ && @Term.1.imm@;
@}
;
'-' Term Minusterm
@{
@i @Minusterm.node@ = new_node(O_ADD, @Minusterm.1.node@, @Term.node@);
+ @i @Minusterm.imm@ = @Term.imm@ && @Minusterm.1.imm@;
- @reg { @Minusterm.1.node@->reg = @Minusterm.node@->reg;
+ @reg {
+ @Minusterm.1.node@->reg = @Minusterm.node@->reg;
@Term.node@->reg = next_reg(@Minusterm.1.node@->reg, @Minusterm.node@->skip);
- fprintf(stderr, "0at-minusterm_: Minusterm.node \"%s\", Minusterm.1.node \"%s\", Term.node \"%s\"\n", @Minusterm.node@->reg, @Minusterm.1.node@->reg, @Term.node@->reg);
- }
+ }
@}
| '-' Term
@{
- @reg @Term.node@->reg = @Minusterm.node@->reg; {
- fprintf(stderr, "1at-minusterm_: Minusterm.node \"%s\", Term.node \"%s\"\n", @Minusterm.node@->reg, @Term.node@->reg);
- }
+ @reg @Term.node@->reg = @Minusterm.node@->reg;
@}
;
| NUM
@{
- @i @Term.node@ = TREENULL;
+ @i @Term.node@ = new_number(@NUM.val@);
+ @i @Term.imm@ = 1;
+
@reg fprintf(stderr, "wtf2\n");
@}
| '-' NUM
@{
- @i @Term.node@ = TREENULL;
+ @i @Term.node@ = new_number(-1 * (@NUM.val@));
+ @i @Term.imm@ = 1;
+
@reg fprintf(stderr, "wtf3\n");
@}
| THIS
@{
@i @Term.node@ = new_node(O_ID, TREENULL, TREENULL); @Term.node@->param_index = 0;
+ @i @Term.imm@ = 0;
+
@reg fprintf(stderr, "wtf4\n");
@}
@Term.node@->param_index = tmp->param_index;
}
}
+ @i @Term.imm@ = 0;
+
@reg fprintf(stderr, "wtf5\n");
@}
| Feld
@{
@i @Term.node@ = TREENULL;
+ @i @Term.imm@ = 0;
+
@reg fprintf(stderr, "wtf6\n");
@}
| IDENT '(' Exprs ')'
@{
@i @Term.node@ = TREENULL;
+ @i @Term.imm@ = 0;
+
@reg fprintf(stderr, "wtf7\n");
@}
| Term '.' IDENT '(' Exprs ')'
@{
@i @Term.node@ = TREENULL;
+ @i @Term.imm@ = 0;
+
@reg fprintf(stderr, "wtf8\n");
@}
#define DDTREE
#endif
-struct treenode *new_node(int op, struct treenode *l, struct treenode *r)
+static struct treenode *_new_plain(int op)
{
struct treenode *new = (TREECAST) malloc(TREESIZE);
+ new->op = op;
+ new->kids[0] = new->kids[1] = TREENULL;
+ new->parent = TREENULL;
+ new->label = NULL;
+ new->name = new->reg = (char *)NULL;
+ new->val = new->skip = 0;
+ new->param_index = -1;
+ return new;
+}
+
+struct treenode *new_node(int op, struct treenode *l, struct treenode *r)
+{
+ struct treenode *new = _new_plain(op);
#ifdef DDTREE
fprintf(stderr, "new_node: %i (%s)\n", op, o_names[op]);
new->kids[0] = l;
new->kids[1] = r;
- new->op = op;
new->name = (char *)NULL;
return new;
}
+struct treenode *new_number(long val)
+{
+ struct treenode *new = _new_plain(O_NUM);
+#ifdef DDTREE
+ fprintf(stderr, "new_number: %i\n", val);
+#endif
+ new->val = val;
+ return new;
+}
+
O_LESS,
O_EQ,
O_ID,
- O_ADD
+ O_ADD,
+ O_NUM
};
static char *o_names[] = {
"O_LESS",
"O_EQ",
"O_ID",
- "O_ADD"
+ "O_ADD",
+ "O_NUM"
};
struct treenode {
#define PANIC printf
struct treenode *new_node(int op, struct treenode *l, struct treenode *r);
+struct treenode *new_number(long val);
#endif