From f36879c1d42e34d593dff204e26ecfb10eb6dfac Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 24 Jan 2018 22:46:14 +0100 Subject: Asm literals and hwi --- ir.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 15 deletions(-) (limited to 'ir.c') diff --git a/ir.c b/ir.c index e3a3171..4dca5b0 100644 --- a/ir.c +++ b/ir.c @@ -60,8 +60,15 @@ const char* condcode_show(enum condcode condcode) { } } -void ref_show(struct ref ref, char *dest) { +const char* ref_show(struct ref ref) { static const char *special[8] = {"A", "B", "C", "D", "X", "Y", "SP", "BP"}; + static char *buffer = NULL; + static int buffer_size = 0; + + if (buffer == NULL) { + buffer_size = 40; // enough for all non-name refs + buffer = malloc(buffer_size + 1); + } const char *suffix = NULL; if (ref.type == REF_MEM) { @@ -74,48 +81,70 @@ void ref_show(struct ref ref, char *dest) { switch (ref.type) { case REF_REG: if (ref.reg == REG_UNUSED) { - strcpy(dest, "<>"); + strcpy(buffer, "<>"); } else if (ref.reg < 0) { - strcpy(dest, special[-(ref.reg - REG_A)]); + strcpy(buffer, special[-(ref.reg - REG_A)]); } else { - sprintf(dest, "t%d", ref.reg); + sprintf(buffer, "t%d", ref.reg); } break; case REF_MEM: if (ref.reg == REG_UNUSED) { - sprintf(dest, "[0x%x%s]", ref.offset, suffix); + sprintf(buffer, "[0x%x%s]", ref.offset, suffix); } else if (ref.reg < 0) { if (ref.offset < 0) { - sprintf(dest, "[%s - %d%s]", special[-(ref.reg - REG_A)], -ref.offset, suffix); + sprintf(buffer, "[%s - %d%s]", special[-(ref.reg - REG_A)], -ref.offset, suffix); } else { - sprintf(dest, "[%s + %d%s]", special[-(ref.reg - REG_A)], ref.offset, suffix); + sprintf(buffer, "[%s + %d%s]", special[-(ref.reg - REG_A)], ref.offset, suffix); } } else { if (ref.offset < 0) { - sprintf(dest, "[t%d - %d%s]", ref.reg, -ref.offset, suffix); + sprintf(buffer, "[t%d - %d%s]", ref.reg, -ref.offset, suffix); } else { - sprintf(dest, "[t%d + %d%s]", ref.reg, ref.offset, suffix); + sprintf(buffer, "[t%d + %d%s]", ref.reg, ref.offset, suffix); } } break; case REF_IMM: - sprintf(dest, "%d", ref.imm); + sprintf(buffer, "%d", ref.imm); + break; + + case REF_VARNAME: { + int namelen = strlen(ref.name); + if (buffer_size < 1 + namelen) { + buffer_size = 1 + namelen; + buffer = realloc(buffer, 1 + namelen + 1); + } + buffer[0] = '@'; + memcpy(buffer + 1, ref.name, namelen + 1); break; + } default: assert(false); } + + return buffer; } static const char* ref_show_c(struct ref ref) { - static char cbuf[3][40]; + static char *cbuf[3] = {NULL, NULL, NULL}; + static int cbufsize[3] = {-1, -1, -1}; static int cbufi = 0; + const char *sbuf = ref_show(ref); + int len = strlen(sbuf); + if (cbufsize[cbufi] < len) { + cbufsize[cbufi] = len; + if (cbuf[cbufi]) cbuf[cbufi] = realloc(cbuf[cbufi], len + 1); + else cbuf[cbufi] = malloc(len + 1); + } + memcpy(cbuf[cbufi], sbuf, len + 1); + char *buf = cbuf[cbufi]; cbufi = (cbufi + 1) % 3; - ref_show(ref, buf); return buf; } @@ -141,6 +170,7 @@ void irins_print(struct irins *ins, FILE *f) { case INS_RETV: fprintf(f, "\tret %s\n", ref_show_c(ins->r1)); break; case INS_MOV: fprintf(f, "\t%s <- %s\n", ref_show_c(ins->r0), ref_show_c(ins->r1)); break; case INS_BRK: fprintf(f, "\tbrk\n"); break; + case INS_HWI: fprintf(f, "\thwi %s\n", ref_show_c(ins->r1)); break; default: assert(false); } } @@ -245,6 +275,7 @@ void irins_which_refs(const struct irins *ins, bool have[3]) { case INS_RETV: have[1] = true; break; case INS_MOV: have[0] = true; have[1] = true; break; case INS_BRK: break; + case INS_HWI: have[1] = true; break; default: assert(false); } } @@ -257,15 +288,19 @@ const char* gen_label_name(void) { } struct ref ref_reg(int reg) { - return (struct ref){REF_REG, reg, 0, REFREL_ZERO, 0}; + return (struct ref){REF_REG, reg, 0, REFREL_ZERO, 0, NULL}; } struct ref ref_mem(int reg, int offset, enum refrel rel) { - return (struct ref){REF_MEM, reg, offset, rel, 0}; + return (struct ref){REF_MEM, reg, offset, rel, 0, NULL}; } struct ref ref_imm(int imm) { - return (struct ref){REF_IMM, REG_UNUSED, 0, REFREL_ZERO, imm}; + return (struct ref){REF_IMM, REG_UNUSED, 0, REFREL_ZERO, imm, NULL}; +} + +struct ref ref_varname(const char *name) { + return (struct ref){REF_VARNAME, REG_UNUSED, 0, REFREL_ZERO, 0, ir_str(name)}; } struct ref ref_next_register(void) { @@ -279,6 +314,7 @@ bool ref_equal(struct ref r1, struct ref r2) { case REF_REG: return r1.reg == r2.reg; case REF_MEM: return r1.reg == r2.reg && r1.offset == r2.offset && r1.rel == r2.rel; case REF_IMM: return r1.imm == r2.imm; + case REF_VARNAME: return strcmp(r1.name, r2.name) == 0; default: assert(false); } } -- cgit v1.2.3-54-g00ecf