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:
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",
};