#ifndef _CODEGEN_REG_H_ #define _CODEGEN_REG_H_ #define IREG_SIZE_L (0 << 6) #define IREG_SIZE_W (1 << 6) #define IREG_SIZE_B (2 << 6) #define IREG_SIZE_BH (3 << 6) enum { IREG_EAX = 0, IREG_ECX = 1, IREG_EDX = 2, IREG_EBX = 3, IREG_ESP = 4, IREG_EBP = 5, IREG_ESI = 6, IREG_EDI = 7, IREG_flags_op = 8, IREG_flags_res = 9, IREG_flags_op1 = 10, IREG_flags_op2 = 11, IREG_pc = 12, IREG_oldpc = 13, IREG_eaaddr = 14, IREG_ea_seg = 15, IREG_op32 = 16, IREG_ssegs = 17, IREG_rm_mod_reg = 18, IREG_ins = 19, IREG_cycles = 20, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ IREG_temp0 = 21, IREG_temp1 = 22, IREG_temp2 = 23, IREG_temp3 = 24, IREG_COUNT, IREG_INVALID = 255 }; #define IREG_32(reg) ((reg) + IREG_EAX) extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_version_refcount[IREG_COUNT][256]; typedef struct { uint8_t reg; uint8_t version; } ir_reg_t; extern ir_reg_t invalid_ir_reg; typedef uint8_t ir_host_reg_t; static inline ir_reg_t codegen_reg_read(int reg) { ir_reg_t ireg; if (reg == IREG_INVALID) fatal("codegen_reg_read - IREG_INVALID\n"); ireg.reg = reg; ireg.version = reg_last_version[reg]; reg_version_refcount[ireg.reg][ireg.version]++; if (!reg_version_refcount[ireg.reg][ireg.version]) fatal("codegen_reg_read - refcount overflow\n"); return ireg; } static inline ir_reg_t codegen_reg_write(int reg) { ir_reg_t ireg; if (reg == IREG_INVALID) fatal("codegen_reg_write - IREG_INVALID\n"); ireg.reg = reg; ireg.version = reg_last_version[reg] + 1; reg_last_version[reg]++; if (!reg_last_version[reg]) fatal("codegen_reg_write - version overflow\n"); reg_version_refcount[reg][ireg.version] = 0; return ireg; } struct ir_data_t; void codegen_reg_reset(); void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block); /*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b); ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg); ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg); #endif