pcem/src/codegen_ir.c

123 lines
4.7 KiB
C

#include "ibm.h"
#include "codegen.h"
#include "codegen_allocator.h"
#include "codegen_backend.h"
#include "codegen_ir.h"
#include "codegen_reg.h"
extern int has_ea;
static ir_data_t ir_block;
ir_data_t *codegen_ir_init()
{
ir_block.wr_pos = 0;
// pclog("codegen_ir_init %04x:%04x\n", CS,cpu_state.pc);
return &ir_block;
}
void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
{
int jump_target_at_end = -1;
int c;
block_write_data = codeblock_allocator_get_ptr(block->head_mem_block);
block_pos = 0;
codegen_backend_prologue(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);
else if (uop->type & UOP_TYPE_ORDER_BARRIER)
codegen_reg_flush(ir, block);
if (uop->type & UOP_TYPE_JUMP_DEST)
{
uop_t *uop_dest = uop;
while (uop_dest->jump_list_next != -1)
{
uop_dest = &ir->uops[uop_dest->jump_list_next];
codegen_set_jump_dest(block, uop_dest->p);
}
}
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->dest_reg_a.reg != IREG_INVALID)
{
uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a);
}
}
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)
{
if (uop->jump_dest_uop == ir->wr_pos)
{
if (jump_target_at_end == -1)
jump_target_at_end = c;
else
{
uop_t *uop_dest = &ir->uops[jump_target_at_end];
while (uop_dest->jump_list_next != -1)
uop_dest = &ir->uops[uop_dest->jump_list_next];
uop_dest->jump_list_next = c;
}
}
else
{
uop_t *uop_dest = &ir->uops[uop->jump_dest_uop];
while (uop_dest->jump_list_next != -1)
uop_dest = &ir->uops[uop_dest->jump_list_next];
uop_dest->jump_list_next = c;
ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST;
}
}
}
codegen_reg_flush_invalidate(ir, block);
if (jump_target_at_end != -1)
{
uop_t *uop_dest = &ir->uops[jump_target_at_end];
while (1)
{
codegen_set_jump_dest(block, uop_dest->p);
if (uop_dest->jump_list_next == -1)
break;
uop_dest = &ir->uops[uop_dest->jump_list_next];
}
}
codegen_backend_epilogue(block);
block_write_data = NULL;
// if (has_ea)
// fatal("IR compilation complete\n");
}