diff options
author | Fei Peng <fei.peng@intel.com> | 2018-02-26 13:02:12 -0800 |
---|---|---|
committer | Tanner Gooding <tagoo@outlook.com> | 2018-02-26 19:08:13 -0800 |
commit | e61f7f44f8d115aaf688c3238f0e5d44e40dfb29 (patch) | |
tree | 211179946e23da48df6ffe10ac437454700a798c /src/jit/emitxarch.cpp | |
parent | ec78ba4a4467fff7ca069a3123788c96eeca2ebc (diff) | |
download | coreclr-e61f7f44f8d115aaf688c3238f0e5d44e40dfb29.tar.gz coreclr-e61f7f44f8d115aaf688c3238f0e5d44e40dfb29.tar.bz2 coreclr-e61f7f44f8d115aaf688c3238f0e5d44e40dfb29.zip |
Update the table-driven framework to support x86 imm-intrinsics.
And add a new range-check IR for x86 imm-intrinsics.
Diffstat (limited to 'src/jit/emitxarch.cpp')
-rw-r--r-- | src/jit/emitxarch.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp index 3a2f92b557..7e47ccfb7d 100644 --- a/src/jit/emitxarch.cpp +++ b/src/jit/emitxarch.cpp @@ -187,6 +187,14 @@ bool emitter::IsDstDstSrcAVXInstruction(instruction ins) case INS_psubusb: case INS_psubusw: case INS_psubw: + case INS_pslld: + case INS_psllq: + case INS_psllw: + case INS_psrld: + case INS_psrlq: + case INS_psrlw: + case INS_psrad: + case INS_psraw: case INS_punpckhbw: case INS_punpckhdq: case INS_punpckhqdq: @@ -209,6 +217,11 @@ bool emitter::IsDstDstSrcAVXInstruction(instruction ins) case INS_vinsertf128: case INS_vinserti128: case INS_vperm2i128: + case INS_vpsrlvd: + case INS_vpsrlvq: + case INS_vpsravd: + case INS_vpsllvd: + case INS_vpsllvq: case INS_xorpd: case INS_xorps: return IsAVXInstruction(ins); @@ -366,7 +379,7 @@ bool TakesRexWPrefix(instruction ins, emitAttr attr) // size specification (128 vs. 256 bits) and the operand size specification (32 vs. 64 bits), where both are // required, the instruction must be created with the register size attribute (EA_16BYTE or EA_32BYTE), // and here we must special case these by the opcode. - if (ins == INS_vpermq) + if (ins == INS_vpermq || ins == INS_vpsrlvq || ins == INS_vpsllvq) { return true; } @@ -5479,6 +5492,50 @@ void emitter::emitIns_SIMD_R_R_R(instruction ins, emitAttr attr, regNumber reg, } } +static bool isSseShift(instruction ins) +{ + switch (ins) + { + case INS_psrldq: + case INS_pslldq: + case INS_psrld: + case INS_psrlw: + case INS_psrlq: + case INS_pslld: + case INS_psllw: + case INS_psllq: + case INS_psrad: + case INS_psraw: + return true; + default: + return false; + } +} + +void emitter::emitIns_SIMD_R_R_I(instruction ins, emitAttr attr, regNumber reg, regNumber reg1, int ival) +{ + // TODO-XARCH refactoring emitIns_R_R_I to handle SSE2/AVX2 shift as well as emitIns_R_I + bool isShift = isSseShift(ins); + if (UseVEXEncoding() && !isShift) + { + emitIns_R_R_I(ins, attr, reg, reg1, ival); + } + else + { + if (reg1 != reg) + { + emitIns_R_R(INS_movaps, attr, reg, reg1); + } + // TODO-XARCH-BUG emitOutputRI cannot work with SSE2 shift instruction on imm8 > 127, so we replace it by the + // semantic alternatives. https://github.com/dotnet/coreclr/issues/16543 + if (isShift && ival > 127) + { + ival = 127; + } + emitIns_R_I(ins, attr, reg, ival); + } +} + void emitter::emitIns_SIMD_R_R_R_R( instruction ins, emitAttr attr, regNumber reg, regNumber reg1, regNumber reg2, regNumber reg3) { @@ -10746,6 +10803,7 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id) regOpcode = (regNumber)6; break; case INS_psrad: + case INS_psraw: regOpcode = (regNumber)4; break; default: |