[x64/Linux] More return __m128i by value in xmm0 rather than pointer
This commit is contained in:
@@ -2744,11 +2744,15 @@ struct PACK : Sequence<PACK, I<OPCODE_PACK, V128Op, V128Op, V128Op>> {
|
|||||||
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
// http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-f16c-and-fma.aspx
|
||||||
// dest = [(src1.x | src1.y), 0, 0, 0]
|
// dest = [(src1.x | src1.y), 0, 0, 0]
|
||||||
|
|
||||||
if (i.src1.is_constant) {
|
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
e.lea(e.GetNativeParam(0), e.StashConstantXmm(0, i.src1.constant()));
|
|
||||||
} else {
|
#if XE_PLATFORM_WIN32
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, i.src1));
|
// Windows x64 ABI: __m128 is passed by implicit pointer
|
||||||
}
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
|
#else
|
||||||
|
// Linux/Mac System V ABI: __m128 passed in xmm0, return in xmm0
|
||||||
|
e.vmovaps(e.xmm0, src1);
|
||||||
|
#endif
|
||||||
e.CallNativeSafe(reinterpret_cast<void*>(EmulateFLOAT16_2));
|
e.CallNativeSafe(reinterpret_cast<void*>(EmulateFLOAT16_2));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
}
|
}
|
||||||
@@ -2922,26 +2926,36 @@ struct PACK : Sequence<PACK, I<OPCODE_PACK, V128Op, V128Op, V128Op>> {
|
|||||||
if (IsPackOutUnsigned(flags)) {
|
if (IsPackOutUnsigned(flags)) {
|
||||||
if (IsPackOutSaturate(flags)) {
|
if (IsPackOutSaturate(flags)) {
|
||||||
// unsigned -> unsigned + saturate
|
// unsigned -> unsigned + saturate
|
||||||
if (i.src1.is_constant) {
|
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
e.lea(e.GetNativeParam(0),
|
auto src2 = GetInputRegOrConstant(e, i.src2, e.xmm4);
|
||||||
e.StashConstantXmm(0, i.src1.constant()));
|
|
||||||
} else {
|
#if XE_PLATFORM_WIN32
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, i.src1));
|
// Windows x64 ABI: __m128i is passed by implicit pointer
|
||||||
}
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
if (i.src2.is_constant) {
|
e.lea(e.GetNativeParam(1), e.StashXmm(1, src2));
|
||||||
e.lea(e.GetNativeParam(1),
|
#else
|
||||||
e.StashConstantXmm(1, i.src2.constant()));
|
// Linux/Mac System V ABI: __m128i passed in xmm0/xmm1, return in xmm0
|
||||||
} else {
|
e.vmovaps(e.xmm0, src1);
|
||||||
e.lea(e.GetNativeParam(1), e.StashXmm(1, i.src2));
|
e.vmovaps(e.xmm1, src2);
|
||||||
}
|
#endif
|
||||||
e.CallNativeSafe(
|
e.CallNativeSafe(
|
||||||
reinterpret_cast<void*>(EmulatePack8_IN_16_UN_UN_SAT));
|
reinterpret_cast<void*>(EmulatePack8_IN_16_UN_UN_SAT));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMByteOrderMask));
|
e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMByteOrderMask));
|
||||||
} else {
|
} else {
|
||||||
// unsigned -> unsigned
|
// unsigned -> unsigned
|
||||||
e.lea(e.GetNativeParam(1), e.StashXmm(1, i.src2));
|
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, i.src1));
|
auto src2 = GetInputRegOrConstant(e, i.src2, e.xmm4);
|
||||||
|
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
// Windows x64 ABI: __m128i is passed by implicit pointer
|
||||||
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
|
e.lea(e.GetNativeParam(1), e.StashXmm(1, src2));
|
||||||
|
#else
|
||||||
|
// Linux/Mac System V ABI: __m128i passed in xmm0/xmm1, return in xmm0
|
||||||
|
e.vmovaps(e.xmm0, src1);
|
||||||
|
e.vmovaps(e.xmm1, src2);
|
||||||
|
#endif
|
||||||
e.CallNativeSafe(reinterpret_cast<void*>(EmulatePack8_IN_16_UN_UN));
|
e.CallNativeSafe(reinterpret_cast<void*>(EmulatePack8_IN_16_UN_UN));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMByteOrderMask));
|
e.vpshufb(i.dest, i.dest, e.GetXmmConstPtr(XMMByteOrderMask));
|
||||||
@@ -3176,11 +3190,15 @@ struct UNPACK : Sequence<UNPACK, I<OPCODE_UNPACK, V128Op, V128Op>> {
|
|||||||
// Also zero out the high end.
|
// Also zero out the high end.
|
||||||
// TODO(benvanik): special case constant unpacks that just get 0/1/etc.
|
// TODO(benvanik): special case constant unpacks that just get 0/1/etc.
|
||||||
|
|
||||||
if (i.src1.is_constant) {
|
auto src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
e.lea(e.GetNativeParam(0), e.StashConstantXmm(0, i.src1.constant()));
|
|
||||||
} else {
|
#if XE_PLATFORM_WIN32
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, i.src1));
|
// Windows x64 ABI: __m128i is passed by implicit pointer
|
||||||
}
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
|
#else
|
||||||
|
// Linux/Mac System V ABI: __m128i passed in xmm0, return in xmm0
|
||||||
|
e.vmovaps(e.xmm0, src1);
|
||||||
|
#endif
|
||||||
e.CallNativeSafe(reinterpret_cast<void*>(EmulateFLOAT16_2));
|
e.CallNativeSafe(reinterpret_cast<void*>(EmulateFLOAT16_2));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2225,9 +2225,15 @@ struct POW2_V128 : Sequence<POW2_V128, I<OPCODE_POW2, V128Op, V128Op>> {
|
|||||||
}
|
}
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
||||||
Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
|
||||||
|
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
// Windows x64 ABI: __m128 is passed by implicit pointer
|
||||||
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
|
#else
|
||||||
|
// Linux/Mac System V ABI: __m128 passed in xmm0, return in xmm0
|
||||||
|
e.vmovaps(e.xmm0, src1);
|
||||||
|
#endif
|
||||||
e.CallNativeSafe(reinterpret_cast<void*>(EmulatePow2));
|
e.CallNativeSafe(reinterpret_cast<void*>(EmulatePow2));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
}
|
}
|
||||||
@@ -2261,10 +2267,15 @@ struct LOG2_V128 : Sequence<LOG2_V128, I<OPCODE_LOG2, V128Op, V128Op>> {
|
|||||||
}
|
}
|
||||||
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
static void Emit(X64Emitter& e, const EmitArgType& i) {
|
||||||
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
e.ChangeMxcsrMode(MXCSRMode::Vmx);
|
||||||
Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm0);
|
Xmm src1 = GetInputRegOrConstant(e, i.src1, e.xmm3);
|
||||||
|
|
||||||
|
#if XE_PLATFORM_WIN32
|
||||||
|
// Windows x64 ABI: __m128 is passed by implicit pointer
|
||||||
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
e.lea(e.GetNativeParam(0), e.StashXmm(0, src1));
|
||||||
|
#else
|
||||||
|
// Linux/Mac System V ABI: __m128 passed in xmm0, return in xmm0
|
||||||
|
e.vmovaps(e.xmm0, src1);
|
||||||
|
#endif
|
||||||
e.CallNativeSafe(reinterpret_cast<void*>(EmulateLog2));
|
e.CallNativeSafe(reinterpret_cast<void*>(EmulateLog2));
|
||||||
e.vmovaps(i.dest, e.xmm0);
|
e.vmovaps(i.dest, e.xmm0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user