Skip to content
Permalink
Browse files
[SIMD] Intel support for conversions
https://bugs.webkit.org/show_bug.cgi?id=248973
rdar://103144338

Reviewed by Yusuke Suzuki.

https://github.com/WebAssembly/simd/blob/main/proposals/simd/SIMD.md#conversions
Add support for conversion operations except for
```
f64x2.convert_low_i32x4_u(a: v128) -> v128
i32x4.trunc_sat_f32x4_s(a: v128) -> v128
i32x4.trunc_sat_f32x4_u(a: v128) -> v128
```

* Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::supportsAVX):
* Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::vectorTruncSat):
(JSC::MacroAssemblerX86_64::vectorSignedTruncSatF64):
(JSC::MacroAssemblerX86_64::vectorUnsignedTruncSatF64):
(JSC::MacroAssemblerX86_64::vectorExtendLow):
(JSC::MacroAssemblerX86_64::vectorExtendHigh):
(JSC::MacroAssemblerX86_64::vectorPromote):
(JSC::MacroAssemblerX86_64::vectorDemote):
(JSC::MacroAssemblerX86_64::vectorNarrow):
(JSC::MacroAssemblerX86_64::vectorConvert):
(JSC::MacroAssemblerX86_64::vectorConvertUnsigned):
(JSC::MacroAssemblerX86_64::vectorConvertLow):
* Source/JavaScriptCore/assembler/X86Assembler.h:
(JSC::X86Assembler::vunpcklps_rr):
(JSC::X86Assembler::vshufps_rr):
(JSC::X86Assembler::pxor_rr):
(JSC::X86Assembler::pblendw_rr):
(JSC::X86Assembler::vpmulhrsw_rr):
(JSC::X86Assembler::addps_rr):
(JSC::X86Assembler::psubd_rr):
(JSC::X86Assembler::cvtdq2ps_rr):
(JSC::X86Assembler::vcvtdq2ps_rr):
(JSC::X86Assembler::cvtdq2pd_rr):
(JSC::X86Assembler::vcvtdq2pd_rr):
(JSC::X86Assembler::vsubpd_rr):
(JSC::X86Assembler::vxorpd_rr):
(JSC::X86Assembler::vmaxpd_rr):
(JSC::X86Assembler::vminpd_rr):
(JSC::X86Assembler::vroundpd_rr):
(JSC::X86Assembler::vaddpd_rr):
(JSC::X86Assembler::vcmppd_rr):
(JSC::X86Assembler::vcmpeqpd_rr):
(JSC::X86Assembler::vcvttpd2dq_rr):
(JSC::X86Assembler::vandpd_rr):
(JSC::X86Assembler::vcvtpd2ps_rr):
(JSC::X86Assembler::vcvtps2pd_rr):
(JSC::X86Assembler::packsswb_rr):
(JSC::X86Assembler::vpacksswb_rr):
(JSC::X86Assembler::packuswb_rr):
(JSC::X86Assembler::vpackuswb_rr):
(JSC::X86Assembler::packssdw_rr):
(JSC::X86Assembler::vpackssdw_rr):
(JSC::X86Assembler::packusdw_rr):
(JSC::X86Assembler::vpackusdw_rr):
(JSC::X86Assembler::pmovsxbw):
(JSC::X86Assembler::vpmovsxbw):
(JSC::X86Assembler::pmovzxbw):
(JSC::X86Assembler::vpmovzxbw):
(JSC::X86Assembler::pmovsxwd):
(JSC::X86Assembler::vpmovsxwd):
(JSC::X86Assembler::pmovzxwd):
(JSC::X86Assembler::vpmovzxwd):
(JSC::X86Assembler::pmovsxdq):
(JSC::X86Assembler::vpmovsxdq):
(JSC::X86Assembler::pmovzxdq):
(JSC::X86Assembler::vpmovzxdq):
(JSC::X86Assembler::vupckhpd):
(JSC::X86Assembler::psrld_i8r):
(JSC::X86Assembler::X86InstructionFormatter::SingleInstructionBufferWriter::memoryModRM):
* Source/JavaScriptCore/b3/air/AirOpcode.opcodes:
* Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addSIMDV_V):

Canonical link: https://commits.webkit.org/257592@main
  • Loading branch information
hyjorc1 authored and Yijia Huang committed Dec 8, 2022
1 parent 3e568e3 commit 1bb041b2af7af0a06a451fa6f1a536d453781647
Show file tree
Hide file tree
Showing 4 changed files with 651 additions and 44 deletions.
@@ -2844,9 +2844,37 @@ class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
{
ASSERT(scalarTypeIsFloatingPoint(simdInfo.lane));
ASSERT(simdInfo.signMode != SIMDSignMode::None);
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(input);
UNUSED_PARAM(dest);
ASSERT(simdInfo.lane == SIMDLane::f32x4);
UNUSED_PARAM(input); UNUSED_PARAM(dest); UNUSED_PARAM(simdInfo);
// FIXME: Need to support
// i32x4.trunc_sat_f32x4_s(a: v128) -> v128
// i32x4.trunc_sat_f32x4_u(a: v128) -> v128
}

void vectorSignedTruncSatF64(FPRegisterID x, FPRegisterID y, FPRegisterID f62x2, FPRegisterID tmp)
{
if (supportsAVX()) {
// https://github.com/WebAssembly/simd/pull/383
m_assembler.vcmpeqpd_rr(x, x, tmp);
m_assembler.vandpd_rr(f62x2, tmp, tmp);
m_assembler.vminpd_rr(tmp, x, y);
m_assembler.vcvttpd2dq_rr(y, y);
} else
RELEASE_ASSERT_NOT_REACHED();
}

void vectorUnsignedTruncSatF64(FPRegisterID x, FPRegisterID y, FPRegisterID f62x2_1, FPRegisterID f62x2_2, FPRegisterID tmp)
{
if (supportsAVX()) {
// https://github.com/WebAssembly/simd/pull/383
m_assembler.vxorpd_rr(tmp, tmp, tmp);
m_assembler.vmaxpd_rr(tmp, x, y);
m_assembler.vminpd_rr(f62x2_1, y, y);
m_assembler.vroundpd_rr(0x0B, y, y);
m_assembler.vaddpd_rr(f62x2_2, y, y);
m_assembler.vshufps_rr(0x88, tmp, y, y);
} else
RELEASE_ASSERT_NOT_REACHED();
}

void vectorNearest(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
@@ -2865,57 +2893,179 @@ class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
UNUSED_PARAM(input); UNUSED_PARAM(dest); UNUSED_PARAM(simdInfo);
}

void vectorExtendLow(SIMDInfo, FPRegisterID, FPRegisterID)
void vectorExtendLow(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
{
switch (simdInfo.lane) {
case SIMDLane::i16x8:
if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vpmovsxbw(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovsxbw(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
} else {
if (supportsAVX())
m_assembler.vpmovzxbw(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovzxbw(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
}
return;
case SIMDLane::i32x4:
if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vpmovsxwd(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovsxwd(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
} else {
if (supportsAVX())
m_assembler.vpmovzxwd(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovzxwd(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
}
return;
case SIMDLane::i64x2:
if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vpmovsxdq(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovsxdq(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
} else {
if (supportsAVX())
m_assembler.vpmovzxdq(input, dest);
else if (supportsSSE4_1())
m_assembler.pmovzxdq(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
}
return;
default:
RELEASE_ASSERT_NOT_REACHED();
}
}

void vectorExtendHigh(SIMDInfo, FPRegisterID, FPRegisterID)
void vectorExtendHigh(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
{
if (supportsAVX())
m_assembler.vupckhpd(dest, input, dest);
else {
if (input != dest)
m_assembler.movapd_rr(input, dest);
m_assembler.shufpd_rr(1, dest, dest);
}
vectorExtendLow(simdInfo, dest, dest);
}

void vectorPromote(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
{
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(input);
UNUSED_PARAM(dest);
ASSERT(simdInfo.lane == SIMDLane::f32x4);
ASSERT_UNUSED(simdInfo, simdInfo.lane == SIMDLane::f32x4);
if (supportsAVX())
m_assembler.vcvtps2pd_rr(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
}

void vectorDemote(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
{
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(input);
UNUSED_PARAM(dest);
ASSERT(simdInfo.lane == SIMDLane::f64x2);
ASSERT_UNUSED(simdInfo, simdInfo.lane == SIMDLane::f64x2);
if (supportsAVX())
m_assembler.vcvtpd2ps_rr(input, dest);
else
RELEASE_ASSERT_NOT_REACHED();
}

void vectorNarrow(SIMDInfo simdInfo, FPRegisterID lower, FPRegisterID upper, FPRegisterID dest, FPRegisterID)
{
ASSERT(simdInfo.signMode != SIMDSignMode::None);
ASSERT(scalarTypeIsIntegral(simdInfo.lane));
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(lower);
UNUSED_PARAM(upper);
UNUSED_PARAM(dest);

switch (simdInfo.lane) {
case SIMDLane::i16x8:
if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vpacksswb_rr(upper, lower, dest);
else {
if (lower != dest)
m_assembler.movapd_rr(lower, dest);
m_assembler.packsswb_rr(upper, dest);
}
} else {
if (supportsAVX())
m_assembler.vpackuswb_rr(upper, lower, dest);
else {
if (lower != dest)
m_assembler.movapd_rr(lower, dest);
m_assembler.packuswb_rr(upper, dest);
}
}
return;
case SIMDLane::i32x4:
if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vpackssdw_rr(upper, lower, dest);
else {
if (lower != dest)
m_assembler.movapd_rr(lower, dest);
m_assembler.packssdw_rr(upper, dest);
}
} else {
if (supportsAVX())
m_assembler.vpackusdw_rr(upper, lower, dest);
else if (supportsSSE4_1()) {
if (lower != dest)
m_assembler.movapd_rr(lower, dest);
m_assembler.packusdw_rr(upper, dest);
} else
RELEASE_ASSERT_NOT_REACHED();
}
return;
default:
RELEASE_ASSERT_NOT_REACHED();
}
}

void vectorConvert(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
{
ASSERT(scalarTypeIsIntegral(simdInfo.lane));
ASSERT_UNUSED(simdInfo, scalarTypeIsIntegral(simdInfo.lane));
ASSERT(elementByteSize(simdInfo.lane) == 4);
ASSERT(simdInfo.signMode != SIMDSignMode::None);
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(input);
UNUSED_PARAM(dest);
ASSERT(simdInfo.signMode == SIMDSignMode::Signed);
if (supportsAVX())
m_assembler.vcvtdq2ps_rr(input, dest);
else
m_assembler.cvtdq2ps_rr(input, dest);
}

void vectorConvertLow(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest)
void vectorConvertUnsigned(FPRegisterID input, FPRegisterID dest, FPRegisterID scratch)
{
UNUSED_PARAM(input); UNUSED_PARAM(dest); UNUSED_PARAM(scratch);
}

void vectorConvertLow(SIMDInfo simdInfo, FPRegisterID input, FPRegisterID dest, FPRegisterID scratch1, FPRegisterID scratch2)
{
ASSERT(scalarTypeIsIntegral(simdInfo.lane));
ASSERT(elementByteSize(simdInfo.lane) == 4);
UNUSED_PARAM(simdInfo);
UNUSED_PARAM(input);
UNUSED_PARAM(dest);

if (simdInfo.signMode == SIMDSignMode::Signed) {
if (supportsAVX())
m_assembler.vcvtdq2pd_rr(input, dest);
else
m_assembler.cvtdq2pd_rr(input, dest);
} else {
if (supportsAVX()) {
// https://github.com/WebAssembly/simd/pull/383
m_assembler.vunpcklps_rr(scratch1, input, dest);
m_assembler.vsubpd_rr(scratch2, dest, dest);
} else
RELEASE_ASSERT_NOT_REACHED();
}
}

void vectorSplat(SIMDLane lane, RegisterID src, FPRegisterID dest)

0 comments on commit 1bb041b

Please sign in to comment.