mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
UML: Added FCOPYI and ICOPYF instructions to pass raw data between integer and floating-point registers. [Ville Linde]
This commit is contained in:
parent
26c8434a70
commit
e49f3ccb97
@ -1929,6 +1929,14 @@ int drcbe_c::execute(code_handle &entry)
|
||||
FSPARAM0 = 1.0f / sqrtf(FSPARAM1);
|
||||
break;
|
||||
|
||||
case MAKE_OPCODE_SHORT(OP_FCOPYI, 4, 0): // FSCOPYI dst,src
|
||||
FSPARAM0 = u2f(*inst[1].pint32);
|
||||
break;
|
||||
|
||||
case MAKE_OPCODE_SHORT(OP_ICOPYF, 4, 0): // ICOPYFS dst,src
|
||||
*inst[0].pint32 = f2u(FSPARAM1);
|
||||
break;
|
||||
|
||||
|
||||
// ----------------------- 64-Bit Floating Point Operations -----------------------
|
||||
|
||||
@ -2068,6 +2076,14 @@ int drcbe_c::execute(code_handle &entry)
|
||||
FDPARAM0 = 1.0 / sqrt(FDPARAM1);
|
||||
break;
|
||||
|
||||
case MAKE_OPCODE_SHORT(OP_FCOPYI, 8, 0): // FDCOPYI dst,src
|
||||
FDPARAM0 = u2d(*inst[1].pint64);
|
||||
break;
|
||||
|
||||
case MAKE_OPCODE_SHORT(OP_ICOPYF, 8, 0): // ICOPYFD dst,src
|
||||
*inst[0].pint64 = d2u(FDPARAM1);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unexpected opcode!\n");
|
||||
}
|
||||
|
@ -388,7 +388,9 @@ const drcbe_x64::opcode_table_entry drcbe_x64::s_opcode_table_source[] =
|
||||
{ uml::OP_FABS, &drcbe_x64::op_fabs }, // FABS dst,src1
|
||||
{ uml::OP_FSQRT, &drcbe_x64::op_fsqrt }, // FSQRT dst,src1
|
||||
{ uml::OP_FRECIP, &drcbe_x64::op_frecip }, // FRECIP dst,src1
|
||||
{ uml::OP_FRSQRT, &drcbe_x64::op_frsqrt } // FRSQRT dst,src1
|
||||
{ uml::OP_FRSQRT, &drcbe_x64::op_frsqrt }, // FRSQRT dst,src1
|
||||
{ uml::OP_FCOPYI, &drcbe_x64::op_fcopyi }, // FCOPYI dst,src
|
||||
{ uml::OP_ICOPYF, &drcbe_x64::op_icopyf } // ICOPYF dst,src
|
||||
};
|
||||
|
||||
|
||||
@ -6707,3 +6709,131 @@ void drcbe_x64::op_frsqrt(x86code *&dst, const instruction &inst)
|
||||
emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// op_fcopyi - process a FCOPYI opcode
|
||||
//-------------------------------------------------
|
||||
|
||||
void drcbe_x64::op_fcopyi(x86code *&dst, const instruction &inst)
|
||||
{
|
||||
// validate instruction
|
||||
assert(inst.size() == 4 || inst.size() == 8);
|
||||
assert_no_condition(inst);
|
||||
assert_no_flags(inst);
|
||||
|
||||
// normalize parameters
|
||||
be_parameter dstp(*this, inst.param(0), PTYPE_MF);
|
||||
be_parameter srcp(*this, inst.param(1), PTYPE_MR);
|
||||
|
||||
// pick a target register for the general case
|
||||
int dstreg = dstp.select_register(REG_XMM0);
|
||||
|
||||
// 32-bit form
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
emit_movd_r128_m32(dst, dstreg, MABS(srcp.memory())); // movd dstreg,[srcp]
|
||||
emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_mov_p32_r32(dst, dstp, srcp.ireg()); // mov dstp,srcp
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_movd_r128_r32(dst, dstreg, srcp.ireg()); // movd dstreg,srcp
|
||||
emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 64-bit form
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
emit_movq_r128_m64(dst, dstreg, MABS(srcp.memory())); // movq dstreg,[srcp]
|
||||
emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_mov_p64_r64(dst, dstp, srcp.ireg()); // mov dstp,srcp
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_movq_r128_r64(dst, dstreg, srcp.ireg()); // movq dstreg,srcp
|
||||
emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// op_icopyf - process a ICOPYF opcode
|
||||
//-------------------------------------------------
|
||||
|
||||
void drcbe_x64::op_icopyf(x86code *&dst, const instruction &inst)
|
||||
{
|
||||
// validate instruction
|
||||
assert(inst.size() == 4 || inst.size() == 8);
|
||||
assert_no_condition(inst);
|
||||
assert_no_flags(inst);
|
||||
|
||||
// normalize parameters
|
||||
be_parameter dstp(*this, inst.param(0), PTYPE_MR);
|
||||
be_parameter srcp(*this, inst.param(1), PTYPE_MF);
|
||||
|
||||
// 32-bit form
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
int dstreg = dstp.select_register(REG_EAX);
|
||||
emit_mov_r32_m32(dst, dstreg, MABS(srcp.memory())); // mov dstreg,[srcp]
|
||||
emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_movd_m32_r128(dst, MABS(dstp.memory()), srcp.freg()); // movd dstp,srcp
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_movd_r32_r128(dst, dstp.ireg(), srcp.freg()); // movd dstp,srcp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 64-bit form
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
int dstreg = dstp.select_register(REG_RAX);
|
||||
emit_mov_r64_m64(dst, dstreg, MABS(srcp.memory())); // mov dstreg,[srcp]
|
||||
emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_movq_m64_r128(dst, MABS(dstp.memory()), srcp.freg()); // movq dstp,srcp
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_movq_r64_r128(dst, dstp.ireg(), srcp.freg()); // movq dstp,srcp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -207,6 +207,8 @@ private:
|
||||
void op_fsqrt(x86code *&dst, const uml::instruction &inst);
|
||||
void op_frecip(x86code *&dst, const uml::instruction &inst);
|
||||
void op_frsqrt(x86code *&dst, const uml::instruction &inst);
|
||||
void op_fcopyi(x86code *&dst, const uml::instruction &inst);
|
||||
void op_icopyf(x86code *&dst, const uml::instruction &inst);
|
||||
|
||||
// 32-bit code emission helpers
|
||||
void emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m);
|
||||
|
@ -270,7 +270,9 @@ const drcbe_x86::opcode_table_entry drcbe_x86::s_opcode_table_source[] =
|
||||
{ uml::OP_FABS, &drcbe_x86::op_fabs }, // FABS dst,src1
|
||||
{ uml::OP_FSQRT, &drcbe_x86::op_fsqrt }, // FSQRT dst,src1
|
||||
{ uml::OP_FRECIP, &drcbe_x86::op_frecip }, // FRECIP dst,src1
|
||||
{ uml::OP_FRSQRT, &drcbe_x86::op_frsqrt } // FRSQRT dst,src1
|
||||
{ uml::OP_FRSQRT, &drcbe_x86::op_frsqrt }, // FRSQRT dst,src1
|
||||
{ uml::OP_FCOPYI, &drcbe_x86::op_fcopyi }, // FCOPYI dst,src
|
||||
{ uml::OP_ICOPYF, &drcbe_x86::op_icopyf }, // ICOPYF dst,src
|
||||
};
|
||||
|
||||
|
||||
@ -6448,6 +6450,105 @@ void drcbe_x86::op_frsqrt(x86code *&dst, const instruction &inst)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// op_fcopyi - process a FCOPYI opcode
|
||||
//-------------------------------------------------
|
||||
|
||||
void drcbe_x86::op_fcopyi(x86code *&dst, const instruction &inst)
|
||||
{
|
||||
// validate instruction
|
||||
assert(inst.size() == 4 || inst.size() == 8);
|
||||
assert_no_condition(inst);
|
||||
assert_no_flags(inst);
|
||||
|
||||
// normalize parameters
|
||||
be_parameter dstp(*this, inst.param(0), PTYPE_MF);
|
||||
be_parameter srcp(*this, inst.param(1), PTYPE_MR);
|
||||
|
||||
// 32-bit case
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp]
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax
|
||||
}
|
||||
else if (srcp.is_int_register())
|
||||
{
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory()), srcp.ireg()); // mov [dstp],srcp
|
||||
}
|
||||
}
|
||||
|
||||
// 64-bit case
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
if (srcp.is_memory())
|
||||
{
|
||||
emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp]
|
||||
emit_mov_r32_m32(dst, REG_EDX, MABS(srcp.memory(4))); // mov edx,[srcp+4]
|
||||
}
|
||||
else if (srcp.is_int_register())
|
||||
{
|
||||
emit_mov_r32_m32(dst, REG_EDX, MABS(m_reghi[srcp.ireg()])); // mov edx,[reghi[srcp]]
|
||||
emit_mov_r32_r32(dst, REG_EAX, srcp.ireg()); // mov eax,srcp
|
||||
}
|
||||
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// op_icopyf - process a ICOPYF opcode
|
||||
//-------------------------------------------------
|
||||
|
||||
void drcbe_x86::op_icopyf(x86code *&dst, const instruction &inst)
|
||||
{
|
||||
// validate instruction
|
||||
assert(inst.size() == 4 || inst.size() == 8);
|
||||
assert_no_condition(inst);
|
||||
assert_no_flags(inst);
|
||||
|
||||
// normalize parameters
|
||||
be_parameter dstp(*this, inst.param(0), PTYPE_MR);
|
||||
be_parameter srcp(*this, inst.param(1), PTYPE_MF);
|
||||
|
||||
// 32-bit case
|
||||
if (inst.size() == 4)
|
||||
{
|
||||
emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp]
|
||||
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax
|
||||
}
|
||||
else if (dstp.is_int_register())
|
||||
{
|
||||
emit_mov_r32_r32(dst, dstp.ireg(), REG_EAX); // mov dstp,eax
|
||||
}
|
||||
}
|
||||
|
||||
// 64-bit case
|
||||
else if (inst.size() == 8)
|
||||
{
|
||||
emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp]
|
||||
emit_mov_r32_m32(dst, REG_EDX, MABS(srcp.memory(4))); // mov edx,[srcp+4]
|
||||
|
||||
if (dstp.is_memory())
|
||||
{
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax
|
||||
emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_mov_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // mov [reghi[dstp]],edx
|
||||
emit_mov_r32_r32(dst, dstp.ireg(), REG_EAX); // mov dstp,eax
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MISCELLAENOUS FUNCTIONS
|
||||
|
@ -208,6 +208,8 @@ private:
|
||||
void op_fsqrt(x86code *&dst, const uml::instruction &inst);
|
||||
void op_frecip(x86code *&dst, const uml::instruction &inst);
|
||||
void op_frsqrt(x86code *&dst, const uml::instruction &inst);
|
||||
void op_fcopyi(x86code *&dst, const uml::instruction &inst);
|
||||
void op_icopyf(x86code *&dst, const uml::instruction &inst);
|
||||
|
||||
// 32-bit code emission helpers
|
||||
void emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m);
|
||||
|
@ -156,6 +156,8 @@
|
||||
#define UML_FSSQRT(block, dst, src1) do { block->append().fssqrt(dst, src1); } while (0)
|
||||
#define UML_FSRECIP(block, dst, src1) do { block->append().fsrecip(dst, src1); } while (0)
|
||||
#define UML_FSRSQRT(block, dst, src1) do { block->append().fsrsqrt(dst, src1); } while (0)
|
||||
#define UML_FSCOPYI(block, dst, src) do { block->append().fscopyi(dst, src); } while (0)
|
||||
#define UML_ICOPYFS(block, dst, src) do { block->append().icopyfs(dst, src); } while (0)
|
||||
|
||||
|
||||
/* ----- 64-bit Floating Point Arithmetic Operations ----- */
|
||||
@ -179,6 +181,8 @@
|
||||
#define UML_FDSQRT(block, dst, src1) do { block->append().fdsqrt(dst, src1); } while (0)
|
||||
#define UML_FDRECIP(block, dst, src1) do { block->append().fdrecip(dst, src1); } while (0)
|
||||
#define UML_FDRSQRT(block, dst, src1) do { block->append().fdrsqrt(dst, src1); } while (0)
|
||||
#define UML_FDCOPYI(block, dst, src) do { block->append().fdcopyi(dst, src); } while (0)
|
||||
#define UML_ICOPYFD(block, dst, src) do { block->append().icopyfd(dst, src); } while (0)
|
||||
|
||||
|
||||
#endif /* __DRCUMLSH_H__ */
|
||||
|
@ -22,9 +22,6 @@
|
||||
* Support for FPU exceptions
|
||||
|
||||
* New instructions?
|
||||
- FCOPYI, ICOPYF
|
||||
copy raw between float and integer registers
|
||||
|
||||
- VALID opcode_desc,handle,param
|
||||
checksum/compare code referenced by opcode_desc; if not
|
||||
matching, generate exception with handle,param
|
||||
@ -214,6 +211,8 @@ const opcode_info instruction::s_opcode_info_table[OP_MAX] =
|
||||
OPINFO2(FSQRT, "f#sqrt", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY))
|
||||
OPINFO2(FRECIP, "f#recip", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY))
|
||||
OPINFO2(FRSQRT, "f#rsqrt", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY))
|
||||
OPINFO2(FCOPYI, "f#copyi", 4|8, false, NONE, NONE, NONE, PINFO(OUT, OP, FRM), PINFO(IN, OP, IRM))
|
||||
OPINFO2(ICOPYF, "icopyf#", 4|8, false, NONE, NONE, NONE, PINFO(OUT, OP, IRM), PINFO(IN, OP, FRM))
|
||||
};
|
||||
|
||||
|
||||
|
@ -218,6 +218,8 @@ namespace uml
|
||||
OP_FSQRT, // FSQRT dst,src1
|
||||
OP_FRECIP, // FRECIP dst,src1
|
||||
OP_FRSQRT, // FRSQRT dst,src1
|
||||
OP_FCOPYI, // FCOPYI dst,src
|
||||
OP_ICOPYF, // ICOPYF dst,src
|
||||
|
||||
OP_MAX
|
||||
};
|
||||
@ -544,6 +546,8 @@ namespace uml
|
||||
void fssqrt(parameter dst, parameter src1) { configure(OP_FSQRT, 4, dst, src1); }
|
||||
void fsrecip(parameter dst, parameter src1) { configure(OP_FRECIP, 4, dst, src1); }
|
||||
void fsrsqrt(parameter dst, parameter src1) { configure(OP_FRSQRT, 4, dst, src1); }
|
||||
void fscopyi(parameter dst, parameter src) { configure(OP_FCOPYI, 4, dst, src); }
|
||||
void icopyfs(parameter dst, parameter src) { configure(OP_ICOPYF, 4, dst, src); }
|
||||
|
||||
// 64-bit floating point operations
|
||||
void fdload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); }
|
||||
@ -566,6 +570,8 @@ namespace uml
|
||||
void fdsqrt(parameter dst, parameter src1) { configure(OP_FSQRT, 8, dst, src1); }
|
||||
void fdrecip(parameter dst, parameter src1) { configure(OP_FRECIP, 8, dst, src1); }
|
||||
void fdrsqrt(parameter dst, parameter src1) { configure(OP_FRSQRT, 8, dst, src1); }
|
||||
void fdcopyi(parameter dst, parameter src) { configure(OP_FCOPYI, 8, dst, src); }
|
||||
void icopyfd(parameter dst, parameter src) { configure(OP_ICOPYF, 8, dst, src); }
|
||||
|
||||
// constants
|
||||
static const int MAX_PARAMS = 4;
|
||||
|
Loading…
Reference in New Issue
Block a user