compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

commit a07ff79827100b4ac96a751fbb76844775f60b49
parent f582e11d25a13c4c16b59c69405488654ae26eea
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri,  3 Dec 2021 00:46:46 -0800

compiler2: codegen

- naive relop generation (immediately capture a
  bool value in a register)
- quiet tracing messages
- correctly handle enums

Diffstat:
Msrc/codegen-risc5-simple.c | 66++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 44 insertions(+), 22 deletions(-)

diff --git a/src/codegen-risc5-simple.c b/src/codegen-risc5-simple.c @@ -146,7 +146,7 @@ u32 mul_op_to_ins_tab[7] = { MUL, DIV, MOD, AND, ANN, LSL, ASR }; // ------------------------------------------------------------------ -void gen_branch_back(u32 op, u32 addr) { +void gen_branch(u32 op, u32 addr) { emit_bi(op, (addr - ctx.pc - 4) >> 2); } @@ -157,7 +157,7 @@ void gen_branch_fwd(u32 op, Fixup list) { void gen_branch_sym(u32 op, Symbol sym) { if (sym->flags & SYM_IS_PLACED) { - gen_branch_back(op, sym->value); + gen_branch(op, sym->value); } else { fixup_add_sym(sym, ctx.pc); emit_bi(op, 0); @@ -203,6 +203,9 @@ u32 loop_continue = 0; Fixup loop_exit = nil; Fixup func_exit = nil; +void gen_trace(str msg) { +} + void gen_block(Ast node); u32 gen_expr(Ast node); @@ -222,7 +225,7 @@ void sym_get_loc(Symbol sym, u32* base, i32* offset) { } u32 gen_assign(Symbol sym, Ast expr) { - fprintf(stderr,"gen_assign()\n"); + gen_trace("gen_assign()\n"); u32 base; i32 offset; sym_get_loc(sym, &base, &offset); @@ -233,17 +236,16 @@ u32 gen_assign(Symbol sym, Ast expr) { } u32 gen_call(Ast node) { - fprintf(stderr,"gen_call()\n"); + gen_trace("gen_call()\n"); Symbol sym = node->child->sym; Ast arg = node->child->next; if (sym->flags & SYM_IS_BUILTIN) { - fprintf(stderr, "BUILTIN!\n"); u32 r = gen_expr(arg); emit_movi(R11, 0xffff0000); emit_mem(STW, r, R11, 0x100 + sym->value * 4); put_reg(r); - } else { + } else if (sym->type->len > 0) { emit_opi(SUB, SP, SP, 4 * sym->type->len); u32 n = 0; while (arg != nil) { @@ -255,6 +257,9 @@ u32 gen_call(Ast node) { } gen_branch_sym(AL|L, sym); emit_opi(ADD, SP, SP, 4 * sym->type->len); + } else { + // no args + gen_branch_sym(AL|L, sym); } // return is in r0, if it exists return 0; @@ -265,7 +270,7 @@ u32 gen_lexpr(Ast node) { } u32 gen_binop(Ast node, u32 op) { - fprintf(stderr, "gen_binop()\n"); + gen_trace( "gen_binop()\n"); u32 left = gen_expr(node->child); u32 right = gen_expr(node->child->next); u32 res = get_reg_tmp(); @@ -275,18 +280,37 @@ u32 gen_binop(Ast node, u32 op) { return res; } +u32 gen_relop(Ast node, u32 cc) { + gen_trace("gen_relop()\n"); + u32 left = gen_expr(node->child); + u32 right = gen_expr(node->child->next); + u32 res = get_reg_tmp(); + emit_movi(res, 1); + emit_op(SUB, left, left, right); + gen_branch(cc, ctx.pc + 8); + emit_movi(res, 0); + put_reg(left); + put_reg(right); + return res; +} + u32 gen_expr(Ast node) { - fprintf(stderr,"gen_expr()\n"); + gen_trace("gen_expr()\n"); if (node->kind == AST_U32) { u32 r = get_reg_tmp(); emit_movi(r, node->ival); return r; } else if (node->kind == AST_NAME) { - u32 base; - i32 offset; - sym_get_loc(node->sym, &base, &offset); u32 r = get_reg_tmp(); - emit_mem(LDW, r, base, offset); + // XXX type checking here or before + if (node->sym->kind == SYM_CONST) { + emit_movi(r, node->sym->value); + } else { + u32 base; + i32 offset; + sym_get_loc(node->sym, &base, &offset); + emit_mem(LDW, r, base, offset); + } return r; } else if (node->kind == AST_BINOP) { u32 op = node->ival; @@ -296,13 +320,11 @@ u32 gen_expr(Ast node) { } return gen_assign(node->child->sym, node->child->next); } else if ((op & tcMASK) == tcRELOP) { - error("sorry"); + return gen_relop(node, rel_op_to_cc_tab[op - tEQ]); } else if ((op & tcMASK) == tcADDOP) { - op = add_op_to_ins_tab[op - tPLUS]; - return gen_binop(node, op); + return gen_binop(node, add_op_to_ins_tab[op - tPLUS]); } else if ((op & tcMASK) == tcMULOP) { - op = mul_op_to_ins_tab[op - tSTAR]; - return gen_binop(node, op); + return gen_binop(node, mul_op_to_ins_tab[op - tSTAR]); } else { error("gen_expr cannot handle binop %s\n", tnames[op]); } @@ -366,7 +388,7 @@ void gen_if_else(Ast node) { } void gen_stmt(Ast node) { - fprintf(stderr,"gen_stmt()\n"); + gen_trace("gen_stmt()\n"); u32 kind = node->kind; if (kind == AST_EXPR) { u32 r = gen_expr(node->child); @@ -390,14 +412,14 @@ void gen_stmt(Ast node) { } else if (kind == AST_BREAK) { gen_branch_fwd(AL, loop_exit); } else if (kind == AST_CONTINUE) { - gen_branch_back(AL, loop_continue); + gen_branch(AL, loop_continue); } else { error("gen_stmt cannot handle %s\n", ast_kind[kind]); } } void gen_block(Ast node) { - fprintf(stderr,"gen_block()\n"); + gen_trace("gen_block()\n"); node = node->child; while (node != nil) { gen_stmt(node); @@ -427,7 +449,7 @@ void gen_block(Ast node) { // SP -> locn void gen_func(Ast node) { - fprintf(stderr,"gen_func()\n"); + gen_trace("gen_func()\n"); // local space plus saved lr and fp u32 x = node->sym->type->size + 8; @@ -464,7 +486,7 @@ void gen_func(Ast node) { } void gen_risc5_simple(Ast node) { - fprintf(stderr, "gen_risc5_simple()\n"); + gen_trace( "gen_risc5_simple()\n"); emit_movi(SB, 0); // placeholder SB load emit_bi(AL, 0); // placeholder branch to init