From 71b49aa438b22b02230fff30e8874ff756336e6d Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 15 Jul 2020 23:50:29 -0700 Subject: [PATCH] [X86] Allow lsl/lar to be parsed with a GR16, GR32, or GR64 as source register. This matches GNU assembler behavior. Operand size is determined only from the destination register. --- llvm/lib/Target/X86/AsmParser/X86Operand.h | 18 +++++++++++++++++- llvm/lib/Target/X86/X86InstrInfo.td | 9 ++++++++- llvm/lib/Target/X86/X86InstrSystem.td | 16 ++++++---------- llvm/test/MC/X86/I286-32.s | 4 ++-- llvm/test/MC/X86/I286-64.s | 16 ++++++++++++---- llvm/utils/TableGen/X86RecognizableInstr.cpp | 3 +++ 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h index 5cf4516..e323353 100644 --- a/llvm/lib/Target/X86/AsmParser/X86Operand.h +++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h @@ -463,7 +463,14 @@ struct X86Operand final : public MCParsedAsmOperand { bool isGR32orGR64() const { return Kind == Register && (X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || - X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); + X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); + } + + bool isGR16orGR32orGR64() const { + return Kind == Register && + (X86MCRegisterClasses[X86::GR16RegClassID].contains(getReg()) || + X86MCRegisterClasses[X86::GR32RegClassID].contains(getReg()) || + X86MCRegisterClasses[X86::GR64RegClassID].contains(getReg())); } bool isVectorReg() const { @@ -520,6 +527,15 @@ struct X86Operand final : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createReg(RegNo)); } + void addGR16orGR32orGR64Operands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + MCRegister RegNo = getReg(); + if (X86MCRegisterClasses[X86::GR32RegClassID].contains(RegNo) || + X86MCRegisterClasses[X86::GR64RegClassID].contains(RegNo)) + RegNo = getX86SubSuperRegister(RegNo, 16); + Inst.addOperand(MCOperand::createReg(RegNo)); + } + void addAVX512RCOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); addExpr(Inst, getImm()); diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 23841c3..3ea0ae8 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -640,10 +640,17 @@ class ImmSExtAsmOperandClass : AsmOperandClass { def X86GR32orGR64AsmOperand : AsmOperandClass { let Name = "GR32orGR64"; } - def GR32orGR64 : RegisterOperand { let ParserMatchClass = X86GR32orGR64AsmOperand; } + +def X86GR16orGR32orGR64AsmOperand : AsmOperandClass { + let Name = "GR16orGR32orGR64"; +} +def GR16orGR32orGR64 : RegisterOperand { + let ParserMatchClass = X86GR16orGR32orGR64AsmOperand; +} + def AVX512RCOperand : AsmOperandClass { let Name = "AVX512RC"; } diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td index d5f1064..13659b5 100644 --- a/llvm/lib/Target/X86/X86InstrSystem.td +++ b/llvm/lib/Target/X86/X86InstrSystem.td @@ -207,45 +207,41 @@ let mayLoad = 1 in def LAR16rm : I<0x02, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), "lar{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, NotMemoryFoldable; -def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), +def LAR16rr : I<0x02, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src), "lar{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, NotMemoryFoldable; -// i16mem operand in LAR32rm and GR32 operand in LAR32rr is not a typo. let mayLoad = 1 in def LAR32rm : I<0x02, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src), "lar{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, NotMemoryFoldable; -def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), +def LAR32rr : I<0x02, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src), "lar{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, NotMemoryFoldable; -// i16mem operand in LAR64rm and GR32 operand in LAR64rr is not a typo. let mayLoad = 1 in def LAR64rm : RI<0x02, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src), "lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable; -def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR32orGR64:$src), +def LAR64rr : RI<0x02, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src), "lar{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable; -// i16mem operand in LSL32rm and GR32 operand in LSL32rr is not a typo. let mayLoad = 1 in def LSL16rm : I<0x03, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), "lsl{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, NotMemoryFoldable; -def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), +def LSL16rr : I<0x03, MRMSrcReg, (outs GR16:$dst), (ins GR16orGR32orGR64:$src), "lsl{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, NotMemoryFoldable; -// i16mem operand in LSL64rm and GR32 operand in LSL64rr is not a typo. let mayLoad = 1 in def LSL32rm : I<0x03, MRMSrcMem, (outs GR32:$dst), (ins i16mem:$src), "lsl{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, NotMemoryFoldable; -def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), +def LSL32rr : I<0x03, MRMSrcReg, (outs GR32:$dst), (ins GR16orGR32orGR64:$src), "lsl{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, NotMemoryFoldable; let mayLoad = 1 in def LSL64rm : RI<0x03, MRMSrcMem, (outs GR64:$dst), (ins i16mem:$src), "lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable; -def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR32orGR64:$src), +def LSL64rr : RI<0x03, MRMSrcReg, (outs GR64:$dst), (ins GR16orGR32orGR64:$src), "lsl{q}\t{$src, $dst|$dst, $src}", []>, TB, NotMemoryFoldable; def INVLPG : I<0x01, MRM7m, (outs), (ins i8mem:$addr), "invlpg\t$addr", []>, TB; diff --git a/llvm/test/MC/X86/I286-32.s b/llvm/test/MC/X86/I286-32.s index 0d46366..648de01 100644 --- a/llvm/test/MC/X86/I286-32.s +++ b/llvm/test/MC/X86/I286-32.s @@ -24,7 +24,7 @@ larl 485498096(%edx), %eax // CHECK: encoding: [0x0f,0x02,0x44,0x02,0x40] larl 64(%edx,%eax), %eax -// CHECK: larl %eax, %eax +// CHECK: larl %ax, %eax // CHECK: encoding: [0x0f,0x02,0xc0] larl %eax, %eax @@ -100,7 +100,7 @@ lsll 485498096(%edx), %eax // CHECK: encoding: [0x0f,0x03,0x44,0x02,0x40] lsll 64(%edx,%eax), %eax -// CHECK: lsll %eax, %eax +// CHECK: lsll %ax, %eax // CHECK: encoding: [0x0f,0x03,0xc0] lsll %eax, %eax diff --git a/llvm/test/MC/X86/I286-64.s b/llvm/test/MC/X86/I286-64.s index 1bab0a6..7707d7b 100644 --- a/llvm/test/MC/X86/I286-64.s +++ b/llvm/test/MC/X86/I286-64.s @@ -24,7 +24,7 @@ larl -64(%rdx,%rax,4), %r13d // CHECK: encoding: [0x44,0x0f,0x02,0x6c,0x02,0x40] larl 64(%rdx,%rax), %r13d -// CHECK: larl %r13d, %r13d +// CHECK: larl %r13w, %r13d // CHECK: encoding: [0x45,0x0f,0x02,0xed] larl %r13d, %r13d @@ -32,7 +32,11 @@ larl %r13d, %r13d // CHECK: encoding: [0x44,0x0f,0x02,0x2a] larl (%rdx), %r13d -// CHECK: larq %eax, %rax +// CHECK: larq %ax, %rax +// CHECK: encoding: [0x48,0x0f,0x02,0xc0] +lar %ax, %rax + +// CHECK: larq %ax, %rax // CHECK: encoding: [0x48,0x0f,0x02,0xc0] lar %rax, %rax @@ -160,7 +164,7 @@ lsll -64(%rdx,%rax,4), %r13d // CHECK: encoding: [0x44,0x0f,0x03,0x6c,0x02,0x40] lsll 64(%rdx,%rax), %r13d -// CHECK: lsll %r13d, %r13d +// CHECK: lsll %r13w, %r13d // CHECK: encoding: [0x45,0x0f,0x03,0xed] lsll %r13d, %r13d @@ -168,7 +172,11 @@ lsll %r13d, %r13d // CHECK: encoding: [0x44,0x0f,0x03,0x2a] lsll (%rdx), %r13d -// CHECK: lslq %eax, %rax +// CHECK: lslq %ax, %rax +// CHECK: encoding: [0x48,0x0f,0x03,0xc0] +lsl %ax, %rax + +// CHECK: lslq %ax, %rax // CHECK: encoding: [0x48,0x0f,0x03,0xc0] lsl %rax, %rax diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index 84f6d52..6a245b5 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -874,6 +874,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("i16imm", TYPE_IMM) TYPE("i16i8imm", TYPE_IMM) TYPE("GR16", TYPE_R16) + TYPE("GR16orGR32orGR64", TYPE_R16) TYPE("i32mem", TYPE_M) TYPE("i32imm", TYPE_IMM) TYPE("i32i8imm", TYPE_IMM) @@ -1035,6 +1036,7 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s, ENCODING("RST", ENCODING_FP) ENCODING("RSTi", ENCODING_FP) ENCODING("GR16", ENCODING_RM) + ENCODING("GR16orGR32orGR64",ENCODING_RM) ENCODING("GR32", ENCODING_RM) ENCODING("GR32orGR64", ENCODING_RM) ENCODING("GR64", ENCODING_RM) @@ -1072,6 +1074,7 @@ OperandEncoding RecognizableInstr::roRegisterEncodingFromString(const std::string &s, uint8_t OpSize) { ENCODING("GR16", ENCODING_REG) + ENCODING("GR16orGR32orGR64",ENCODING_REG) ENCODING("GR32", ENCODING_REG) ENCODING("GR32orGR64", ENCODING_REG) ENCODING("GR64", ENCODING_REG) -- 2.7.4