diff options
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrSSE.td | 42 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 11 |
3 files changed, 53 insertions, 51 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index e0dc71e9db6..836de26a5ee 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2529,57 +2529,6 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { switch (Inst.getOpcode()) { default: return false; - case X86::VMOVZPQILo2PQIrr: - case X86::VMOVAPDrr: - case X86::VMOVAPDYrr: - case X86::VMOVAPSrr: - case X86::VMOVAPSYrr: - case X86::VMOVDQArr: - case X86::VMOVDQAYrr: - case X86::VMOVDQUrr: - case X86::VMOVDQUYrr: - case X86::VMOVUPDrr: - case X86::VMOVUPDYrr: - case X86::VMOVUPSrr: - case X86::VMOVUPSYrr: { - if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) || - !X86II::isX86_64ExtendedReg(Inst.getOperand(1).getReg())) - return false; - - unsigned NewOpc; - switch (Inst.getOpcode()) { - default: llvm_unreachable("Invalid opcode"); - case X86::VMOVZPQILo2PQIrr: NewOpc = X86::VMOVPQI2QIrr; break; - case X86::VMOVAPDrr: NewOpc = X86::VMOVAPDrr_REV; break; - case X86::VMOVAPDYrr: NewOpc = X86::VMOVAPDYrr_REV; break; - case X86::VMOVAPSrr: NewOpc = X86::VMOVAPSrr_REV; break; - case X86::VMOVAPSYrr: NewOpc = X86::VMOVAPSYrr_REV; break; - case X86::VMOVDQArr: NewOpc = X86::VMOVDQArr_REV; break; - case X86::VMOVDQAYrr: NewOpc = X86::VMOVDQAYrr_REV; break; - case X86::VMOVDQUrr: NewOpc = X86::VMOVDQUrr_REV; break; - case X86::VMOVDQUYrr: NewOpc = X86::VMOVDQUYrr_REV; break; - case X86::VMOVUPDrr: NewOpc = X86::VMOVUPDrr_REV; break; - case X86::VMOVUPDYrr: NewOpc = X86::VMOVUPDYrr_REV; break; - case X86::VMOVUPSrr: NewOpc = X86::VMOVUPSrr_REV; break; - case X86::VMOVUPSYrr: NewOpc = X86::VMOVUPSYrr_REV; break; - } - Inst.setOpcode(NewOpc); - return true; - } - case X86::VMOVSDrr: - case X86::VMOVSSrr: { - if (X86II::isX86_64ExtendedReg(Inst.getOperand(0).getReg()) || - !X86II::isX86_64ExtendedReg(Inst.getOperand(2).getReg())) - return false; - unsigned NewOpc; - switch (Inst.getOpcode()) { - default: llvm_unreachable("Invalid opcode"); - case X86::VMOVSDrr: NewOpc = X86::VMOVSDrr_REV; break; - case X86::VMOVSSrr: NewOpc = X86::VMOVSSrr_REV; break; - } - Inst.setOpcode(NewOpc); - return true; - } } } diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index 34e34d99991..ae488c4bf4b 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -761,6 +761,13 @@ let Predicates = [UseSSE2] in { (MOVSDrr VR128:$src1, (COPY_TO_REGCLASS VR128:$src2, FR64))>; } +// Aliases to help the assembler pick two byte VEX encodings by swapping the +// operands relative to the normal instructions to use VEX.R instead of VEX.B. +def : InstAlias<"vmovss\t{$src2, $src1, $dst|$dst, $src1, $src2}", + (VMOVSSrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>; +def : InstAlias<"vmovsd\t{$src2, $src1, $dst|$dst, $src1, $src2}", + (VMOVSDrr_REV VR128L:$dst, VR128:$src1, VR128H:$src2), 0>; + //===----------------------------------------------------------------------===// // SSE 1 & 2 - Move Aligned/Unaligned FP Instructions //===----------------------------------------------------------------------===// @@ -903,6 +910,25 @@ def : Pat<(int_x86_avx_storeu_ps_256 addr:$dst, VR256:$src), def : Pat<(int_x86_avx_storeu_pd_256 addr:$dst, VR256:$src), (VMOVUPDYmr addr:$dst, VR256:$src)>; +// Aliases to help the assembler pick two byte VEX encodings by swapping the +// operands relative to the normal instructions to use VEX.R instead of VEX.B. +def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}", + (VMOVAPSrr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}", + (VMOVAPDrr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}", + (VMOVUPSrr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}", + (VMOVUPDrr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovaps\t{$src, $dst|$dst, $src}", + (VMOVAPSYrr_REV VR256L:$dst, VR256H:$src), 0>; +def : InstAlias<"vmovapd\t{$src, $dst|$dst, $src}", + (VMOVAPDYrr_REV VR256L:$dst, VR256H:$src), 0>; +def : InstAlias<"vmovups\t{$src, $dst|$dst, $src}", + (VMOVUPSYrr_REV VR256L:$dst, VR256H:$src), 0>; +def : InstAlias<"vmovupd\t{$src, $dst|$dst, $src}", + (VMOVUPDYrr_REV VR256L:$dst, VR256H:$src), 0>; + let SchedRW = [WriteStore] in { def MOVAPSmr : PSI<0x29, MRMDestMem, (outs), (ins f128mem:$dst, VR128:$src), "movaps\t{$src, $dst|$dst, $src}", @@ -3885,6 +3911,17 @@ let Predicates = [UseSSE2] in def : Pat<(int_x86_sse2_storeu_dq addr:$dst, VR128:$src), (MOVDQUmr addr:$dst, VR128:$src)>; +// Aliases to help the assembler pick two byte VEX encodings by swapping the +// operands relative to the normal instructions to use VEX.R instead of VEX.B. +def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}", + (VMOVDQArr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovdqa\t{$src, $dst|$dst, $src}", + (VMOVDQAYrr_REV VR256L:$dst, VR256H:$src), 0>; +def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}", + (VMOVDQUrr_REV VR128L:$dst, VR128H:$src), 0>; +def : InstAlias<"vmovdqu\t{$src, $dst|$dst, $src}", + (VMOVDQUYrr_REV VR256L:$dst, VR256H:$src), 0>; + //===---------------------------------------------------------------------===// // SSE2 - Packed Integer Arithmetic Instructions //===---------------------------------------------------------------------===// @@ -4977,6 +5014,11 @@ def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src), "movq\t{$src, $dst|$dst, $src}", [], IIC_SSE_MOVQ_RR>; } +// Aliases to help the assembler pick two byte VEX encodings by swapping the +// operands relative to the normal instructions to use VEX.R instead of VEX.B. +def : InstAlias<"vmovq\t{$src, $dst|$dst, $src}", + (VMOVPQI2QIrr VR128L:$dst, VR128H:$src), 0>; + //===---------------------------------------------------------------------===// // Store / copy lower 64-bits of a XMM register. // diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index 5f894c040b8..373f9b4c65f 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -471,6 +471,17 @@ def VR128 : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], def VR256 : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], 256, (sequence "YMM%u", 0, 15)>; +// Special classes that help the assembly parser choose some alternate +// instructions to favor 2-byte VEX encodings. +def VR128L : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], + 128, (sequence "XMM%u", 0, 7)>; +def VR128H : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], + 128, (sequence "XMM%u", 8, 15)>; +def VR256L : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], + 256, (sequence "YMM%u", 0, 7)>; +def VR256H : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], + 256, (sequence "YMM%u", 8, 15)>; + // Status flags registers. def CCR : RegisterClass<"X86", [i32], 32, (add EFLAGS)> { let CopyCost = -1; // Don't allow copying of status registers. |