WARNING: CONFIGS MIGHT PARTIALLY BREAK WHERE DEVICE NAMES HAVE CHANGED.

Changes to device_t struct to accomodate the upcoming PCI IRQ arbitration rewrite;
Added device.c/h API to obtain name from the device_t struct;
Significant changes to win/win_settings.c to clean up the code a bit and fix bugs;
Ported all the CPU and AudioPCI commits from PCem;
Added an API call to allow ACPI soft power off to gracefully stop the emulator;
Removed the Siemens PCD-2L from the Dev branch because it now works;
Removed the Socket 5 HP Vectra from the Dev branch because it now works;
Fixed the Compaq Presario and the Micronics Spitfire;
Give the IBM PC330 its own list of 486 CPU so it can have DX2's with CPUID 0x470;
SMM fixes;
Rewrote the SYSENTER, SYSEXIT, SYSCALL, and SYSRET instructions;
Changed IDE reset period to match the specification, fixes #929;
The keyboard input and output ports are now forced in front of the queue when read, fixes a number of bugs, including the AMI Apollo hanging on soft reset;
Added the Intel AN430TX but Dev branched because it does not work;
The network code no longer drops packets if the emulated network card has failed to receive them (eg. when the buffer is full);
Changes to PCI card adding and renamed some PCI slot types, also added proper AGP bridge slot types;
USB UHCI emulation is no longer a stub (still doesn't fully work, but at least Windows XP chk with Debug no longer ASSERT's on it);
Fixed NVR on the the SMC FDC37C932QF and APM variants;
A number of fixes to Intel 4x0 chipsets, including fixing every register of the 440LX and 440EX;
Some ACPI changes.
This commit is contained in:
OBattler
2020-11-16 00:01:21 +01:00
parent 745460f64b
commit 0faf6692c9
260 changed files with 5122 additions and 4471 deletions

View File

@@ -32,7 +32,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst
{
int c;
for (c = 0; c < block->ins; c++)
for (c = 0; c <= block->ins; c++)
{
if (codegen_instructions[c].pc == pc)
{

View File

@@ -10,3 +10,5 @@
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_MAX 0x3c0
#define CODEGEN_BACKEND_HAS_MOV_IMM

View File

@@ -521,6 +521,26 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
codegen_addbyte(block, imm_data);
}
}
void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data)
{
int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
if (offset >= -128 && offset < 127)
{
codegen_alloc_bytes(block, 6);
codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/
codegen_addword(block, imm_data);
}
else
{
if ((uintptr_t)p >> 32)
fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p);
codegen_alloc_bytes(block, 10);
codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/
codegen_addlong(block, (uint32_t)(uintptr_t)p);
codegen_addword(block, imm_data);
}
}
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@@ -945,6 +965,30 @@ void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset
fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset);
}
void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data)
{
if (base_reg & 8)
fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n");
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_RSP)
{
codegen_alloc_bytes(block, 8);
codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset);
codegen_addlong(block, imm_data);
}
else
{
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset);
codegen_addlong(block, imm_data);
}
}
else
fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset);
}
void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data)
{
if (reg >= 8)

View File

@@ -56,6 +56,7 @@ void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr
void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift);
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data);
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg);
@@ -72,6 +73,8 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg);
void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg);
void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data);
void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);

View File

@@ -3145,4 +3145,21 @@ void codegen_set_jump_dest(codeblock_t *block, void *p)
*(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4);
}
void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data)
{
host_x86_MOV8_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data)
{
host_x86_MOV16_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data)
{
host_x86_MOV32_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data)
{
host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data);
}
#endif

View File

@@ -10,3 +10,5 @@
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_MAX 0x3c0
#define CODEGEN_BACKEND_HAS_MOV_IMM

View File

@@ -449,6 +449,24 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
codegen_addbyte(block, imm_data);
}
}
void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
if (offset >= -128 && offset < 127)
{
codegen_alloc_bytes(block, 6);
codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/
codegen_addword(block, imm_data);
}
else
{
codegen_alloc_bytes(block, 9);
codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/
codegen_addlong(block, (uint32_t)p);
codegen_addword(block, imm_data);
}
}
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@@ -705,6 +723,27 @@ void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset
fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset);
}
void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data)
{
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_ESP)
{
codegen_alloc_bytes(block, 8);
codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset);
codegen_addlong(block, imm_data);
}
else
{
codegen_alloc_bytes(block, 7);
codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset);
codegen_addlong(block, imm_data);
}
}
else
fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset);
}
void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data)
{
codegen_alloc_bytes(block, 2);

View File

@@ -60,6 +60,7 @@ void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr
void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift);
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data);
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg);
@@ -75,6 +76,8 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg
void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data);
void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);

View File

@@ -2643,6 +2643,11 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
static int codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop)
{
host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data);
return 0;
}
static int codegen_SUB(codeblock_t *block, uop_t *uop)
{
@@ -2838,6 +2843,7 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM,
[UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8,
[UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16,
[UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS,
[UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG,
@@ -3138,4 +3144,21 @@ void codegen_set_jump_dest(codeblock_t *block, void *p)
*(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4);
}
void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data)
{
host_x86_MOV8_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data)
{
host_x86_MOV16_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data)
{
host_x86_MOV32_ABS_IMM(block, p, imm_data);
}
void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data)
{
host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data);
}
#endif

View File

@@ -67,8 +67,10 @@ static int dirty_list_size = 0;
static void block_free_list_add(codeblock_t *block)
{
#ifndef RELEASE_BUILD
if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
fatal("block_free_list_add: block=%p in dirty list\n", block);
#endif
if (block_free_list)
block->next = block_free_list;
else
@@ -79,8 +81,10 @@ static void block_free_list_add(codeblock_t *block)
static void block_dirty_list_add(codeblock_t *block)
{
#ifndef RELEASE_BUILD
if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
fatal("block_dirty_list_add: block=%p already in dirty list\n", block);
#endif
if (block_dirty_list_head != BLOCK_INVALID)
{
codeblock_t *old_head = &codeblock[block_dirty_list_head];
@@ -102,12 +106,14 @@ static void block_dirty_list_add(codeblock_t *block)
/*Evict oldest block to the free list*/
codeblock_t *evict_block = &codeblock[block_dirty_list_tail];
#ifndef RELEASE_BUILD
if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST))
fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags);
if (!block_dirty_list_tail)
fatal("block_dirty_list_add - !block_dirty_list_tail\n");
if (evict_block->prev == BLOCK_INVALID)
fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n");
#endif
block_dirty_list_tail = evict_block->prev;
codeblock[evict_block->prev].next = BLOCK_INVALID;
@@ -123,8 +129,10 @@ static void block_dirty_list_remove(codeblock_t *block)
codeblock_t *prev_block = &codeblock[block->prev];
codeblock_t *next_block = &codeblock[block->next];
#ifndef RELEASE_BUILD
if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST))
fatal("block_dirty_list_remove: block=%p not in dirty list\n", block);
#endif
/*Is block head of list*/
if (block->prev == BLOCK_INVALID)
@@ -139,8 +147,10 @@ static void block_dirty_list_remove(codeblock_t *block)
next_block->prev = block->prev;
dirty_list_size--;
#ifndef RELEASE_BUILD
if (dirty_list_size < 0)
fatal("remove - dirty_list_size < 0!\n");
#endif
block->flags &= ~CODEBLOCK_IN_DIRTY_LIST;
}
@@ -170,9 +180,10 @@ static codeblock_t *block_free_list_get()
/*Free list is empty, check the dirty list*/
if (block_dirty_list_tail)
{
#ifndef RELEASE_BUILD
if (dirty_list_size <= 0)
fatal("get - dirty_list_size <= 0!\n");
#endif
/*Reuse oldest block*/
block = &codeblock[block_dirty_list_tail];
@@ -296,8 +307,10 @@ static void add_to_block_list(codeblock_t *block)
uint16_t block_prev_nr = pages[block->phys >> 12].block;
uint16_t block_nr = get_block_nr(block);
#ifndef RELEASE_BUILD
if (!block->page_mask)
fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask,block->page_mask2);
#endif
if (block_prev_nr)
{
@@ -313,8 +326,10 @@ static void add_to_block_list(codeblock_t *block)
if (block->next)
{
#ifndef RELEASE_BUILD
if (codeblock[block->next].pc == BLOCK_PC_INVALID)
fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos);
#endif
}
if (block->page_mask2)
@@ -341,9 +356,10 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
{
if (!block->page_mask)
return;
#ifndef RELEASE_BUILD
if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
fatal("remove_from_block_list: in dirty list\n");
#endif
if (block->prev)
{
codeblock[block->prev].next = block->next;
@@ -361,8 +377,10 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
if (!(block->flags & CODEBLOCK_HAS_PAGE2))
{
#ifndef RELEASE_BUILD
if (block->prev_2 || block->next_2)
fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys);
#endif
return;
}
block->flags &= ~CODEBLOCK_HAS_PAGE2;
@@ -387,11 +405,12 @@ static void invalidate_block(codeblock_t *block)
{
uint32_t old_pc = block->pc;
#ifndef RELEASE_BUILD
if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
fatal("invalidate_block: already in dirty list\n");
if (block->pc == BLOCK_PC_INVALID)
fatal("Invalidating deleted block\n");
#endif
remove_from_block_list(block, old_pc);
block_dirty_list_add(block);
if (block->head_mem_block)
@@ -406,8 +425,10 @@ static void delete_block(codeblock_t *block)
if (block == &codeblock[codeblock_hash[HASH(block->phys)]])
codeblock_hash[HASH(block->phys)] = BLOCK_INVALID;
#ifndef RELEASE_BUILD
if (block->pc == BLOCK_PC_INVALID)
fatal("Deleting deleted block\n");
#endif
block->pc = BLOCK_PC_INVALID;
codeblock_tree_delete(block);
@@ -426,8 +447,10 @@ static void delete_dirty_block(codeblock_t *block)
if (block == &codeblock[codeblock_hash[HASH(block->phys)]])
codeblock_hash[HASH(block->phys)] = BLOCK_INVALID;
#ifndef RELEASE_BUILD
if (block->pc == BLOCK_PC_INVALID)
fatal("Deleting deleted block\n");
#endif
block->pc = BLOCK_PC_INVALID;
codeblock_tree_delete(block);
@@ -475,8 +498,10 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{
invalidate_block(block);
}
#ifndef RELEASE_BUILD
if (block_nr == next_block)
fatal("Broken 1\n");
#endif
block_nr = next_block;
}
@@ -491,8 +516,10 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{
invalidate_block(block);
}
#ifndef RELEASE_BUILD
if (block_nr == next_block)
fatal("Broken 2\n");
#endif
block_nr = next_block;
}
@@ -520,8 +547,10 @@ void codegen_block_init(uint32_t phys_addr)
if (!page->block)
mem_flush_write_page(phys_addr, cs+cpu_state.pc);
block = block_free_list_get();
#ifndef RELEASE_BUILD
if (!block)
fatal("codegen_block_init: block_free_list_get() returned NULL\n");
#endif
block_current = get_block_nr(block);
block_num = HASH(phys_addr);
@@ -560,8 +589,10 @@ void codegen_block_start_recompile(codeblock_t *block)
block_num = HASH(block->phys);
block_current = get_block_nr(block);//block->pnt;
#ifndef RELEASE_BUILD
if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED))
fatal("Recompile to used block!\n");
#endif
block->head_mem_block = codegen_allocator_allocate(NULL, block_current);
block->data = codeblock_allocator_get_ptr(block->head_mem_block);
@@ -668,6 +699,7 @@ void codegen_block_generate_end_mask_recompile()
if (!pages[block->phys_2 >> 12].block_2)
mem_flush_write_page(block->phys_2, codegen_endpc);
#ifndef RELEASE_BUILD
if (!block->page_mask2)
fatal("!page_mask2\n");
if (block->next_2)
@@ -675,6 +707,7 @@ void codegen_block_generate_end_mask_recompile()
if (codeblock[block->next_2].pc == BLOCK_PC_INVALID)
fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]);
}
#endif
}
else
{
@@ -695,8 +728,10 @@ void codegen_block_generate_end_mask_mark()
uint32_t end_pc;
page_t *p;
#ifndef RELEASE_BUILD
if (block->flags & CODEBLOCK_BYTE_MASK)
fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n");
#endif
block->page_mask = 0;
start_pc = (block->pc & 0xfff) & ~63;
@@ -741,6 +776,7 @@ void codegen_block_generate_end_mask_mark()
if (!pages[block->phys_2 >> 12].block_2)
mem_flush_write_page(block->phys_2, codegen_endpc);
#ifndef RELEASE_BUILD
if (!block->page_mask2)
fatal("!page_mask2\n");
if (block->next_2)
@@ -748,7 +784,7 @@ void codegen_block_generate_end_mask_mark()
if (codeblock[block->next_2].pc == BLOCK_PC_INVALID)
fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]);
}
#endif
block->dirty_mask2 = &page_2->dirty_mask;
}
else

View File

@@ -71,8 +71,10 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++)
{
int offset = ir->wr_pos - codegen_unroll_start;
// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count);
for (c = codegen_unroll_start; c < unroll_end; c++)
{
// pclog(" Duplicate uop %i\n", c);
duplicate_uop(ir, &ir->uops[c], offset);
}
}
@@ -87,6 +89,8 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
for (c = 0; c < ir->wr_pos; c++)
{
uop_t *uop = &ir->uops[c];
// pclog("uOP %i : %08x\n", c, uop->type);
if (uop->type & UOP_TYPE_BARRIER)
codegen_reg_flush_invalidate(ir, block);
@@ -105,37 +109,61 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
if ((uop->type & UOP_MASK) == UOP_INVALID)
continue;
if (uop->type & UOP_TYPE_PARAMS_REGS)
#ifdef CODEGEN_BACKEND_HAS_MOV_IMM
if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0)
{
codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c);
if (uop->src_reg_a.reg != IREG_INVALID)
{
uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL);
}
if (uop->src_reg_b.reg != IREG_INVALID)
{
uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL);
}
if (uop->src_reg_c.reg != IREG_INVALID)
{
uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL);
}
/*Special case for UOP_MOV_IMM - if destination not already in host register
and won't be used again then just store directly to memory*/
codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data);
}
if (uop->type & UOP_TYPE_ORDER_BARRIER)
codegen_reg_flush(ir, block);
else
#endif
if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 &&
reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a))
{
/*Special case for UOP_MOV - if source register won't be used again then
just rename it to dest register instead of moving*/
codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg);
uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL);
codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a);
if (uop->type & UOP_TYPE_ORDER_BARRIER)
codegen_reg_flush(ir, block);
}
else
{
if (uop->type & UOP_TYPE_PARAMS_REGS)
{
codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c);
if (uop->src_reg_a.reg != IREG_INVALID)
{
uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL);
}
if (uop->src_reg_b.reg != IREG_INVALID)
{
uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL);
}
if (uop->src_reg_c.reg != IREG_INVALID)
{
uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL);
}
}
if (uop->type & UOP_TYPE_PARAMS_REGS)
{
if (uop->dest_reg_a.reg != IREG_INVALID)
if (uop->type & UOP_TYPE_ORDER_BARRIER)
codegen_reg_flush(ir, block);
if (uop->type & UOP_TYPE_PARAMS_REGS)
{
uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a);
if (uop->dest_reg_a.reg != IREG_INVALID)
{
uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a);
}
}
#ifndef RELEASE_BUILD
if (!uop_handlers[uop->type & UOP_MASK])
fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type);
#endif
uop_handlers[uop->type & UOP_MASK](block, uop);
}
if (!uop_handlers[uop->type & UOP_MASK])
fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type);
uop_handlers[uop->type & UOP_MASK](block, uop);
if (uop->type & UOP_TYPE_JUMP)
{

View File

@@ -55,6 +55,7 @@
/*UOP_JMP_DEST - jump to ptr*/
#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP)
#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18)
#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19)
#ifdef DEBUG_EXTRA
/*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/
@@ -765,6 +766,7 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in
#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm)
#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm)
#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm)
#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg)
#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg)
@@ -807,4 +809,9 @@ void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int
void codegen_set_jump_dest(codeblock_t *block, void *p);
void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data);
void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data);
void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data);
void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data);
#endif

View File

@@ -277,8 +277,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size)
{
case REG_WORD:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n");
#endif
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (int)(uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
@@ -286,8 +288,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_DWORD:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n");
#endif
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (int)(uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
@@ -295,8 +299,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_QWORD:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_QWORD !REG_FP\n");
#endif
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (int)(uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
@@ -304,8 +310,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_POINTER:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n");
#endif
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (int)(uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
@@ -313,8 +321,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_DOUBLE:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n");
#endif
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (int)(uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
@@ -322,8 +332,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_FPU_ST_BYTE:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]);
else
@@ -331,8 +343,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_FPU_ST_QWORD:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]);
else
@@ -340,8 +354,10 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
break;
case REG_FPU_ST_DOUBLE:
#ifndef RELEASE_BUILD
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]);
else
@@ -366,24 +382,30 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
switch (ireg_data[ir_reg].native_size)
{
case REG_BYTE:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n");
if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_BYTE %p\n", p);
#endif
codegen_direct_write_8(block, p, reg_set->reg_list[c].reg);
break;
case REG_WORD:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n");
if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_WORD %p\n", p);
#endif
codegen_direct_write_16(block, p, reg_set->reg_list[c].reg);
break;
case REG_DWORD:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n");
#endif
if ((uintptr_t)p < 256)
codegen_direct_write_32_stack(block, (int)(uintptr_t)p, reg_set->reg_list[c].reg);
else
@@ -391,8 +413,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break;
case REG_QWORD:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n");
#endif
if ((uintptr_t)p < 256)
codegen_direct_write_64_stack(block, (int)(uintptr_t)p, reg_set->reg_list[c].reg);
else
@@ -400,16 +424,20 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break;
case REG_POINTER:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n");
if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_POINTER %p\n", p);
#endif
codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg);
break;
case REG_DOUBLE:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n");
#endif
if ((uintptr_t)p < 256)
codegen_direct_write_double_stack(block, (int)(uintptr_t)p, reg_set->reg_list[c].reg);
else
@@ -417,8 +445,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break;
case REG_FPU_ST_BYTE:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else
@@ -426,8 +456,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break;
case REG_FPU_ST_QWORD:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else
@@ -435,8 +467,10 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break;
case REG_FPU_ST_DOUBLE:
#ifndef RELEASE_BUILD
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n");
#endif
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else
@@ -452,6 +486,49 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
reg_set->dirty[c] = 0;
}
#ifdef CODEGEN_BACKEND_HAS_MOV_IMM
void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data)
{
int reg_idx = IREG_GET_REG(ir_reg.reg);
void *p = ireg_data[reg_idx].p;
switch (ireg_data[reg_idx].native_size)
{
case REG_BYTE:
#ifndef RELEASE_BUILD
if ((uintptr_t)p < 256)
fatal("codegen_reg_write_imm - REG_BYTE %p\n", p);
#endif
codegen_direct_write_8_imm(block, p, imm_data);
break;
case REG_WORD:
#ifndef RELEASE_BUILD
if ((uintptr_t)p < 256)
fatal("codegen_reg_write_imm - REG_WORD %p\n", p);
#endif
codegen_direct_write_16_imm(block, p, imm_data);
break;
case REG_DWORD:
if ((uintptr_t)p < 256)
codegen_direct_write_32_imm_stack(block, (int)p, imm_data);
else
codegen_direct_write_32_imm(block, p, imm_data);
break;
case REG_POINTER:
case REG_QWORD:
case REG_DOUBLE:
case REG_FPU_ST_BYTE:
case REG_FPU_ST_QWORD:
case REG_FPU_ST_DOUBLE:
default:
fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size);
}
}
#endif
static void alloc_reg(ir_reg_t ir_reg)
{
host_reg_set_t *reg_set = get_reg_set(ir_reg);
@@ -462,8 +539,10 @@ static void alloc_reg(ir_reg_t ir_reg)
{
if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg))
{
#ifndef RELEASE_BUILD
if (reg_set->regs[c].version != ir_reg.version)
fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg);
#endif
reg_set->locked |= (1 << c);
return;
}
@@ -551,8 +630,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in
break;
}
#ifndef RELEASE_BUILD
if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount)
fatal("codegen_reg_alloc_read_reg - version mismatch!\n");
#endif
}
if (c == reg_set->nr_regs)
@@ -571,8 +652,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in
if (!(reg_set->locked & (1 << c)))
break;
}
#ifndef RELEASE_BUILD
if (c == reg_set->nr_regs)
fatal("codegen_reg_alloc_read_reg - out of registers\n");
#endif
}
if (reg_set->dirty[c])
codegen_reg_writeback(reg_set, block, c, 1);
@@ -582,8 +665,10 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in
}
reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--;
#ifndef RELEASE_BUILD
if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1)
fatal("codegen_reg_alloc_read_reg - refcount < 0\n");
#endif
if (host_reg_idx)
*host_reg_idx = c;
@@ -606,11 +691,13 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
codegen_reg_alloc_read_reg(block, parent_reg, &c);
#ifndef RELEASE_BUILD
if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version-1)
fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c,
reg_set->regs[c].reg,reg_set->regs[c].version,
ir_reg.reg,ir_reg.version);
#endif
reg_set->regs[c].reg = ir_reg.reg;
reg_set->regs[c].version = ir_reg.version;
reg_set->dirty[c] = 1;
@@ -624,8 +711,10 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
{
if (reg_set->regs[c].version <= ir_reg.version-1)
{
#ifndef RELEASE_BUILD
if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0)
fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n");
#endif
break;
}
}
@@ -648,8 +737,10 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
if (!(reg_set->locked & (1 << c)))
break;
}
#ifndef RELEASE_BUILD
if (c == reg_set->nr_regs)
fatal("codegen_reg_alloc_write_reg - out of registers\n");
#endif
if (reg_set->dirty[c])
codegen_reg_writeback(reg_set, block, c, 1);
}
@@ -661,6 +752,68 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg);
}
#ifdef CODEGEN_BACKEND_HAS_MOV_IMM
int codegen_reg_is_loaded(ir_reg_t ir_reg)
{
host_reg_set_t *reg_set = get_reg_set(ir_reg);
int c;
/*Search for previous version in host register*/
for (c = 0; c < reg_set->nr_regs; c++)
{
if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg))
{
if (reg_set->regs[c].version <= ir_reg.version-1)
{
#ifndef RELEASE_BUILD
if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0)
fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n");
#endif
return 1;
}
}
}
return 0;
}
#endif
void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst)
{
host_reg_set_t *reg_set = get_reg_set(src);
int c;
int target;
// pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version);
/*Search for required register*/
for (c = 0; c < reg_set->nr_regs; c++)
{
if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version)
break;
}
#ifndef RELEASE_BUILD
if (c == reg_set->nr_regs)
fatal("codegen_reg_rename: Can't find register to rename\n");
#endif
target = c;
if (reg_set->dirty[target])
codegen_reg_writeback(reg_set, block, target, 0);
reg_set->regs[target] = dst;
reg_set->dirty[target] = 1;
// pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version);
/*Invalidate any stale copies of the dest register*/
for (c = 0; c < reg_set->nr_regs; c++)
{
if (c == target)
continue;
if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg))
{
reg_set->regs[c] = invalid_ir_reg;
reg_set->dirty[c] = 0;
}
}
}
void codegen_reg_flush(ir_data_t *ir, codeblock_t *block)
{
host_reg_set_t *reg_set;

View File

@@ -325,17 +325,21 @@ static inline ir_reg_t codegen_reg_read(int reg)
ir_reg_t ireg;
reg_version_t *version;
#ifndef RELEASE_BUILD
if (IREG_GET_REG(reg) == IREG_INVALID)
fatal("codegen_reg_read - IREG_INVALID\n");
#endif
ireg.reg = reg;
ireg.version = reg_last_version[IREG_GET_REG(reg)];
version = &reg_version[IREG_GET_REG(ireg.reg)][ireg.version];
version->flags = 0;
version->refcount++;
#ifndef RELEASE_BUILD
if (!version->refcount)
fatal("codegen_reg_read - refcount overflow\n");
else if (version->refcount > REG_REFCOUNT_MAX)
else
#endif
if (version->refcount > REG_REFCOUNT_MAX)
CPU_BLOCK_END();
if (version->refcount > max_version_refcount)
max_version_refcount = version->refcount;
@@ -350,9 +354,10 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr)
int last_version = reg_last_version[IREG_GET_REG(reg)];
reg_version_t *version;
#ifndef RELEASE_BUILD
if (IREG_GET_REG(reg) == IREG_INVALID)
fatal("codegen_reg_write - IREG_INVALID\n");
#endif
ireg.reg = reg;
ireg.version = last_version + 1;
@@ -364,9 +369,12 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr)
}
reg_last_version[IREG_GET_REG(reg)]++;
#ifndef RELEASE_BUILD
if (!reg_last_version[IREG_GET_REG(reg)])
fatal("codegen_reg_write - version overflow\n");
else if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
else
#endif
if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX)
CPU_BLOCK_END();
if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount)
max_version_refcount = reg_last_version[IREG_GET_REG(reg)];
@@ -394,9 +402,16 @@ void codegen_reg_flush_invalidate(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_reg_t src_reg_c);
#ifdef CODEGEN_BACKEND_HAS_MOV_IMM
int codegen_reg_is_loaded(ir_reg_t ir_reg);
void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data);
#endif
ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx);
ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg);
void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst);
void codegen_reg_mark_as_required();
void codegen_reg_process_dead_list(struct ir_data_t *ir);
#endif