From: Craig Topper Date: Mon, 18 Mar 2019 21:33:59 +0000 (+0000) Subject: [X86] Allow any 8-bit immediate to be used with BT/BTC/BTR/BTS not just sign extended... X-Git-Tag: android-x86-9.0-r1~5783 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=ca0ea067ee021147d76f73a44d849c4b67cd7c34;p=android-x86%2Fexternal-llvm.git [X86] Allow any 8-bit immediate to be used with BT/BTC/BTR/BTS not just sign extended 8-bit immediates. We need to allow [128,255] in addition to [-128, 127] to match gas. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356413 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 64d1c2f2452..be5085b6523 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -695,6 +695,14 @@ def u8imm : Operand { let OperandType = "OPERAND_IMMEDIATE"; } +// 16-bit immediate but only 8-bits are significant and they are unsigned. +// Used by BT instructions. +def i16u8imm : Operand { + let PrintMethod = "printU8Imm"; + let ParserMatchClass = ImmUnsignedi8AsmOperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + // 32-bit immediate but only 8-bits are significant and they are unsigned. // Used by some SSE/AVX instructions that use intrinsics. def i32u8imm : Operand { @@ -703,6 +711,14 @@ def i32u8imm : Operand { let OperandType = "OPERAND_IMMEDIATE"; } +// 64-bit immediate but only 8-bits are significant and they are unsigned. +// Used by BT instructions. +def i64u8imm : Operand { + let PrintMethod = "printU8Imm"; + let ParserMatchClass = ImmUnsignedi8AsmOperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + // 64-bits but only 32 bits are significant, and those bits are treated as being // pc relative. def i64i32imm_pcrel : Operand { @@ -1747,36 +1763,36 @@ let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in { } let SchedRW = [WriteBitTest] in { -def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16i8imm:$src2), +def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2), "bt{w}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86bt GR16:$src1, i16immSExt8:$src2))]>, + [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>, OpSize16, TB; -def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32i8imm:$src2), +def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2), "bt{l}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86bt GR32:$src1, i32immSExt8:$src2))]>, + [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>, OpSize32, TB; -def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64i8imm:$src2), +def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", - [(set EFLAGS, (X86bt GR64:$src1, i64immSExt8:$src2))]>, TB; + [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB; } // SchedRW // Note that these instructions aren't slow because that only applies when the // other operand is in a register. When it's an immediate, bt is still fast. let SchedRW = [WriteBitTestImmLd] in { -def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16i8imm:$src2), +def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2), "bt{w}\t{$src2, $src1|$src1, $src2}", [(set EFLAGS, (X86bt (loadi16 addr:$src1), - i16immSExt8:$src2))]>, + imm:$src2))]>, OpSize16, TB; -def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32i8imm:$src2), +def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2), "bt{l}\t{$src2, $src1|$src1, $src2}", [(set EFLAGS, (X86bt (loadi32 addr:$src1), - i32immSExt8:$src2))]>, + imm:$src2))]>, OpSize32, TB; -def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64i8imm:$src2), +def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2), "bt{q}\t{$src2, $src1|$src1, $src2}", [(set EFLAGS, (X86bt (loadi64 addr:$src1), - i64immSExt8:$src2))]>, TB, + imm:$src2))]>, TB, Requires<[In64BitMode]>; } // SchedRW @@ -1806,20 +1822,20 @@ def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), } let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { -def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), +def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), +def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), +def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB; } // SchedRW let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { -def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16i8imm:$src2), +def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2), "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32i8imm:$src2), +def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2), "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64i8imm:$src2), +def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2), "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, Requires<[In64BitMode]>; } @@ -1849,24 +1865,24 @@ def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), } let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { -def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), +def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), "btr{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), +def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), "btr{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), +def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB; } // SchedRW let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { -def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16i8imm:$src2), +def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2), "btr{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32i8imm:$src2), +def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2), "btr{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64i8imm:$src2), +def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2), "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, Requires<[In64BitMode]>; } @@ -1896,20 +1912,20 @@ def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), } let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { -def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2), +def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2), +def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2), +def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB; } // SchedRW let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { -def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16i8imm:$src2), +def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2), "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; -def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32i8imm:$src2), +def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2), "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; -def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64i8imm:$src2), +def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2), "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, Requires<[In64BitMode]>; } diff --git a/test/MC/X86/I386-32.s b/test/MC/X86/I386-32.s index dc9e3a5cbee..aacb68ea257 100644 --- a/test/MC/X86/I386-32.s +++ b/test/MC/X86/I386-32.s @@ -12,6 +12,14 @@ bsrl %eax, %eax // CHECK: encoding: [0x0f,0xba,0xf8,0x00] btcl $0, %eax +// CHECK: btcl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xf8,0xff] +btcl $-1, %eax + +// CHECK: btcl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xf8,0xff] +btcl $255, %eax + // CHECK: btcl %eax, %eax // CHECK: encoding: [0x0f,0xbb,0xc0] btcl %eax, %eax @@ -20,6 +28,14 @@ btcl %eax, %eax // CHECK: encoding: [0x0f,0xba,0xe0,0x00] btl $0, %eax +// CHECK: btl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xe0,0xff] +btl $-1, %eax + +// CHECK: btl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xe0,0xff] +btl $255, %eax + // CHECK: btl %eax, %eax // CHECK: encoding: [0x0f,0xa3,0xc0] btl %eax, %eax @@ -28,6 +44,14 @@ btl %eax, %eax // CHECK: encoding: [0x0f,0xba,0xf0,0x00] btrl $0, %eax +// CHECK: btrl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xf0,0xff] +btrl $-1, %eax + +// CHECK: btrl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xf0,0xff] +btrl $255, %eax + // CHECK: btrl %eax, %eax // CHECK: encoding: [0x0f,0xb3,0xc0] btrl %eax, %eax @@ -36,6 +60,14 @@ btrl %eax, %eax // CHECK: encoding: [0x0f,0xba,0xe8,0x00] btsl $0, %eax +// CHECK: btsl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xe8,0xff] +btsl $-1, %eax + +// CHECK: btsl $255, %eax +// CHECK: encoding: [0x0f,0xba,0xe8,0xff] +btsl $255, %eax + // CHECK: btsl %eax, %eax // CHECK: encoding: [0x0f,0xab,0xc0] btsl %eax, %eax diff --git a/test/MC/X86/I386-64.s b/test/MC/X86/I386-64.s index ccefeb8bd53..c5bb2b08bfb 100644 --- a/test/MC/X86/I386-64.s +++ b/test/MC/X86/I386-64.s @@ -12,6 +12,14 @@ bsrl %r13d, %r13d // CHECK: encoding: [0x41,0x0f,0xba,0xfd,0x00] btcl $0, %r13d +// CHECK: btcl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xfd,0xff] +btcl $-1, %r13d + +// CHECK: btcl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xfd,0xff] +btcl $255, %r13d + // CHECK: btcl %r13d, %r13d // CHECK: encoding: [0x45,0x0f,0xbb,0xed] btcl %r13d, %r13d @@ -20,6 +28,14 @@ btcl %r13d, %r13d // CHECK: encoding: [0x41,0x0f,0xba,0xe5,0x00] btl $0, %r13d +// CHECK: btl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xe5,0xff] +btl $-1, %r13d + +// CHECK: btl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xe5,0xff] +btl $255, %r13d + // CHECK: btl %r13d, %r13d // CHECK: encoding: [0x45,0x0f,0xa3,0xed] btl %r13d, %r13d @@ -28,6 +44,14 @@ btl %r13d, %r13d // CHECK: encoding: [0x41,0x0f,0xba,0xf5,0x00] btrl $0, %r13d +// CHECK: btrl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xf5,0xff] +btrl $-1, %r13d + +// CHECK: btrl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xf5,0xff] +btrl $255, %r13d + // CHECK: btrl %r13d, %r13d // CHECK: encoding: [0x45,0x0f,0xb3,0xed] btrl %r13d, %r13d @@ -36,6 +60,14 @@ btrl %r13d, %r13d // CHECK: encoding: [0x41,0x0f,0xba,0xed,0x00] btsl $0, %r13d +// CHECK: btsl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xed,0xff] +btsl $-1, %r13d + +// CHECK: btsl $255, %r13d +// CHECK: encoding: [0x41,0x0f,0xba,0xed,0xff] +btsl $255, %r13d + // CHECK: btsl %r13d, %r13d // CHECK: encoding: [0x45,0x0f,0xab,0xed] btsl %r13d, %r13d diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index ef897420215..5b040644553 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -824,7 +824,9 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("i8mem", TYPE_M) TYPE("i8imm", TYPE_IMM) TYPE("u8imm", TYPE_UIMM8) + TYPE("i16u8imm", TYPE_UIMM8) TYPE("i32u8imm", TYPE_UIMM8) + TYPE("i64u8imm", TYPE_UIMM8) TYPE("GR8", TYPE_R8) TYPE("VR128", TYPE_XMM) TYPE("VR128X", TYPE_XMM) @@ -935,7 +937,9 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s, ENCODING("i64i8imm", ENCODING_IB) ENCODING("i8imm", ENCODING_IB) ENCODING("u8imm", ENCODING_IB) + ENCODING("i16u8imm", ENCODING_IB) ENCODING("i32u8imm", ENCODING_IB) + ENCODING("i64u8imm", ENCODING_IB) // This is not a typo. Instructions like BLENDVPD put // register IDs in 8-bit immediates nowadays. ENCODING("FR32", ENCODING_IB) @@ -1121,7 +1125,9 @@ RecognizableInstr::relocationEncodingFromString(const std::string &s, ENCODING("i64i8imm", ENCODING_IB) ENCODING("i8imm", ENCODING_IB) ENCODING("u8imm", ENCODING_IB) + ENCODING("i16u8imm", ENCODING_IB) ENCODING("i32u8imm", ENCODING_IB) + ENCODING("i64u8imm", ENCODING_IB) ENCODING("i64i32imm_pcrel", ENCODING_ID) ENCODING("i16imm_pcrel", ENCODING_IW) ENCODING("i32imm_pcrel", ENCODING_ID)