diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp | 32 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 5 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86InstrXOP.td | 47 |
8 files changed, 122 insertions, 27 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 9f17ca07424..2517a6c79d7 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2022,6 +2022,33 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, } } + // FIXME: Hack to recognize vpcom<comparison code>{ub,uw,ud,uq,b,w,d,q}. + if (PatchedName.startswith("vpcom") && + (PatchedName.endswith("b") || PatchedName.endswith("w") || + PatchedName.endswith("d") || PatchedName.endswith("q"))) { + unsigned XOPIdx = PatchedName.drop_back().endswith("u") ? 2 : 1; + unsigned XOPComparisonCode = StringSwitch<unsigned>( + PatchedName.slice(5, PatchedName.size() - XOPIdx)) + .Case("lt", 0x0) + .Case("le", 0x1) + .Case("gt", 0x2) + .Case("ge", 0x3) + .Case("eq", 0x4) + .Case("neq", 0x5) + .Case("false", 0x6) + .Case("true", 0x7) + .Default(~0U); + if (XOPComparisonCode != ~0U) { + Operands.push_back(X86Operand::CreateToken("vpcom", NameLoc)); + + const MCExpr *ImmOp = MCConstantExpr::Create(XOPComparisonCode, + getParser().getContext()); + Operands.push_back(X86Operand::CreateImm(ImmOp, NameLoc, NameLoc)); + + PatchedName = PatchedName.substr(PatchedName.size() - XOPIdx); + } + } + Operands.push_back(X86Operand::CreateToken(PatchedName, NameLoc)); if (ExtraImmOp && !isParsingIntelSyntax()) diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index 90d1b793efc..99fb1aba841 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -344,14 +344,30 @@ static void translateImmediate(MCInst &mcInst, uint64_t immediate, unsigned NewOpc; switch (mcInst.getOpcode()) { default: llvm_unreachable("unexpected opcode"); - case X86::CMPPDrmi: NewOpc = X86::CMPPDrmi_alt; break; - case X86::CMPPDrri: NewOpc = X86::CMPPDrri_alt; break; - case X86::CMPPSrmi: NewOpc = X86::CMPPSrmi_alt; break; - case X86::CMPPSrri: NewOpc = X86::CMPPSrri_alt; break; - case X86::CMPSDrm: NewOpc = X86::CMPSDrm_alt; break; - case X86::CMPSDrr: NewOpc = X86::CMPSDrr_alt; break; - case X86::CMPSSrm: NewOpc = X86::CMPSSrm_alt; break; - case X86::CMPSSrr: NewOpc = X86::CMPSSrr_alt; break; + case X86::CMPPDrmi: NewOpc = X86::CMPPDrmi_alt; break; + case X86::CMPPDrri: NewOpc = X86::CMPPDrri_alt; break; + case X86::CMPPSrmi: NewOpc = X86::CMPPSrmi_alt; break; + case X86::CMPPSrri: NewOpc = X86::CMPPSrri_alt; break; + case X86::CMPSDrm: NewOpc = X86::CMPSDrm_alt; break; + case X86::CMPSDrr: NewOpc = X86::CMPSDrr_alt; break; + case X86::CMPSSrm: NewOpc = X86::CMPSSrm_alt; break; + case X86::CMPSSrr: NewOpc = X86::CMPSSrr_alt; break; + case X86::VPCOMBri: NewOpc = X86::VPCOMBri_alt; break; + case X86::VPCOMBmi: NewOpc = X86::VPCOMBmi_alt; break; + case X86::VPCOMWri: NewOpc = X86::VPCOMWri_alt; break; + case X86::VPCOMWmi: NewOpc = X86::VPCOMWmi_alt; break; + case X86::VPCOMDri: NewOpc = X86::VPCOMDri_alt; break; + case X86::VPCOMDmi: NewOpc = X86::VPCOMDmi_alt; break; + case X86::VPCOMQri: NewOpc = X86::VPCOMQri_alt; break; + case X86::VPCOMQmi: NewOpc = X86::VPCOMQmi_alt; break; + case X86::VPCOMUBri: NewOpc = X86::VPCOMUBri_alt; break; + case X86::VPCOMUBmi: NewOpc = X86::VPCOMUBmi_alt; break; + case X86::VPCOMUWri: NewOpc = X86::VPCOMUWri_alt; break; + case X86::VPCOMUWmi: NewOpc = X86::VPCOMUWmi_alt; break; + case X86::VPCOMUDri: NewOpc = X86::VPCOMUDri_alt; break; + case X86::VPCOMUDmi: NewOpc = X86::VPCOMUDmi_alt; break; + case X86::VPCOMUQri: NewOpc = X86::VPCOMUQri_alt; break; + case X86::VPCOMUQmi: NewOpc = X86::VPCOMUQmi_alt; break; } // Switch opcode to the one that doesn't get special printing. mcInst.setOpcode(NewOpc); diff --git a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp index a4aef717761..65461af5b7b 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp +++ b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp @@ -112,8 +112,24 @@ void X86ATTInstPrinter::printSSEAVXCC(const MCInst *MI, unsigned Op, } } -void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op, +void X86ATTInstPrinter::printXOPCC(const MCInst *MI, unsigned Op, raw_ostream &O) { + int64_t Imm = MI->getOperand(Op).getImm(); + switch (Imm) { + default: llvm_unreachable("Invalid xopcc argument!"); + case 0: O << "lt"; break; + case 1: O << "le"; break; + case 2: O << "gt"; break; + case 3: O << "ge"; break; + case 4: O << "eq"; break; + case 5: O << "neq"; break; + case 6: O << "false"; break; + case 7: O << "true"; break; + } +} + +void X86ATTInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op, + raw_ostream &O) { int64_t Imm = MI->getOperand(Op).getImm() & 0x3; switch (Imm) { case 0: O << "{rn-sae}"; break; diff --git a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h index 1d4ef39abe7..f71cb81690d 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h +++ b/llvm/lib/Target/X86/InstPrinter/X86ATTInstPrinter.h @@ -46,6 +46,7 @@ public: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &OS); void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &OS); void printSSEAVXCC(const MCInst *MI, unsigned Op, raw_ostream &OS); + void printXOPCC(const MCInst *MI, unsigned Op, raw_ostream &OS); void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &OS); void printSrcIdx(const MCInst *MI, unsigned OpNo, raw_ostream &OS); void printDstIdx(const MCInst *MI, unsigned OpNo, raw_ostream &OS); diff --git a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp index 57f0a66a287..91d1828ddb9 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp +++ b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp @@ -90,8 +90,24 @@ void X86IntelInstPrinter::printSSEAVXCC(const MCInst *MI, unsigned Op, } } +void X86IntelInstPrinter::printXOPCC(const MCInst *MI, unsigned Op, + raw_ostream &O) { + int64_t Imm = MI->getOperand(Op).getImm(); + switch (Imm) { + default: llvm_unreachable("Invalid xopcc argument!"); + case 0: O << "lt"; break; + case 1: O << "le"; break; + case 2: O << "gt"; break; + case 3: O << "ge"; break; + case 4: O << "eq"; break; + case 5: O << "neq"; break; + case 6: O << "false"; break; + case 7: O << "true"; break; + } +} + void X86IntelInstPrinter::printRoundingControl(const MCInst *MI, unsigned Op, - raw_ostream &O) { + raw_ostream &O) { int64_t Imm = MI->getOperand(Op).getImm() & 0x3; switch (Imm) { case 0: O << "{rn-sae}"; break; diff --git a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h index 2955cf49b14..2150144d648 100644 --- a/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h +++ b/llvm/lib/Target/X86/InstPrinter/X86IntelInstPrinter.h @@ -37,6 +37,7 @@ public: void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printMemReference(const MCInst *MI, unsigned Op, raw_ostream &O); void printSSEAVXCC(const MCInst *MI, unsigned Op, raw_ostream &O); + void printXOPCC(const MCInst *MI, unsigned Op, raw_ostream &O); void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printSrcIdx(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index ba8e28ad876..c13148afb18 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -561,6 +561,11 @@ def AVX512ICC : Operand<i8> { let OperandType = "OPERAND_IMMEDIATE"; } +def XOPCC : Operand<i8> { + let PrintMethod = "printXOPCC"; + let OperandType = "OPERAND_IMMEDIATE"; +} + class ImmSExtAsmOperandClass : AsmOperandClass { let SuperClasses = [ImmAsmOperand]; let RenderMethod = "addImmOperands"; diff --git a/llvm/lib/Target/X86/X86InstrXOP.td b/llvm/lib/Target/X86/X86InstrXOP.td index 6f2b3e4d44d..f3a202d0d5d 100644 --- a/llvm/lib/Target/X86/X86InstrXOP.td +++ b/llvm/lib/Target/X86/X86InstrXOP.td @@ -158,30 +158,43 @@ defm VPMACSDQH : xop4opm2<0x9F, "vpmacsdqh", int_x86_xop_vpmacsdqh>; defm VPMACSDD : xop4opm2<0x9E, "vpmacsdd", int_x86_xop_vpmacsdd>; // Instruction where second source can be memory, third must be imm8 -multiclass xop4opimm<bits<8> opc, string OpcodeStr, Intrinsic Int> { +multiclass xopvpcom<bits<8> opc, string Suffix, Intrinsic Int> { def ri : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), - (ins VR128:$src1, VR128:$src2, i8imm:$src3), - !strconcat(OpcodeStr, - "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), - [(set VR128:$dst, (Int VR128:$src1, VR128:$src2, imm:$src3))]>, + (ins VR128:$src1, VR128:$src2, XOPCC:$cc), + !strconcat("vpcom${cc}", Suffix, + "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), + [(set VR128:$dst, (Int VR128:$src1, VR128:$src2, i8immZExt3:$cc))]>, XOP_4V; def mi : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), - (ins VR128:$src1, i128mem:$src2, i8imm:$src3), - !strconcat(OpcodeStr, - "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), + (ins VR128:$src1, i128mem:$src2, XOPCC:$cc), + !strconcat("vpcom${cc}", Suffix, + "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), [(set VR128:$dst, (Int VR128:$src1, (bitconvert (loadv2i64 addr:$src2)), - imm:$src3))]>, XOP_4V; + i8immZExt3:$cc))]>, XOP_4V; + let isAsmParserOnly = 1, hasSideEffects = 0 in { + def ri_alt : IXOPi8<opc, MRMSrcReg, (outs VR128:$dst), + (ins VR128:$src1, VR128:$src2, i8imm:$src3), + !strconcat("vpcom", Suffix, + "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), + []>, XOP_4V; + let mayLoad = 1 in + def mi_alt : IXOPi8<opc, MRMSrcMem, (outs VR128:$dst), + (ins VR128:$src1, i128mem:$src2, i8imm:$src3), + !strconcat("vpcom", Suffix, + "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), + []>, XOP_4V; + } } -defm VPCOMB : xop4opimm<0xCC, "vpcomb", int_x86_xop_vpcomb>; -defm VPCOMW : xop4opimm<0xCD, "vpcomw", int_x86_xop_vpcomw>; -defm VPCOMD : xop4opimm<0xCE, "vpcomd", int_x86_xop_vpcomd>; -defm VPCOMQ : xop4opimm<0xCF, "vpcomq", int_x86_xop_vpcomq>; -defm VPCOMUB : xop4opimm<0xEC, "vpcomub", int_x86_xop_vpcomub>; -defm VPCOMUW : xop4opimm<0xED, "vpcomuw", int_x86_xop_vpcomuw>; -defm VPCOMUD : xop4opimm<0xEE, "vpcomud", int_x86_xop_vpcomud>; -defm VPCOMUQ : xop4opimm<0xEF, "vpcomuq", int_x86_xop_vpcomuq>; +defm VPCOMB : xopvpcom<0xCC, "b", int_x86_xop_vpcomb>; +defm VPCOMW : xopvpcom<0xCD, "w", int_x86_xop_vpcomw>; +defm VPCOMD : xopvpcom<0xCE, "d", int_x86_xop_vpcomd>; +defm VPCOMQ : xopvpcom<0xCF, "q", int_x86_xop_vpcomq>; +defm VPCOMUB : xopvpcom<0xEC, "ub", int_x86_xop_vpcomub>; +defm VPCOMUW : xopvpcom<0xED, "uw", int_x86_xop_vpcomuw>; +defm VPCOMUD : xopvpcom<0xEE, "ud", int_x86_xop_vpcomud>; +defm VPCOMUQ : xopvpcom<0xEF, "uq", int_x86_xop_vpcomuq>; // Instruction where either second or third source can be memory multiclass xop4op<bits<8> opc, string OpcodeStr, Intrinsic Int> { |

