From beb6d5bddecc4d234022474ace96001edc2a50fa Mon Sep 17 00:00:00 2001 From: mike lowis Date: Sun, 25 Apr 2021 23:36:17 -0400 Subject: [PATCH] added a single case of code generation for binary operators using variables --- cerise/build.sh | 2 +- cerise/cerise.h | 48 ++++--- cerise/codegen.c | 276 +++++++++++++++++++++-------------------- cerise/oberon0/OSG.Mod | 220 +++++++++++++++++++++++++------- cerise/parser.c | 35 ++++-- cerise/tests/Module.m | 15 ++- cerise/tests/Module.s | 27 +++- 7 files changed, 405 insertions(+), 218 deletions(-) diff --git a/cerise/build.sh b/cerise/build.sh index e0a3c86..65e385f 100755 --- a/cerise/build.sh +++ b/cerise/build.sh @@ -1,8 +1,8 @@ #!/bin/sh ctags -R & cc -g -D CERISE_TESTS -Wall -Wextra --std=c99 -o cerisec-test *.c \ - && ./cerisec-test \ && cc -g -Wall -Wextra --std=c99 -o cerisec *.c \ + && ./cerisec-test \ && ./cerisec tests/Module.m | tee tests/Module.s \ && cc -o Module tests/Module.s rm Module diff --git a/cerise/cerise.h b/cerise/cerise.h index d435505..c784aaf 100644 --- a/cerise/cerise.h +++ b/cerise/cerise.h @@ -101,10 +101,11 @@ typedef struct Symbol { enum{ SYM_CONST, SYM_VAR, SYM_TYPE, SYM_PROC } class; - int export; char* name; Type* type; ImmValue imm; + int export : 1; + int global : 1; } Symbol; typedef struct Module { @@ -116,7 +117,7 @@ typedef struct Module { typedef struct { enum { - ITEM_CONST, ITEM_VAR + ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG } mode; Type* type; int reg; @@ -130,8 +131,30 @@ typedef struct { Module* imports; Symbol* scope; char* name; + long curr_reg; } Parser; +static inline void item_dump(Item* a) +{ + printf("// Item M:%d R:%d ", a->mode, a->reg); + if (a->mode == ITEM_MVAR) + { + printf(" %s", a->imm.s); + } + else + { + if (a->type->form == FORM_INT) + { + printf("%lld", a->imm.i); + } + else if (a->type->form == FORM_REAL) + { + printf("%f", a->imm.f); + } + } + puts(""); +} + void lexfile(Parser* ctx, char* path); void lex(Parser* ctx); void lexprintpos(Parser* p, FILE* file, Tok* tok); @@ -139,19 +162,8 @@ void compile(char* fname); /* Code Generation *****************************************************************************/ -/* opcodes */ -enum AsmOp { - /* Assembly Operations */ - OP_LOAD = 0, OP_STORE, OP_MOVE, - OP_CMP, OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, - OP_EQ, OP_NEQ, OP_LT, OP_GT, OP_LTEQ, OP_GTEQ, - - OP_CALL, OP_RET, -}; - enum Regs { - IMM = 0, - RAX, RBX, RCX, RDX, RBP, RSP, RSI, RDI, + NOREG, RBX, RCX, RDX, RBP, RSP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15, }; @@ -165,7 +177,7 @@ void codegen_imports(Parser* p); void codegen_global(Parser* p, char* name, Type* type); void codegen_main(Parser* p); void codegen_startproc(Parser* p, char* name, long long localsz); -void codegen_endproc(void); -void codegen_unop(int op, Item* a); -void codegen_binop(int op, Item* a, Item* b); -void codegen_store(Item* a, Item* b); +void codegen_endproc(Parser* p); +void codegen_unop(Parser* p, int op, Item* a); +void codegen_binop(Parser* p, int op, Item* a, Item* b); +void codegen_store(Parser* p, Item* a, Item* b); diff --git a/cerise/codegen.c b/cerise/codegen.c index 012eb18..c3b1636 100644 --- a/cerise/codegen.c +++ b/cerise/codegen.c @@ -2,6 +2,12 @@ #include #include +#define MAX_REG 15 + +/* Register Usage + +*/ + Type BoolType = { .form = FORM_BOOL, .size = sizeof(bool) @@ -26,7 +32,7 @@ void codegen_setint(Item* item, Type* type, long long val) { item->mode = ITEM_CONST; item->type = type; - item->reg = IMM; + item->reg = NOREG; item->imm.i = val; } @@ -34,7 +40,7 @@ void codegen_setreal(Item* item, double val) { item->mode = ITEM_CONST; item->type = &RealType; - item->reg = IMM; + item->reg = NOREG; item->imm.f = val; } @@ -42,7 +48,7 @@ void codegen_setstr(Item* item, char* val) { item->mode = ITEM_CONST; item->type = &StringType; - item->reg = IMM; + item->reg = NOREG; item->imm.s = val; } @@ -152,8 +158,9 @@ static void const_binop(int op, Item* a, Item* b) } } -static void const_unop(int op, Item* a) +static void const_unop(Parser* p, int op, Item* a) { + (void)p; if (a->type->form == FORM_INT) { switch (op) @@ -186,6 +193,88 @@ static void const_unop(int op, Item* a) } } +static char* regname(int reg) +{ + static char* names[] = { + "%noreg", // invalid register + "%rdi", // 1st argument + "%rsi", // 2nd argument + "%rdx", // 3rd argument + "%rcx", // 4th argument + "%r8", // 5th argument + "%r9", // 6th argument + "%rbx", // temp register + "%r10", // temp register + "%r11", // temp register + "%r12", // callee saved register + "%r13", // callee saved register + "%r14", // callee saved register + "%r15", // callee saved register + "%rax", // return value + }; + return names[reg]; +} + +static char* curr_regname(Parser* p) +{ + return regname(p->curr_reg); +} + +static void next_reg(Parser* p) +{ + if (p->curr_reg < MAX_REG) + { + p->curr_reg++; + } + else + { + assert(!"register stack overflow"); + } +} + +static void load_var(Parser* p, Item* item) +{ + (void)p; + switch (item->mode) + { + case ITEM_CONST: + puts("BAR"); + /* TODO: range check the constant */ + // emit instruction + item->reg = p->curr_reg; + + printf("movq %s, $%lld\n", curr_regname(p), item->imm.i); + item->reg = p->curr_reg; + next_reg(p); + break; + + case ITEM_VAR: + break; + + case ITEM_MVAR: +// puts("MVAR"); +// printf("movq %s, $%lld\n", curr_regname(p), item->imm.i); + +// item_dump(item); + + + printf(" movq %s_%s(%%rip), %s\n", + p->name, + item->imm.s, + curr_regname(p) + ); +// b->imm.i, p->name, a->imm.s); + + item->reg = p->curr_reg; + next_reg(p); + break; + + case ITEM_REG: + /* nothing to do */ + break; + } +} + void codegen_imports(Parser* p) { for (Module* m = p->imports; m; m = m->next) @@ -238,20 +327,22 @@ void codegen_startproc(Parser* p, char* name, long long localsz) { printf(" movq %%rsp, %%rbp\n\n"); } + p->curr_reg = 1; } -void codegen_endproc(void) +void codegen_endproc(Parser* p) { + (void)p; puts(""); printf(" pop %%rbp\n"); printf(" ret\n\n"); } -void codegen_unop(int op, Item* a) +void codegen_unop(Parser* p, int op, Item* a) { if (a->mode == ITEM_CONST) { - const_unop(op, a); + const_unop(p, op, a); } else { @@ -259,149 +350,62 @@ void codegen_unop(int op, Item* a) } } -void codegen_binop(int op, Item* a, Item* b) +static void imm_binop(Parser* p, int op, Item* a, Item* b) +{ + if (a->type->form == FORM_INT || a->type->form == FORM_BOOL) + { + switch (op) + { + case '+': + printf(" addq $%lld, %s\n", b->imm.i, regname(a->reg)); + break; + + default: + assert(!"not implemented"); + break; + } + } + else + { + assert(!"not implemented"); + } +} + +void codegen_binop(Parser* p, int op, Item* a, Item* b) { if (items_const(a, b)) { const_binop(op, a, b); } + else if (b->mode == ITEM_CONST) + { + load_var(p, a); + imm_binop(p, op, a, b); + } else { - assert(!"not supported"); + load_var(p, a); + load_var(p, b); + // emit instruction + // p->topreg--; + // a->reg = p->topreg-1; } } -/* - PROCEDURE GetSB; - BEGIN - IF curSB = 1 THEN - Put2(Ldw, SB, 0, pc-fixorgD); - fixorgD := pc-1; - curSB := 0 - END - END GetSB; - - PROCEDURE load(VAR x: Item); - BEGIN - IF x.mode # Reg THEN - IF x.mode = Var THEN - IF x.r > 0 THEN (*local*) - Put2(Ldw, RH, SP, x.a) - ELSE - GetSB; - Put2(Ldw, RH, SB, x.a) - END ; - x.r := RH; - incR - ELSIF x.mode = Par THEN - Put2(Ldw, RH, x.r, x.a); - Put2(Ldw, RH, RH, 0); - x.r := RH; - incR - ELSIF x.mode = Const THEN - IF (x.a >= 10000H) OR (x.a < -10000H) THEN - OSS.Mark("const too large") - END ; - Put1(Mov, RH, 0, x.a); - x.r := RH; - incR - ELSIF x.mode = RegI THEN - Put2(Ldw, x.r, x.r, x.a) - ELSIF x.mode = Cond THEN - Put3(2, negated(x.r), 2); - FixLink(x.b); - Put1(Mov, RH, 0, 1); - Put3(2, 7, 1); - FixLink(x.a); - Put1(Mov, RH, 0, 0); - x.r := RH; - incR - END ; - x.mode := Reg - END - END load; - - PROCEDURE Store*(VAR x, y: Item); (* x := y *) - BEGIN - load(y); - IF x.mode = Var THEN - IF x.r > 0 THEN (*local*) - Put2(Stw, y.r, SP, x.a) - ELSE - GetSB; - Put2(Stw, y.r, SB, x.a) - END - ELSIF x.mode = Par THEN - Put2(Ldw, RH, SP, x.a); - Put2(Stw, y.r, RH, x.b) - ELSIF x.mode = RegI THEN - Put2(Stw, y.r, x.r, x.a); - DEC(RH) - ELSE - OSS.Mark("illegal assignment") - END ; - DEC(RH) - END Store; - -*/ - -void codegen_store(Item* a, Item* b) +void codegen_store(Parser* p, Item* a, Item* b) { - if (a->mode == ITEM_VAR && b->reg == IMM) + if (a->mode == ITEM_MVAR && b->reg == NOREG) + { + printf(" movq $%lld, %s_%s(%%rip)\n", + b->imm.i, p->name, a->imm.s); + } + else if (a->mode == ITEM_MVAR) { - printf(" movq $%lld, %s(%%rip)\n", b->imm.i, a->imm.s); + printf(" movq %s, %s_%s(%%rip)\n", + regname(b->reg), p->name, a->imm.s); } else { - assert(!"bad store op"); +// assert(!"bad store op"); } } - - -/* - -add %r10,%r11 // add r10 and r11, put result in r11 -add $5,%r10 // add 5 to r10, put result in r10 -call label // call a subroutine / function / procedure -cmp %r10,%r11 // compare register r10 with register r11. The comparison sets flags in the processor status register which affect conditional jumps. -cmp $99,%r11 // compare the number 99 with register r11. The comparison sets flags in the processor status register which affect conditional jumps. -div %r10 // divide rax by the given register (r10), places quotient into rax and remainder into rdx (rdx must be zero before this instruction) -inc %r10 // increment r10 -jmp label // jump to label -je label // jump to label if equal -jne label // jump to label if not equal -jl label // jump to label if less -jg label // jump to label if greater -mov %r10,%r11 // move data from r10 to r11 -mov $99,%r10 // put the immediate value 99 into r10 -mov %r10,(%r11) // move data from r10 to address pointed to by r11 -mov (%r10),%r11 // move data from address pointed to by r10 to r10 -mul %r10 // multiplies rax by r10, places result in rax and overflow in rdx -push %r10 // push r10 onto the stack -pop %r10 // pop r10 off the stack -ret // routine from subroutine (counterpart to call) -syscall // invoke a syscall (in 32-bit mode, use "int $0x80" instead) - -*/ - -//static void emit_op0(AsmOp op) -//{ -//} -// -//static void emit_opreg1(AsmOp op, long long reg) -//{ -//} -// -//static void emit_opimmi(AsmOp op, long long imm) -//{ -//} -// -//static void emit_opimmf(AsmOp op, double imm) -//{ -//} -// -//static void emit_opreg2(AsmOp op, int rega, int regb) -//{ -//} - - diff --git a/cerise/oberon0/OSG.Mod b/cerise/oberon0/OSG.Mod index 9e4b750..bd64f26 100644 --- a/cerise/oberon0/OSG.Mod +++ b/cerise/oberon0/OSG.Mod @@ -73,14 +73,20 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) PROCEDURE incR; BEGIN - IF RH < SB THEN INC(RH) ELSE OSS.Mark("register stack overflow") END + IF RH < SB THEN + INC(RH) + ELSE + OSS.Mark("register stack overflow") + END END incR; PROCEDURE CheckRegs*; BEGIN IF RH # 0 THEN - (* Texts.WriteString(W, "RegStack!"); Texts.WriteInt(W, R, 4); - Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) *) + (* Texts.WriteString(W, "RegStack!"); + Texts.WriteInt(W, R, 4); + Texts.WriteLn(W); + Texts.Append(Oberon.Log, W.buf) *) OSS.Mark("Reg Stack"); RH := 0 END END CheckRegs; @@ -118,24 +124,54 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) PROCEDURE GetSB; BEGIN - IF curSB = 1 THEN Put2(Ldw, SB, 0, pc-fixorgD); fixorgD := pc-1; curSB := 0 END + IF curSB = 1 THEN + Put2(Ldw, SB, 0, pc-fixorgD); + fixorgD := pc-1; + curSB := 0 + END END GetSB; PROCEDURE load(VAR x: Item); BEGIN IF x.mode # Reg THEN + IF x.mode = Var THEN - IF x.r > 0 THEN (*local*) Put2(Ldw, RH, SP, x.a) ELSE GetSB; Put2(Ldw, RH, SB, x.a) END ; - x.r := RH; incR - ELSIF x.mode = Par THEN Put2(Ldw, RH, x.r, x.a); Put2(Ldw, RH, RH, 0); x.r := RH; incR + IF x.r > 0 THEN (*local*) + Put2(Ldw, RH, SP, x.a) + ELSE + GetSB; + Put2(Ldw, RH, SB, x.a) + END ; + x.r := RH; + incR + + ELSIF x.mode = Par THEN + Put2(Ldw, RH, x.r, x.a); + Put2(Ldw, RH, RH, 0); + x.r := RH; + incR + ELSIF x.mode = Const THEN - IF (x.a >= 10000H) OR (x.a < -10000H) THEN OSS.Mark("const too large") END ; - Put1(Mov, RH, 0, x.a); x.r := RH; incR - ELSIF x.mode = RegI THEN Put2(Ldw, x.r, x.r, x.a) + IF (x.a >= 10000H) OR (x.a < -10000H) THEN + OSS.Mark("const too large") + END ; + + Put1(Mov, RH, 0, x.a); + x.r := RH; + incR + + ELSIF x.mode = RegI THEN + Put2(Ldw, x.r, x.r, x.a) + ELSIF x.mode = Cond THEN Put3(2, negated(x.r), 2); - FixLink(x.b); Put1(Mov, RH, 0, 1); Put3(2, 7, 1); - FixLink(x.a); Put1(Mov, RH, 0, 0); x.r := RH; incR + FixLink(x.b); + Put1(Mov, RH, 0, 1); + Put3(2, 7, 1); + FixLink(x.a); + Put1(Mov, RH, 0, 0); + x.r := RH; + incR END ; x.mode := Reg END @@ -277,27 +313,62 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) PROCEDURE AddOp*(op: LONGINT; VAR x, y: Item); (* x := x +- y *) BEGIN IF op = OSS.plus THEN - IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a + y.a - ELSIF y.mode = Const THEN load(x); - IF y.a # 0 THEN Put1(Add, x.r, x.r, y.a) END - ELSE load(x); load(y); Put0(Add, RH-2, x.r, y.r); DEC(RH); x.r := RH-1 + IF (x.mode = Const) & (y.mode = Const) THEN + x.a := x.a + y.a + + ELSIF y.mode = Const THEN + load(x); + IF y.a # 0 THEN + Put1(Add, x.r, x.r, y.a) + END + + ELSE + load(x); + load(y); + Put0(Add, RH-2, x.r, y.r); + DEC(RH); + x.r := RH-1 END + ELSE (*op = OSS.minus*) - IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a - y.a - ELSIF y.mode = Const THEN load(x); - IF y.a # 0 THEN Put1(Sub, x.r, x.r, y.a) END - ELSE load(x); load(y); Put0(Sub, RH-2, x.r, y.r); DEC(RH); x.r := RH-1 + IF (x.mode = Const) & (y.mode = Const) THEN + x.a := x.a - y.a + ELSIF y.mode = Const THEN + load(x); + IF y.a # 0 THEN + Put1(Sub, x.r, x.r, y.a) + END + ELSE + load(x); + load(y); + Put0(Sub, RH-2, x.r, y.r); + DEC(RH); + x.r := RH-1 END END END AddOp; PROCEDURE MulOp*(VAR x, y: Item); (* x := x * y *) BEGIN - IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a * y.a - ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(Lsl, x.r, x.r, 1) - ELSIF y.mode = Const THEN load(x); Put1(Mul, x.r, x.r, y.a) - ELSIF x.mode = Const THEN load(y); Put1(Mul, y.r, y.r, x.a); x.mode := Reg; x.r := y.r - ELSE load(x); load(y); Put0(Mul, RH-2, x.r, y.r); DEC(RH); x.r := RH-1 + IF (x.mode = Const) & (y.mode = Const) THEN + x.a := x.a * y.a + ELSIF (y.mode = Const) & (y.a = 2) THEN + load(x); + Put1(Lsl, x.r, x.r, 1) + ELSIF y.mode = Const THEN + load(x); + Put1(Mul, x.r, x.r, y.a) + ELSIF x.mode = Const THEN + load(y); + Put1(Mul, y.r, y.r, x.a); + x.mode := Reg; + x.r := y.r + ELSE + load(x); + load(y); + Put0(Mul, RH-2, x.r, y.r); + DEC(RH); + x.r := RH-1 END END MulOp; @@ -305,27 +376,68 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) BEGIN IF op = OSS.div THEN IF (x.mode = Const) & (y.mode = Const) THEN - IF y.a > 0 THEN x.a := x.a DIV y.a ELSE OSS.Mark("bad divisor") END - ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(Asr, x.r, x.r, 1) + IF y.a > 0 THEN + x.a := x.a DIV y.a + ELSE + OSS.Mark("bad divisor") + END + ELSIF (y.mode = Const) & (y.a = 2) THEN + load(x); + Put1(Asr, x.r, x.r, 1) ELSIF y.mode = Const THEN - IF y.a > 0 THEN load(x); Put1(Div, x.r, x.r, y.a) ELSE OSS.Mark("bad divisor") END - ELSE load(y); load(x); Put0(Div, RH-2, x.r, y.r); DEC(RH); x.r := RH-1 + IF y.a > 0 THEN + load(x); + Put1(Div, x.r, x.r, y.a) + ELSE + OSS.Mark("bad divisor") + END + ELSE + load(y); + load(x); + Put0(Div, RH-2, x.r, y.r); + DEC(RH); + x.r := RH-1 END ELSE (*op = OSS.mod*) IF (x.mode = Const) & (y.mode = Const) THEN - IF y.a > 0 THEN x.a := x.a MOD y.a ELSE OSS.Mark("bad modulus") END - ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(And, x.r, x.r, 1) + IF y.a > 0 THEN + x.a := x.a MOD y.a + ELSE + OSS.Mark("bad modulus") + END + ELSIF (y.mode = Const) & (y.a = 2) THEN + load(x); + Put1(And, x.r, x.r, 1) ELSIF y.mode = Const THEN - IF y.a > 0 THEN load(x); Put1(Div, x.r, x.r, y.a); Put0(Mov+U, x.r, 0, 0) ELSE OSS.Mark("bad modulus") END - ELSE load(y); load(x); Put0(Div, RH-2, x.r, y.r); Put0(Mov+U, RH-2, 0, 0); DEC(RH); x.r := RH-1 + IF y.a > 0 THEN + load(x); + Put1(Div, x.r, x.r, y.a); + Put0(Mov+U, x.r, 0, 0) + ELSE + OSS.Mark("bad modulus") + END + ELSE + load(y); + load(x); + Put0(Div, RH-2, x.r, y.r); + Put0(Mov+U, RH-2, 0, 0); + DEC(RH); + x.r := RH-1 END END END DivOp; PROCEDURE Relation*(op: INTEGER; VAR x, y: Item); (* x := x ? y *) BEGIN - IF y.mode = Const THEN load(x); Put1(Cmp, x.r, x.r, y.a); DEC(RH) - ELSE load(x); load(y); Put0(Cmp, x.r, x.r, y.r); DEC(RH, 2) + IF y.mode = Const THEN + load(x); + Put1(Cmp, x.r, x.r, y.a); + DEC(RH) + ELSE + load(x); + load(y); + Put0(Cmp, x.r, x.r, y.r); + DEC(RH, 2) END ; SetCC(x, relmap[op - OSS.eql]) END Relation; @@ -334,10 +446,20 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) BEGIN load(y); IF x.mode = Var THEN - IF x.r > 0 THEN (*local*) Put2(Stw, y.r, SP, x.a) ELSE GetSB; Put2(Stw, y.r, SB, x.a) END - ELSIF x.mode = Par THEN Put2(Ldw, RH, SP, x.a); Put2(Stw, y.r, RH, x.b) - ELSIF x.mode = RegI THEN Put2(Stw, y.r, x.r, x.a); DEC(RH) - ELSE OSS.Mark("illegal assignment") + IF x.r > 0 THEN (*local*) + Put2(Stw, y.r, SP, x.a) + ELSE + GetSB; + Put2(Stw, y.r, SB, x.a) + END + ELSIF x.mode = Par THEN + Put2(Ldw, RH, SP, x.a); + Put2(Stw, y.r, RH, x.b) + ELSIF x.mode = RegI THEN + Put2(Stw, y.r, x.r, x.a); + DEC(RH) + ELSE + OSS.Mark("illegal assignment") END ; DEC(RH) END Store; @@ -346,20 +468,32 @@ MODULE OSG; (* NW 19.12.94 / 20.10.07 / OSGX 9.5.2017*) VAR xmd: INTEGER; BEGIN xmd := x.mode; loadAdr(x); IF (ftype.form = Array) & (ftype.len < 0) THEN (*open array*) - IF x.type.len >= 0 THEN Put1(Mov, RH, 0, x.type.len) ELSE Put2(Ldw, RH, SP, x.a+4) END ; + IF x.type.len >= 0 THEN + Put1(Mov, RH, 0, x.type.len) + ELSE + Put2(Ldw, RH, SP, x.a+4) + END ; incR ELSIF ftype.form = Record THEN - IF xmd = Par THEN Put2(Ldw, RH, SP, x.a+4); incR END + IF xmd = Par THEN + Put2(Ldw, RH, SP, x.a+4); + incR + END END END VarParam; PROCEDURE ValueParam*(VAR x: Item); - BEGIN load(x) + BEGIN + load(x) END ValueParam; PROCEDURE OpenArrayParam*(VAR x: Item); BEGIN loadAdr(x); - IF x.type.len >= 0 THEN Put1(Mov, RH, 0, x.type.len) ELSE Put2(Ldw, RH, SP, x.a+4) END ; + IF x.type.len >= 0 THEN + Put1(Mov, RH, 0, x.type.len) + ELSE + Put2(Ldw, RH, SP, x.a+4) + END ; incR END OpenArrayParam; diff --git a/cerise/parser.c b/cerise/parser.c index 34382af..a76adf4 100644 --- a/cerise/parser.c +++ b/cerise/parser.c @@ -164,7 +164,14 @@ static Symbol* symbol_get(Parser* p, int class, char* name) *****************************************************************************/ static void init_item(Item* item, Symbol* sym) { - item->mode = sym->class; + if (SYM_VAR == sym->class) + { + item->mode = (sym->global ? ITEM_MVAR : ITEM_VAR); + } + else + { + item->mode = ITEM_CONST; + } item->imm = sym->imm; item->type = sym->type; } @@ -279,6 +286,11 @@ RULE(qualident) char* name = expect_text(p, IDENT); Symbol* sym = symbol_get(p, -1, name); init_item(item, sym); + if (sym->class == SYM_VAR) + { + item->imm.s = sym->name; + } + // item->mode = sym->class; // item->type = sym->type; @@ -361,7 +373,7 @@ RULE(factor) consume(p); factor(p, item); check_bool(p, item); - codegen_unop(NOT, item); + codegen_unop(p, NOT, item); break; case IDENT: @@ -386,12 +398,12 @@ RULE(term) case '/': case '%': check_nums(p, item, &right); - codegen_binop(op, item, &right); + codegen_binop(p, op, item, &right); break; case AND: check_bools(p, item, &right); - codegen_binop(op, item, &right); + codegen_binop(p, op, item, &right); break; default: @@ -409,7 +421,7 @@ RULE(simple_expr) int op = consume(p); // OP term(p, item); check_num(p, item); - codegen_unop(op, item); + codegen_unop(p, op, item); } else { @@ -430,7 +442,7 @@ RULE(simple_expr) { check_nums(p, item, &right); } - codegen_binop(op, item, &right); + codegen_binop(p, op, item, &right); } } @@ -438,13 +450,14 @@ RULE(expression) { int ops[] = { EQ, NEQ, '<', LTEQ, '>', GTEQ, IS, 0 }; simple_expr(p, item); + item_dump(item); if (matches_oneof(p, ops)) { Item right = { 0 }; int op = consume(p); simple_expr(p, &right); check_nums(p, item, &right); - codegen_binop(op, item, &right); + codegen_binop(p, op, item, &right); } } @@ -464,6 +477,7 @@ RULE(var_decl) name = expect_text(p, IDENT); export = accept(p, '*'); sym = symbol_new(p, name, SYM_VAR, export); + sym->global = 1; nsyms++; if (!accept(p, ',')) @@ -585,7 +599,7 @@ RULE(statement_seq) expression(p, &right); check_types(p, item, &right); - codegen_store(item, &right); + codegen_store(p, item, &right); } else { @@ -677,7 +691,7 @@ RULE(module) statement_seq(p, item); expect(p, END); } - codegen_endproc(); + codegen_endproc(p); // char* ename = expect_text(p, IDENT); // if (strcmp(sname, ename)) @@ -717,7 +731,8 @@ void compile(char* fname) .path = fname, .fbeg = fcontents, .fpos = fcontents, - } + }, + .curr_reg = 0 }; module(p, &(Item){0}); codegen_main(p); diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 7699a0b..21b89db 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -1,6 +1,6 @@ module Module -#import +#import # A = Foo # B = Bar @@ -11,11 +11,14 @@ const var a : Bool b : Int + c : Int begin - a = true; - a = A; - b = 24; - b = B; -# c = a + b; + a = true; + a = A; + b = 24; + b = B; + c = b + 1; +# c = 1 + b; +# c = a + b; end diff --git a/cerise/tests/Module.s b/cerise/tests/Module.s index 50a2c52..1f9c331 100644 --- a/cerise/tests/Module.s +++ b/cerise/tests/Module.s @@ -1,3 +1,5 @@ +// Item M:0 R:0 +// Item M:0 R:0 42 .data Module_a: .zero 1 @@ -6,16 +8,33 @@ Module_a: Module_b: .zero 8 + .data +Module_c: + .zero 8 + .text .globl Module Module: pushq %rbp movq %rsp, %rbp - movq $1, a(%rip) - movq $1, a(%rip) - movq $24, b(%rip) - movq $42, b(%rip) +// Item M:0 R:0 + movq $1, Module_a(%rip) +// Item M:0 R:0 + movq $1, Module_a(%rip) +// Item M:0 R:0 24 + movq $24, Module_b(%rip) +// Item M:0 R:0 42 + movq $42, Module_b(%rip) + movq Module_b(%rip), %rdi + addq $1, %rdi +// Item M:2 R:1 b + movq %rdi, Module_c(%rip) +BAR +movq %rsi, $1 + movq Module_b(%rip), %rdx +// Item M:0 R:2 1 + movq %rsi, Module_c(%rip) pop %rbp ret -- 2.49.0