#include #include #include "ir.h" struct ir* ir_make(void) { struct ir *ir = malloc(sizeof(struct ir)); ir->cap = 32; ir->len = 0; ir->inss = malloc(ir->cap * sizeof(struct irins*)); ir->globspace = 0; return ir; } void ir_delete(struct ir *ir) { for (int i = 0; i < ir->len; i++) { irins_delete(ir->inss[i]); } free(ir->inss); free(ir); } struct ref ir_reserve_global(struct ir *ir, int size) { int offset = ir->globspace; ir->globspace += size; return ref_mem(-1, offset, true); } void ir_append(struct ir *ir, struct irins *ins) { if (ir->len == ir->cap) { ir->cap *= 2; ir->inss = realloc(ir->inss, ir->cap * sizeof(struct irins*)); } ir->inss[ir->len++] = ins; } struct irins* irins_make(enum instype type) { struct irins *ins = malloc(sizeof(struct irins)); ins->type = type; ins->name = NULL; return ins; } struct irins* irins_make_name(enum instype type, char *name) { struct irins *ins = irins_make(type); ins->name = name; return ins; } struct irins* irins_make_01(enum instype type, struct ref r0, struct ref r1) { struct irins *ins = irins_make(type); ins->r0 = r0; ins->r1 = r1; return ins; } struct irins* irins_make_012(enum instype type, struct ref r0, struct ref r1, struct ref r2) { struct irins *ins = irins_make_01(type, r0, r1); ins->r2 = r2; return ins; } struct irins* irins_make_1(enum instype type, struct ref r1) { struct irins *ins = irins_make(type); ins->r1 = r1; return ins; } struct irins* irins_make_12(enum instype type, struct ref r1, struct ref r2) { struct irins *ins = irins_make(type); ins->r1 = r1; ins->r2 = r2; return ins; } struct irins* irins_make_jcc(char *name, enum condcode condcode) { struct irins *ins = irins_make(INS_JCC); ins->name = name; ins->condcode = condcode; return ins; } void irins_delete(struct irins *ins) { if (ins->name) free(ins->name); free(ins); } char* gen_label_name(void) { static int next = 0; char *buf = malloc(16); sprintf(buf, "L%d", next++); return buf; } struct ref ref_reg(int reg) { return (struct ref){REF_REG, reg, 0, false, 0}; } struct ref ref_mem(int reg, int offset, bool rel_heap) { return (struct ref){REF_MEM, reg, offset, rel_heap, 0}; } struct ref ref_imm(int imm) { return (struct ref){REF_IMM, -1, 0, false, imm}; } struct ref ref_next_register(void) { static int next = 0; return ref_reg(next++); }