mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-09 14:08:58 +01:00
x64: add support for some x87 instructions
This commit is contained in:
parent
47d17aef80
commit
c25c4a6e20
@ -204,7 +204,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
|
|||||||
{
|
{
|
||||||
// Oh, RIP addressing.
|
// Oh, RIP addressing.
|
||||||
_offsetOrBaseReg = 5;
|
_offsetOrBaseReg = 5;
|
||||||
emit->WriteModRM(0, _operandReg&7, 5);
|
emit->WriteModRM(0, _operandReg, _offsetOrBaseReg);
|
||||||
//TODO : add some checks
|
//TODO : add some checks
|
||||||
#ifdef _M_X64
|
#ifdef _M_X64
|
||||||
u64 ripAddr = (u64)emit->GetCodePtr() + 4 + extraBytes;
|
u64 ripAddr = (u64)emit->GetCodePtr() + 4 + extraBytes;
|
||||||
@ -328,7 +328,6 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// W = operand extended width (1 if 64-bit)
|
// W = operand extended width (1 if 64-bit)
|
||||||
// R = register# upper bit
|
// R = register# upper bit
|
||||||
// X = scale amnt upper bit
|
// X = scale amnt upper bit
|
||||||
@ -1510,6 +1509,24 @@ void XEmitter::FWAIT()
|
|||||||
Write8(0x9B);
|
Write8(0x9B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: make this more generic
|
||||||
|
void XEmitter::WriteFloatLoadStore(int bits, FloatOp op, OpArg arg)
|
||||||
|
{
|
||||||
|
int mf = 0;
|
||||||
|
switch (bits) {
|
||||||
|
case 32: mf = 0; break;
|
||||||
|
case 64: mf = 2; break;
|
||||||
|
default: _assert_msg_(DYNA_REC, 0, "WriteFloatLoadStore: bits is not 32 or 64");
|
||||||
|
}
|
||||||
|
Write8(0xd9 | (mf << 1));
|
||||||
|
// x87 instructions use the reg field of the ModR/M byte as opcode:
|
||||||
|
arg.WriteRest(this, 0, (X64Reg) op);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XEmitter::FLD(int bits, OpArg src) {WriteFloatLoadStore(bits, floatLD, src);}
|
||||||
|
void XEmitter::FST(int bits, OpArg dest) {WriteFloatLoadStore(bits, floatST, dest);}
|
||||||
|
void XEmitter::FSTP(int bits, OpArg dest) {WriteFloatLoadStore(bits, floatSTP, dest);}
|
||||||
|
|
||||||
void XEmitter::RTDSC() { Write8(0x0F); Write8(0x31); }
|
void XEmitter::RTDSC() { Write8(0x0F); Write8(0x31); }
|
||||||
|
|
||||||
// helper routines for setting pointers
|
// helper routines for setting pointers
|
||||||
|
@ -97,6 +97,12 @@ enum NormalOp {
|
|||||||
nrmXCHG,
|
nrmXCHG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FloatOp {
|
||||||
|
floatLD = 0,
|
||||||
|
floatST = 2,
|
||||||
|
floatSTP = 3,
|
||||||
|
};
|
||||||
|
|
||||||
class XEmitter;
|
class XEmitter;
|
||||||
|
|
||||||
// RIP addressing does not benefit from micro op fusion on Core arch
|
// RIP addressing does not benefit from micro op fusion on Core arch
|
||||||
@ -115,6 +121,7 @@ struct OpArg
|
|||||||
void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const;
|
void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const;
|
||||||
void WriteVex(XEmitter* emit, int size, int packed, Gen::X64Reg regOp1, X64Reg regOp2) const;
|
void WriteVex(XEmitter* emit, int size, int packed, Gen::X64Reg regOp1, X64Reg regOp2) const;
|
||||||
void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=(X64Reg)0xFF, bool warn_64bit_offset = true) const;
|
void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=(X64Reg)0xFF, bool warn_64bit_offset = true) const;
|
||||||
|
void WriteFloatModRM(XEmitter *emit, FloatOp op);
|
||||||
void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits);
|
void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits);
|
||||||
// This one is public - must be written to
|
// This one is public - must be written to
|
||||||
u64 offset; // use RIP-relative as much as possible - 64-bit immediates are not available.
|
u64 offset; // use RIP-relative as much as possible - 64-bit immediates are not available.
|
||||||
@ -244,6 +251,7 @@ private:
|
|||||||
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
void WriteSSEOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
||||||
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp, OpArg arg, int extrabytes = 0);
|
||||||
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
void WriteAVXOp(int size, u8 sseOp, bool packed, X64Reg regOp1, X64Reg regOp2, OpArg arg, int extrabytes = 0);
|
||||||
|
void WriteFloatLoadStore(int bits, FloatOp op, OpArg arg);
|
||||||
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg &a1, const OpArg &a2);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -424,6 +432,10 @@ public:
|
|||||||
void REP();
|
void REP();
|
||||||
void REPNE();
|
void REPNE();
|
||||||
|
|
||||||
|
// x87
|
||||||
|
void FLD(int bits, OpArg src);
|
||||||
|
void FST(int bits, OpArg dest);
|
||||||
|
void FSTP(int bits, OpArg dest);
|
||||||
void FWAIT();
|
void FWAIT();
|
||||||
|
|
||||||
// SSE/SSE2: Floating point arithmetic
|
// SSE/SSE2: Floating point arithmetic
|
||||||
|
Loading…
x
Reference in New Issue
Block a user