diff options
author | Craig Topper <craig.topper@intel.com> | 2019-04-10 05:43:20 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2019-04-10 05:43:20 +0000 |
commit | 391d5caa106007daaa1ae0bf8214f9020f40a8b5 (patch) | |
tree | 02d6eec2d5aa7cd23a90863bd06a378137844c6f /llvm/lib | |
parent | 7d4ad143715c22ef8e28157df26e7da29dc89cfa (diff) | |
download | bcm5719-llvm-391d5caa106007daaa1ae0bf8214f9020f40a8b5.tar.gz bcm5719-llvm-391d5caa106007daaa1ae0bf8214f9020f40a8b5.zip |
[X86] Move the 2 byte VEX optimization for MOV instructions back to the X86AsmParser::processInstruction where it used to be. Block when {vex3} prefix is present.
Years ago I moved this to an InstAlias using VR128H/VR128L. But now that we support {vex3} pseudo prefix, we need to block the optimization when it is set to match gas behavior.
llvm-svn: 358046
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 64 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrSSE.td | 42 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RegisterInfo.td | 11 |
3 files changed, 63 insertions, 54 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index fa079242e75..30411a232ef 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2830,7 +2830,69 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, } bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) { - return false; + const MCRegisterInfo *MRI = getContext().getRegisterInfo(); + + 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: { + // We can get a smaller encoding by using VEX.R instead of VEX.B if one of + // the registers is extended, but other isn't. + if (ForcedVEXEncoding == VEXEncoding_VEX3 || + MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 || + MRI->getEncodingValue(Inst.getOperand(1).getReg()) < 8) + 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: { + // We can get a smaller encoding by using VEX.R instead of VEX.B if one of + // the registers is extended, but other isn't. + if (ForcedVEXEncoding == VEXEncoding_VEX3 || + MRI->getEncodingValue(Inst.getOperand(0).getReg()) >= 8 || + MRI->getEncodingValue(Inst.getOperand(2).getReg()) < 8) + 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; + } + } } bool X86AsmParser::validateInstruction(MCInst &Inst, const OperandVector &Ops) { diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td index f2ce89bcebd..6ee2504beea 100644 --- a/llvm/lib/Target/X86/X86InstrSSE.td +++ b/llvm/lib/Target/X86/X86InstrSSE.td @@ -350,13 +350,6 @@ let Predicates = [UseSSE2] in { (COPY_TO_REGCLASS (MOVSDrm addr:$src), VR128)>; } -// 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 //===----------------------------------------------------------------------===// @@ -503,25 +496,6 @@ let SchedRW = [SchedWriteFMoveLS.YMM.RR] in { } // SchedRW } // Predicate -// 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>; - // Reversed version with ".s" suffix for GAS compatibility. def : InstAlias<"vmovaps.s\t{$src, $dst|$dst, $src}", (VMOVAPSrr_REV VR128:$dst, VR128:$src), 0>; @@ -3444,17 +3418,6 @@ def MOVDQUmr : I<0x7F, MRMDestMem, (outs), (ins i128mem:$dst, VR128:$src), } // ExeDomain = SSEPackedInt -// 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>; - // Reversed version with ".s" suffix for GAS compatibility. def : InstAlias<"vmovdqa.s\t{$src, $dst|$dst, $src}", (VMOVDQArr_REV VR128:$dst, VR128:$src), 0>; @@ -4423,11 +4386,6 @@ def MOVPQI2QIrr : S2I<0xD6, MRMDestReg, (outs VR128:$dst), (ins VR128:$src), "movq\t{$src, $dst|$dst, $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<"vmovq\t{$src, $dst|$dst, $src}", - (VMOVPQI2QIrr VR128L:$dst, VR128H:$src), 0>; - def : InstAlias<"vmovq.s\t{$src, $dst|$dst, $src}", (VMOVPQI2QIrr VR128:$dst, VR128:$src), 0>; def : InstAlias<"movq.s\t{$src, $dst|$dst, $src}", diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index d81f08b0f06..e03f0492cd7 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -552,17 +552,6 @@ def VR128 : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64, f128 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, f128], - 128, (sequence "XMM%u", 0, 7)>; -def VR128H : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64, f128], - 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. |