XMM registers are not preserved across function calls, and should be flushed & discarded by the recompiler prior to calling external functions. Fixes graphics issues in some games (eg World Cup 98 title/menus).

This commit is contained in:
SarahW 2019-05-05 14:49:10 +01:00
commit 5e35e48ec7
7 changed files with 135 additions and 98 deletions

View file

@ -1,3 +1,6 @@
#ifndef _CODEGEN_BACKEND_H_
#define _CODEGEN_BACKEND_H_
//#ifdef __amd64__ //#ifdef __amd64__
//#include "codegen_x86-64.h" //#include "codegen_x86-64.h"
#if defined __amd64__ #if defined __amd64__
@ -25,5 +28,16 @@ typedef int (*uOpFn)(codeblock_t *codeblock, struct uop_t *uop);
extern const uOpFn uop_handlers[]; extern const uOpFn uop_handlers[];
extern int codegen_host_reg_list[CODEGEN_HOST_REGS]; /*Register will not be preserved across function calls*/
extern int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS]; #define HOST_REG_FLAG_VOLATILE (1 << 0)
typedef struct host_reg_def_t
{
int reg;
int flags;
} host_reg_def_t;
extern host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS];
extern host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS];
#endif

View file

@ -38,27 +38,27 @@ void *codegen_fp_round;
void *codegen_gpf_rout; void *codegen_gpf_rout;
void *codegen_exit_rout; void *codegen_exit_rout;
int codegen_host_reg_list[CODEGEN_HOST_REGS] = host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] =
{ {
REG_R4, {REG_R4, 0},
REG_R5, {REG_R5, 0},
REG_R6, {REG_R6, 0},
REG_R7, {REG_R7, 0},
REG_R8, {REG_R8, 0},
REG_R9, {REG_R9, 0},
REG_R11, {REG_R11, 0}
}; };
int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
{ {
REG_D8, {REG_D8, 0},
REG_D9, {REG_D9, 0},
REG_D10, {REG_D10, 0},
REG_D11, {REG_D11, 0},
REG_D12, {REG_D12, 0},
REG_D13, {REG_D13, 0},
REG_D14, {REG_D14, 0},
REG_D15 {REG_D15, 0}
}; };
static void build_load_routine(codeblock_t *block, int size, int is_float) static void build_load_routine(codeblock_t *block, int size, int is_float)

View file

@ -39,30 +39,30 @@ void *codegen_fp_round_quad;
void *codegen_gpf_rout; void *codegen_gpf_rout;
void *codegen_exit_rout; void *codegen_exit_rout;
int codegen_host_reg_list[CODEGEN_HOST_REGS] = host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] =
{ {
REG_X19, {REG_X19, 0},
REG_X20, {REG_X20, 0},
REG_X21, {REG_X21, 0},
REG_X22, {REG_X22, 0},
REG_X23, {REG_X23, 0},
REG_X24, {REG_X24, 0},
REG_X25, {REG_X25, 0},
REG_X26, {REG_X26, 0},
REG_X27, {REG_X27, 0},
REG_X28 {REG_X28, 0}
}; };
int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
{ {
REG_V8, {REG_V8, 0},
REG_V9, {REG_V9, 0},
REG_V10, {REG_V10, 0},
REG_V11, {REG_V11, 0},
REG_V12, {REG_V12, 0},
REG_V13, {REG_V13, 0},
REG_V14, {REG_V14, 0},
REG_V15 {REG_V15, 0}
}; };
static void build_load_routine(codeblock_t *block, int size, int is_float) static void build_load_routine(codeblock_t *block, int size, int is_float)

View file

@ -35,22 +35,32 @@ void *codegen_mem_store_double;
void *codegen_gpf_rout; void *codegen_gpf_rout;
void *codegen_exit_rout; void *codegen_exit_rout;
int codegen_host_reg_list[CODEGEN_HOST_REGS] = host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] =
{ {
REG_EAX, /*Note: while EAX and EDX are normally volatile registers under x86
REG_EBX, calling conventions, the recompiler will explicitly save and restore
REG_EDX them across funcion calls*/
{REG_EAX, 0},
{REG_EBX, 0},
{REG_EDX, 0}
}; };
int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
{ {
REG_XMM0, #if WIN64
REG_XMM1, /*Windows x86-64 calling convention preserves XMM6-XMM15*/
REG_XMM2, {REG_XMM6, 0},
REG_XMM3, {REG_XMM7, 0},
REG_XMM4, #else
REG_XMM5, /*System V AMD64 calling convention does not preserve any XMM registers*/
REG_XMM6 {REG_XMM6, HOST_REG_FLAG_VOLATILE},
{REG_XMM7, HOST_REG_FLAG_VOLATILE},
#endif
{REG_XMM1, HOST_REG_FLAG_VOLATILE},
{REG_XMM2, HOST_REG_FLAG_VOLATILE},
{REG_XMM3, HOST_REG_FLAG_VOLATILE},
{REG_XMM4, HOST_REG_FLAG_VOLATILE},
{REG_XMM5, HOST_REG_FLAG_VOLATILE}
}; };
static void build_load_routine(codeblock_t *block, int size, int is_float) static void build_load_routine(codeblock_t *block, int size, int is_float)

View file

@ -44,7 +44,7 @@
#define REG_XMM6 6 #define REG_XMM6 6
#define REG_XMM7 7 #define REG_XMM7 7
#define REG_XMM_TEMP REG_XMM7 #define REG_XMM_TEMP REG_XMM0
#define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_REGS 3
#define CODEGEN_HOST_FP_REGS 7 #define CODEGEN_HOST_FP_REGS 7

View file

@ -36,21 +36,24 @@ void *codegen_mem_store_double;
void *codegen_gpf_rout; void *codegen_gpf_rout;
void *codegen_exit_rout; void *codegen_exit_rout;
int codegen_host_reg_list[CODEGEN_HOST_REGS] = host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] =
{ {
REG_EAX, /*Note: while EAX and EDX are normally volatile registers under x86
REG_EBX, calling conventions, the recompiler will explicitly save and restore
REG_EDX them across funcion calls*/
{REG_EAX, 0},
{REG_EBX, 0},
{REG_EDX, 0}
}; };
int codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] =
{ {
REG_XMM0, {REG_XMM0, HOST_REG_FLAG_VOLATILE},
REG_XMM1, {REG_XMM1, HOST_REG_FLAG_VOLATILE},
REG_XMM2, {REG_XMM2, HOST_REG_FLAG_VOLATILE},
REG_XMM3, {REG_XMM3, HOST_REG_FLAG_VOLATILE},
REG_XMM4, {REG_XMM4, HOST_REG_FLAG_VOLATILE},
REG_XMM5 {REG_XMM5, HOST_REG_FLAG_VOLATILE}
}; };
static void build_load_routine(codeblock_t *block, int size, int is_float) static void build_load_routine(codeblock_t *block, int size, int is_float)

View file

@ -22,7 +22,7 @@ typedef struct host_reg_set_t
{ {
ir_reg_t *regs; ir_reg_t *regs;
uint8_t *dirty; uint8_t *dirty;
int *reg_list; host_reg_def_t *reg_list;
uint16_t locked; uint16_t locked;
int nr_regs; int nr_regs;
} host_reg_set_t; } host_reg_set_t;
@ -274,72 +274,72 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_16_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else else
codegen_direct_read_16(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_DWORD: case REG_DWORD:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_32_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else else
codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_QWORD: case REG_QWORD:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); fatal("codegen_reg_load - REG_QWORD !REG_FP\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_64_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else else
codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_POINTER: case REG_POINTER:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_pointer_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else else
codegen_direct_read_pointer(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_DOUBLE: case REG_DOUBLE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_double_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else else
codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_FPU_ST_BYTE: case REG_FPU_ST_BYTE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_8(block, reg_set->reg_list[c], &cpu_state.tag[ir_reg.reg & 7]); codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]);
else else
codegen_direct_read_st_8(block, reg_set->reg_list[c], &cpu_state.tag[0], ir_reg.reg & 7); codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7);
break; break;
case REG_FPU_ST_QWORD: case REG_FPU_ST_QWORD:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_64(block, reg_set->reg_list[c], &cpu_state.MM[ir_reg.reg & 7]); codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]);
else else
codegen_direct_read_st_64(block, reg_set->reg_list[c], &cpu_state.MM[0], ir_reg.reg & 7); codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7);
break; break;
case REG_FPU_ST_DOUBLE: case REG_FPU_ST_DOUBLE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]);
else else
codegen_direct_read_st_double(block, reg_set->reg_list[c], &cpu_state.ST[0], ir_reg.reg & 7); codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7);
break; break;
default: default:
@ -367,7 +367,7 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_BYTE %p\n", p); fatal("codegen_reg_writeback - REG_BYTE %p\n", p);
codegen_direct_write_8(block, p, reg_set->reg_list[c]); codegen_direct_write_8(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_WORD: case REG_WORD:
@ -375,25 +375,25 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_WORD %p\n", p); fatal("codegen_reg_writeback - REG_WORD %p\n", p);
codegen_direct_write_16(block, p, reg_set->reg_list[c]); codegen_direct_write_16(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_DWORD: case REG_DWORD:
if (ireg_data[ir_reg].type != REG_INTEGER) if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c]); codegen_direct_write_32_stack(block, (int)p, reg_set->reg_list[c].reg);
else else
codegen_direct_write_32(block, p, reg_set->reg_list[c]); codegen_direct_write_32(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_QWORD: case REG_QWORD:
if (ireg_data[ir_reg].type != REG_FP) if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c]); codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c].reg);
else else
codegen_direct_write_64(block, p, reg_set->reg_list[c]); codegen_direct_write_64(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_POINTER: case REG_POINTER:
@ -401,43 +401,43 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_POINTER %p\n", p); fatal("codegen_reg_writeback - REG_POINTER %p\n", p);
codegen_direct_write_ptr(block, p, reg_set->reg_list[c]); codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_DOUBLE: case REG_DOUBLE:
if (ireg_data[ir_reg].type != REG_FP) if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n");
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c]); codegen_direct_write_double_stack(block, (int)p, reg_set->reg_list[c].reg);
else else
codegen_direct_write_double(block, p, reg_set->reg_list[c]); codegen_direct_write_double(block, p, reg_set->reg_list[c].reg);
break; break;
case REG_FPU_ST_BYTE: case REG_FPU_ST_BYTE:
if (ireg_data[ir_reg].type != REG_INTEGER) if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n");
if (block->flags & CODEBLOCK_STATIC_TOP) 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]); codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else else
codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg);
break; break;
case REG_FPU_ST_QWORD: case REG_FPU_ST_QWORD:
if (ireg_data[ir_reg].type != REG_FP) if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) 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]); codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else else
codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg);
break; break;
case REG_FPU_ST_DOUBLE: case REG_FPU_ST_DOUBLE:
if (ireg_data[ir_reg].type != REG_FP) if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) 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]); codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg);
else else
codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg);
break; break;
default: default:
@ -595,7 +595,7 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, in
if (host_reg_idx) if (host_reg_idx)
*host_reg_idx = c; *host_reg_idx = c;
// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c); // pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c);
return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg);
} }
ir_host_reg_t codegen_reg_alloc_write_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)
@ -623,7 +623,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
reg_set->regs[c].version = ir_reg.version; reg_set->regs[c].version = ir_reg.version;
reg_set->dirty[c] = 1; reg_set->dirty[c] = 1;
// pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); // pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]);
return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg);
} }
/*Search for previous version in host register*/ /*Search for previous version in host register*/
@ -668,7 +668,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
reg_set->regs[c].version = ir_reg.version; reg_set->regs[c].version = ir_reg.version;
reg_set->dirty[c] = 1; reg_set->dirty[c] = 1;
// pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); // pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]);
return reg_set->reg_list[c] | IREG_GET_SIZE(ir_reg.reg); return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg);
} }
void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) void codegen_reg_flush(ir_data_t *ir, codeblock_t *block)
@ -683,6 +683,11 @@ void codegen_reg_flush(ir_data_t *ir, codeblock_t *block)
{ {
codegen_reg_writeback(reg_set, block, c, 0); codegen_reg_writeback(reg_set, block, c, 0);
} }
if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE)
{
reg_set->regs[c] = invalid_ir_reg;
reg_set->dirty[c] = 0;
}
} }
reg_set = &host_fp_reg_set; reg_set = &host_fp_reg_set;
@ -692,6 +697,11 @@ void codegen_reg_flush(ir_data_t *ir, codeblock_t *block)
{ {
codegen_reg_writeback(reg_set, block, c, 0); codegen_reg_writeback(reg_set, block, c, 0);
} }
if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE)
{
reg_set->regs[c] = invalid_ir_reg;
reg_set->dirty[c] = 0;
}
} }
} }