diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrXOP.td | 93 |
3 files changed, 75 insertions, 52 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 8fb33512fc6..15a09ee61bb 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -5411,18 +5411,7 @@ MachineInstr *X86InstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI, case X86::VPCOMWri: case X86::VPCOMUWri: { // Flip comparison mode immediate (if necessary). unsigned Imm = MI.getOperand(3).getImm() & 0x7; - switch (Imm) { - default: llvm_unreachable("Unreachable!"); - case 0x00: Imm = 0x02; break; // LT -> GT - case 0x01: Imm = 0x03; break; // LE -> GE - case 0x02: Imm = 0x00; break; // GT -> LT - case 0x03: Imm = 0x01; break; // GE -> LE - case 0x04: // EQ - case 0x05: // NE - case 0x06: // FALSE - case 0x07: // TRUE - break; - } + Imm = X86::getSwappedVPCOMImm(Imm); auto &WorkingMI = cloneIfNew(MI); WorkingMI.getOperand(3).setImm(Imm); return TargetInstrInfo::commuteInstructionImpl(WorkingMI, /*NewMI=*/false, @@ -6140,6 +6129,24 @@ unsigned X86::getSwappedVPCMPImm(unsigned Imm) { return Imm; } +/// \brief Get the VPCOM immediate if the opcodes are swapped. +unsigned X86::getSwappedVPCOMImm(unsigned Imm) { + switch (Imm) { + default: llvm_unreachable("Unreachable!"); + case 0x00: Imm = 0x02; break; // LT -> GT + case 0x01: Imm = 0x03; break; // LE -> GE + case 0x02: Imm = 0x00; break; // GT -> LT + case 0x03: Imm = 0x01; break; // GE -> LE + case 0x04: // EQ + case 0x05: // NE + case 0x06: // FALSE + case 0x07: // TRUE + break; + } + + return Imm; +} + bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const { if (!MI.isTerminator()) return false; diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 5a2e00152e8..8bb90eb4ffe 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -87,6 +87,9 @@ CondCode GetOppositeBranchCondition(CondCode CC); /// \brief Get the VPCMP immediate if the opcodes are swapped. unsigned getSwappedVPCMPImm(unsigned Imm); +/// \brief Get the VPCOM immediate if the opcodes are swapped. +unsigned getSwappedVPCOMImm(unsigned Imm); + } // namespace X86 /// isGlobalStubReference - Return true if the specified TargetFlag operand is diff --git a/llvm/lib/Target/X86/X86InstrXOP.td b/llvm/lib/Target/X86/X86InstrXOP.td index 435dd2498ce..7f776a6c760 100644 --- a/llvm/lib/Target/X86/X86InstrXOP.td +++ b/llvm/lib/Target/X86/X86InstrXOP.td @@ -211,52 +211,65 @@ let Predicates = [HasXOP] in { (VPMADCSWDrr VR128:$src1, VR128:$src2, VR128:$src3)>; } +// Transforms to swizzle an immediate to help matching memory operand in first +// operand. +def CommuteVPCOMCC : SDNodeXForm<imm, [{ + uint8_t Imm = N->getZExtValue() & 0x7; + Imm = X86::getSwappedVPCOMImm(Imm); + return getI8Imm(Imm, SDLoc(N)); +}]>; + // Instruction where second source can be memory, third must be imm8 multiclass xopvpcom<bits<8> opc, string Suffix, SDNode OpNode, ValueType vt128> { - let isCommutable = 1 in - def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), - (ins VR128:$src1, VR128:$src2, XOPCC:$cc), - !strconcat("vpcom${cc}", Suffix, - "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR128:$dst, - (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), - imm:$cc)))]>, - XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), - (ins VR128:$src1, i128mem:$src2, XOPCC:$cc), - !strconcat("vpcom${cc}", Suffix, - "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR128:$dst, - (vt128 (OpNode (vt128 VR128:$src1), - (vt128 (bitconvert (loadv2i64 addr:$src2))), - imm:$cc)))]>, - XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - let isAsmParserOnly = 1, hasSideEffects = 0 in { - def ri_alt : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), - (ins VR128:$src1, VR128:$src2, u8imm:$src3), - !strconcat("vpcom", Suffix, - "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), - []>, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; - let mayLoad = 1 in - def mi_alt : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), - (ins VR128:$src1, i128mem:$src2, u8imm:$src3), - !strconcat("vpcom", Suffix, - "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), - []>, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let ExeDomain = SSEPackedInt in { // SSE integer instructions + let isCommutable = 1 in + def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), + (ins VR128:$src1, VR128:$src2, XOPCC:$cc), + !strconcat("vpcom${cc}", Suffix, + "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), + [(set VR128:$dst, + (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), + imm:$cc)))]>, + XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), + (ins VR128:$src1, i128mem:$src2, XOPCC:$cc), + !strconcat("vpcom${cc}", Suffix, + "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), + [(set VR128:$dst, + (vt128 (OpNode (vt128 VR128:$src1), + (vt128 (bitconvert (loadv2i64 addr:$src2))), + imm:$cc)))]>, + XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let isAsmParserOnly = 1, hasSideEffects = 0 in { + def ri_alt : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), + (ins VR128:$src1, VR128:$src2, u8imm:$src3), + !strconcat("vpcom", Suffix, + "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), + []>, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + let mayLoad = 1 in + def mi_alt : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), + (ins VR128:$src1, i128mem:$src2, u8imm:$src3), + !strconcat("vpcom", Suffix, + "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), + []>, XOP_4V, Sched<[WriteVecALULd, ReadAfterLd]>; + } } -} -let ExeDomain = SSEPackedInt in { // SSE integer instructions - defm VPCOMB : xopvpcom<0xCC, "b", X86vpcom, v16i8>; - defm VPCOMW : xopvpcom<0xCD, "w", X86vpcom, v8i16>; - defm VPCOMD : xopvpcom<0xCE, "d", X86vpcom, v4i32>; - defm VPCOMQ : xopvpcom<0xCF, "q", X86vpcom, v2i64>; - defm VPCOMUB : xopvpcom<0xEC, "ub", X86vpcomu, v16i8>; - defm VPCOMUW : xopvpcom<0xED, "uw", X86vpcomu, v8i16>; - defm VPCOMUD : xopvpcom<0xEE, "ud", X86vpcomu, v4i32>; - defm VPCOMUQ : xopvpcom<0xEF, "uq", X86vpcomu, v2i64>; + def : Pat<(OpNode (bitconvert (loadv2i64 addr:$src2)), + (vt128 VR128:$src1), imm:$cc), + (!cast<Instruction>(NAME#"mi") VR128:$src1, addr:$src2, + (CommuteVPCOMCC imm:$cc))>; } +defm VPCOMB : xopvpcom<0xCC, "b", X86vpcom, v16i8>; +defm VPCOMW : xopvpcom<0xCD, "w", X86vpcom, v8i16>; +defm VPCOMD : xopvpcom<0xCE, "d", X86vpcom, v4i32>; +defm VPCOMQ : xopvpcom<0xCF, "q", X86vpcom, v2i64>; +defm VPCOMUB : xopvpcom<0xEC, "ub", X86vpcomu, v16i8>; +defm VPCOMUW : xopvpcom<0xED, "uw", X86vpcomu, v8i16>; +defm VPCOMUD : xopvpcom<0xEE, "ud", X86vpcomu, v4i32>; +defm VPCOMUQ : xopvpcom<0xEF, "uq", X86vpcomu, v2i64>; + multiclass xop4op<bits<8> opc, string OpcodeStr, SDNode OpNode, ValueType vt128> { def rrr : IXOPi8Reg<opc, MRMSrcReg, (outs VR128:$dst), |