mirror of
https://github.com/holub/mame
synced 2025-07-05 09:57:47 +03:00
Added support for ROUNDSS and ROUNDSD on Penryn architectures.
This commit is contained in:
parent
d197133829
commit
9abf2c3efa
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
* Identify common pairs and optimize output
|
* Identify common pairs and optimize output
|
||||||
|
|
||||||
* Add SSE4.1 support for ROUNDSS, ROUNDSD
|
|
||||||
|
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
|
||||||
-------------------------
|
-------------------------
|
||||||
@ -267,6 +265,7 @@ struct _drcbe_state
|
|||||||
x86code * drcmap_get_value; /* map lookup helper */
|
x86code * drcmap_get_value; /* map lookup helper */
|
||||||
data_accessors accessors[ADDRESS_SPACES];/* memory accessors */
|
data_accessors accessors[ADDRESS_SPACES];/* memory accessors */
|
||||||
|
|
||||||
|
UINT8 sse41; /* do we have SSE4.1 support? */
|
||||||
UINT32 ssemode; /* saved SSE mode */
|
UINT32 ssemode; /* saved SSE mode */
|
||||||
UINT32 ssemodesave; /* temporary location for saving */
|
UINT32 ssemodesave; /* temporary location for saving */
|
||||||
UINT32 ssecontrol[4]; /* copy of the sse_control array */
|
UINT32 ssecontrol[4]; /* copy of the sse_control array */
|
||||||
@ -358,6 +357,15 @@ static UINT8 condition_map[DRCUML_COND_MAX - DRCUML_COND_Z] =
|
|||||||
COND_GE, /* DRCUML_COND_GE, requires SV */
|
COND_GE, /* DRCUML_COND_GE, requires SV */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* rounding mode mapping table */
|
||||||
|
static const UINT8 fprnd_map[4] =
|
||||||
|
{
|
||||||
|
FPRND_CHOP, /* DRCUML_FMOD_TRUNC, truncate */
|
||||||
|
FPRND_NEAR, /* DRCUML_FMOD_ROUND, round */
|
||||||
|
FPRND_UP, /* DRCUML_FMOD_CEIL, round up */
|
||||||
|
FPRND_DOWN /* DRCUML_FMOD_FLOOR round down */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -794,6 +802,7 @@ static void drcbex64_free(drcbe_state *drcbe)
|
|||||||
|
|
||||||
static void drcbex64_reset(drcbe_state *drcbe)
|
static void drcbex64_reset(drcbe_state *drcbe)
|
||||||
{
|
{
|
||||||
|
UINT32 (*cpuid_ecx_stub)(void);
|
||||||
x86code **dst;
|
x86code **dst;
|
||||||
int spacenum;
|
int spacenum;
|
||||||
|
|
||||||
@ -811,6 +820,18 @@ static void drcbex64_reset(drcbe_state *drcbe)
|
|||||||
if (dst == NULL)
|
if (dst == NULL)
|
||||||
fatalerror("Out of cache space after a reset!");
|
fatalerror("Out of cache space after a reset!");
|
||||||
|
|
||||||
|
/* generate a simple CPUID stub */
|
||||||
|
cpuid_ecx_stub = (UINT32 (*)(void))*dst;
|
||||||
|
emit_push_r64(dst, REG_RBX); // push rbx
|
||||||
|
emit_mov_r32_imm(dst, REG_EAX, 1); // mov eax,1
|
||||||
|
emit_cpuid(dst); // cpuid
|
||||||
|
emit_mov_r32_r32(dst, REG_EAX, REG_ECX); // mov eax,ecx
|
||||||
|
emit_pop_r64(dst, REG_RBX); // pop rbx
|
||||||
|
emit_ret(dst); // ret
|
||||||
|
|
||||||
|
/* call it to determine if we have SSE4.1 support */
|
||||||
|
drcbe->sse41 = (((*cpuid_ecx_stub)() & 0x80000) != 0);
|
||||||
|
|
||||||
/* generate an entry point */
|
/* generate an entry point */
|
||||||
drcbe->entry = (x86_entry_point_func)*dst;
|
drcbe->entry = (x86_entry_point_func)*dst;
|
||||||
emit_push_r64(dst, REG_RBX); // push rbx
|
emit_push_r64(dst, REG_RBX); // push rbx
|
||||||
@ -6656,146 +6677,87 @@ static x86code *op_ftoi4t(drcbe_state *drcbe, x86code *dst, const drcuml_instruc
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
op_ftoi4r - process a FTOI4R opcode
|
op_ftoi4x - process a FTOI4R/F/C opcode
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static x86code *op_ftoi4x(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst, int mode)
|
||||||
|
{
|
||||||
|
drcuml_parameter dstp, srcp;
|
||||||
|
int dstreg;
|
||||||
|
|
||||||
|
/* validate instruction */
|
||||||
|
assert(inst->size == 4 || inst->size == 8);
|
||||||
|
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
||||||
|
|
||||||
|
/* normalize parameters */
|
||||||
|
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
||||||
|
|
||||||
|
/* pick a target register for the general case */
|
||||||
|
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
||||||
|
|
||||||
|
/* non-SSE4.1 case */
|
||||||
|
if (!drcbe->sse41 || inst->size == 8)
|
||||||
|
{
|
||||||
|
/* save and set the control word */
|
||||||
|
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
||||||
|
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[mode])); // ldmxcsr fpcontrol[mode]
|
||||||
|
|
||||||
|
/* 32-bit form */
|
||||||
|
if (inst->size == 4)
|
||||||
|
{
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 64-bit form */
|
||||||
|
else if (inst->size == 8)
|
||||||
|
{
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore control word and proceed */
|
||||||
|
emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
||||||
|
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SSE4.1 case */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 32-bit form */
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_roundss_r128_m32_imm(&dst, REG_XMM0, MABS(drcbe, srcp.value), fprnd_map[mode]);
|
||||||
|
// roundss xmm0,[srcp],mode
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_roundss_r128_r128_imm(&dst, REG_XMM0, srcp.value, fprnd_map[mode]); // roundss xmm0,srcp,mode
|
||||||
|
|
||||||
|
/* store to the destination */
|
||||||
|
if (dstp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_movd_m32_r128(&dst, MABS(drcbe, dstp.value), REG_XMM0); // movd [dstp],xmm0
|
||||||
|
else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
|
||||||
|
emit_movd_r32_r128(&dst, dstp.value, REG_XMM0); // movd dstp,xmm0
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi4r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_ROUND);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_ROUND])); // ldmxcsr fpcontrol[DRCUML_FMOD_ROUND]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
op_ftoi4f - process a FTOI4F opcode
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi4f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_FLOOR);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_FLOOR])); // ldmxcsr fpcontrol[DRCUML_FMOD_FLOOR]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
op_ftoi4c - process a FTOI4C opcode
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi4c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi4x(drcbe, dst, inst, DRCUML_FMOD_CEIL);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_CEIL])); // ldmxcsr fpcontrol[DRCUML_FMOD_CEIL]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6886,146 +6848,87 @@ static x86code *op_ftoi8t(drcbe_state *drcbe, x86code *dst, const drcuml_instruc
|
|||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
op_ftoi8r - process a FTOI8R opcode
|
op_ftoi8x - process a FTOI8R/F/C opcode
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static x86code *op_ftoi8x(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst, int mode)
|
||||||
|
{
|
||||||
|
drcuml_parameter dstp, srcp;
|
||||||
|
int dstreg;
|
||||||
|
|
||||||
|
/* validate instruction */
|
||||||
|
assert(inst->size == 4 || inst->size == 8);
|
||||||
|
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
||||||
|
|
||||||
|
/* normalize parameters */
|
||||||
|
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
||||||
|
|
||||||
|
/* pick a target register for the general case */
|
||||||
|
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
||||||
|
|
||||||
|
/* non-SSE4.1 case */
|
||||||
|
if (!drcbe->sse41 || inst->size == 4)
|
||||||
|
{
|
||||||
|
/* save and set the control word */
|
||||||
|
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
||||||
|
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[mode])); // ldmxcsr fpcontrol[mode]
|
||||||
|
|
||||||
|
/* 32-bit form */
|
||||||
|
if (inst->size == 4)
|
||||||
|
{
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 64-bit form */
|
||||||
|
else if (inst->size == 8)
|
||||||
|
{
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore control word and proceed */
|
||||||
|
emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
||||||
|
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SSE4.1 case */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 64-bit form */
|
||||||
|
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_roundsd_r128_m64_imm(&dst, REG_XMM0, MABS(drcbe, srcp.value), fprnd_map[mode]);
|
||||||
|
// roundsd xmm0,[srcp],mode
|
||||||
|
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
||||||
|
emit_roundsd_r128_r128_imm(&dst, REG_XMM0, srcp.value, fprnd_map[mode]); // roundsd xmm0,srcp,mode
|
||||||
|
|
||||||
|
/* store to the destination */
|
||||||
|
if (dstp.type == DRCUML_PTYPE_MEMORY)
|
||||||
|
emit_movq_m64_r128(&dst, MABS(drcbe, dstp.value), REG_XMM0); // movq [dstp],xmm0
|
||||||
|
else if (dstp.type == DRCUML_PTYPE_INT_REGISTER)
|
||||||
|
emit_movq_r64_r128(&dst, dstp.value, REG_XMM0); // movq dstp,xmm0
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi8r(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_ROUND);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_ROUND])); // ldmxcsr fpcontrol[DRCUML_FMOD_ROUND]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
op_ftoi8f - process a FTOI8F opcode
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi8f(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_FLOOR);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_FLOOR])); // ldmxcsr fpcontrol[DRCUML_FMOD_FLOOR]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
|
||||||
op_ftoi8c - process a FTOI8C opcode
|
|
||||||
-------------------------------------------------*/
|
|
||||||
|
|
||||||
static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
static x86code *op_ftoi8c(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst)
|
||||||
{
|
{
|
||||||
drcuml_parameter dstp, srcp;
|
return op_ftoi8x(drcbe, dst, inst, DRCUML_FMOD_CEIL);
|
||||||
int dstreg;
|
|
||||||
|
|
||||||
/* validate instruction */
|
|
||||||
assert(inst->size == 4 || inst->size == 8);
|
|
||||||
assert(inst->condflags == DRCUML_COND_ALWAYS);
|
|
||||||
|
|
||||||
/* normalize parameters */
|
|
||||||
param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF);
|
|
||||||
|
|
||||||
/* pick a target register for the general case */
|
|
||||||
dstreg = param_select_register(REG_EAX, &dstp, NULL);
|
|
||||||
|
|
||||||
/* save and set the control word */
|
|
||||||
emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave]
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[DRCUML_FMOD_CEIL])); // ldmxcsr fpcontrol[DRCUML_FMOD_CEIL]
|
|
||||||
|
|
||||||
/* 32-bit form */
|
|
||||||
if (inst->size == 4)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 64-bit form */
|
|
||||||
else if (inst->size == 8)
|
|
||||||
{
|
|
||||||
if (srcp.type == DRCUML_PTYPE_MEMORY)
|
|
||||||
emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp]
|
|
||||||
else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER)
|
|
||||||
emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp
|
|
||||||
}
|
|
||||||
|
|
||||||
/* restore control word and proceed */
|
|
||||||
emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg
|
|
||||||
emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave]
|
|
||||||
return dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2967,8 +2967,8 @@ INLINE void emit_cvttss2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg)
|
|||||||
INLINE void emit_cvttss2si_r64_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, MEMPARAMS); }
|
INLINE void emit_cvttss2si_r64_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, MEMPARAMS); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INLINE void emit_roundss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
INLINE void emit_roundss_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
||||||
INLINE void emit_roundss_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
INLINE void emit_roundss_r128_m32_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3086,8 +3086,8 @@ INLINE void emit_cvttsd2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg)
|
|||||||
INLINE void emit_cvttsd2si_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, MEMPARAMS); }
|
INLINE void emit_cvttsd2si_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, MEMPARAMS); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
INLINE void emit_roundsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
INLINE void emit_roundsd_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
||||||
INLINE void emit_roundsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
INLINE void emit_roundsd_r128_m64_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -3138,7 +3138,7 @@ INLINE void emit_cvtpd2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPA
|
|||||||
INLINE void emit_cvttpd2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); }
|
INLINE void emit_cvttpd2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); }
|
||||||
INLINE void emit_cvttpd2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, MEMPARAMS); }
|
INLINE void emit_cvttpd2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, MEMPARAMS); }
|
||||||
|
|
||||||
INLINE void emit_roundpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
INLINE void emit_roundpd_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); }
|
||||||
INLINE void emit_roundpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
INLINE void emit_roundpd_r128_m128_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user