compiler

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

commit 59b31e0490f97b652d6c3ab315c2824c434dd968
parent e886a2fd04ee2edbef3e73e08ee5c321f6199251
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri, 17 Dec 2021 21:49:28 -0800

ir: introduce instruction property flags

- make checking for opcode "class" cheaper
- delect "alu", "branch", "cond branch", "label" "mem", etc

Diffstat:
MMakefile | 2+-
Msrc/codegen-ir.c | 32++++++++++++++++++++------------
Msrc/ir.h | 37++++++++++++++++++++++++++++---------
3 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/Makefile b/Makefile @@ -28,7 +28,7 @@ bin/cast: src/compiler2.c src/codegen-risc5-simple.c src/risc5dis.c out/risc5ins @mkdir -p bin $(CC) -o $@ $(CFLAGS) -Wno-unused-result -DC src/compiler2.c src/risc5dis.c -bin/cir: src/compiler2.c src/codegen-ir.c src/risc5dis.c out/risc5ins.h +bin/cir: src/compiler2.c src/codegen-ir.c src/risc5dis.c out/risc5ins.h src/ir.h @mkdir -p bin $(CC) -o $@ $(CFLAGS) -Wno-unused-result -DIR -DC src/compiler2.c src/risc5dis.c diff --git a/src/codegen-ir.c b/src/codegen-ir.c @@ -69,6 +69,10 @@ i32 label_next = 0; Inst label_idx[1024]; Inst _inst_make(u32 op, i32 a, i32 b, i32 c) { + // add opcode-specific property bitflags to allow + // for quick property testing + op |= ins_props[op & INS_OP_MASK]; + Inst ins = malloc(sizeof(InstRec)); ins->next = nil; ins->prev = nil; @@ -634,14 +638,13 @@ Inst gen_func(Ast node) { reg_next = REG_VIRT_0; label_next = 0; - inst_label_global(node->sym->name->text); + inst_label(label_get()); Inst first = ins_last_placed; // local space plus saved lr and fp u32 x = node->sym->type->size + 8; // generate prologue - inst_label(label_get()); #if 0 node->sym->value = ctx.pc; node->sym->flags |= SYM_IS_PLACED; @@ -673,16 +676,20 @@ Inst gen_func(Ast node) { void inst_disasm(FILE* fp, Inst ins); bool inst_is_label(Inst ins) { - return (ins->op & INS_OP_MASK) == INS_LABEL; + return ins->op & INF_IS_LABEL; } bool inst_is_uncond_branch(Inst ins) { - return (ins->op & INS_OP_MASK) == INS_B; + return ins->op & INF_IS_B_UC; } bool inst_is_cond_branch(Inst ins) { - u32 oc = ins->op & INS_OP_MASK; - return (oc >= INS_BEQ) && (oc <= INS_BGE); + return ins->op & INF_IS_B_CC; +} +bool inst_is_branch(Inst ins) { + return ins->op & INF_IS_B; +} +bool inst_is_return(Inst ins) { + return ins->op & INF_IS_RET; } - // dispose of an instruction // - removes from graph @@ -690,7 +697,7 @@ bool inst_is_cond_branch(Inst ins) { // - DOES NO HOUSEKEEPING for labels (remove at your own risk) Inst opt_inst_destroy(Inst ins) { u32 op = ins->op & INS_OP_MASK; - if ((op >= INS_B) && (op <= INS_BGE)) { + if (inst_is_branch(ins)) { Inst tgt = label_idx[ins->a]; // decrement inbound count on branch target tgt->c --; @@ -782,8 +789,9 @@ void opt_func(Ast node, Inst first, Inst last) { opt_func_label_cleanup(first, last); } -void dis_func(FILE* fp, Inst ins) { +void dis_func(FILE* fp, Inst ins, str name) { fprintf(stderr,"\n------------------\n"); + fprintf(stderr,"@%s:\n", name); while (ins != nil) { inst_disasm(stderr, ins); ins = ins->next; @@ -800,9 +808,9 @@ void gen_program(Ast node) { if (node->kind == AST_FUNC) { Inst first = gen_func(node); Inst last = ins_last_placed; - dis_func(stderr, first); - opt_func(node, first->next, last); - dis_func(stderr, first); + dis_func(stderr, first, node->sym->name->text); + opt_func(node, first, last); + dis_func(stderr, first, node->sym->name->text); } node = node->c2; } diff --git a/src/ir.h b/src/ir.h @@ -3,13 +3,24 @@ enum { // arg c is imm, for ALU and Bcc ops - INF_C_IMM = 0x080, + INF_C_IMM = 0x0100, // size flags for LD/ST ops - INF_SZ_U8 = 0x000, - INF_SZ_U16 = 0x100, - INF_SZ_U32 = 0x200, - INF_SZ_MASK = 0x300, + INF_SZ_U8 = 0x0000, + INF_SZ_U16 = 0x0040, + INF_SZ_U32 = 0x0080, + INF_SZ_MASK = 0x00C0, + + // property bits + INF_IS_B_UC = 0x0200, // is uncondition branch + INF_IS_B_CC = 0x0400, // is conditional branch + INF_IS_B = 0x0600, // is any kind of branch + INF_IS_RET = 0x0800, // is a return op + INF_IS_EOBB = 0x0E00, // is a branch or return (end of bb) + INF_IS_LABEL = 0x1000, // is a label (start of bb) + INF_IS_ALU = 0x2000, // add, sub, and, ... + INF_IS_MEM = 0x4000, // load or store + INF_IS_PHI = 0x8000, }; enum { @@ -28,13 +39,13 @@ enum { INS_OR, INS_XOR, - INS_PHI, - INS_MOV, // MOV Ra, Rc Ra = Rc INS_LD, // LDW Ra, Rb, Rc Ra = MEM[Rb + Rc] INS_ST, // STBI Ra, Rb, IMMc MEM[Rb + IMMc] = Ra + INS_PHI, + INS_LABEL, // La: INS_B, // B La @@ -51,13 +62,21 @@ enum { INS_COUNT, // total unique instructions - INS_OP_MASK = 0x7F, + INS_OP_MASK = 0x3F, +}; + +i32 ins_props[INS_COUNT] = { + INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, + INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, INF_IS_ALU, + 0, INF_IS_MEM, INF_IS_MEM, INF_IS_PHI, INF_IS_LABEL, + INF_IS_B_UC, INF_IS_B_CC, INF_IS_B_CC, INF_IS_B_CC, INF_IS_B_CC, INF_IS_B_CC, INF_IS_B_CC, + 0, INF_IS_RET, 0, }; str ins_name[INS_COUNT] = { "add", "sub", "mul", "udiv", "sdiv", "urem", "srem", "lsl", "lsr", "asr", "and", "or", "xor", - "phi", "mov", "ld", "st", "label", + "mov", "ld", "st", "phi", "label", "b", "beq", "bne", "blt", "ble", "bgt", "bge", "call", "ret", "dead", };