Skip to content

Commit 5b9e1a5

Browse files
authored
[X86][AsmParser] Improve rel8 validation (#126073)
* Check the size of immediate operand of rel8 * Rename AbsMem16 related names to AbsMemMode16 to disambiguate mem size and mode checks.
1 parent 50219c8 commit 5b9e1a5

File tree

8 files changed

+86
-11
lines changed

8 files changed

+86
-11
lines changed

llvm/lib/Target/X86/AsmParser/X86Operand.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,10 +416,16 @@ struct X86Operand final : public MCParsedAsmOperand {
416416
return isImm();
417417
}
418418

419-
bool isAbsMem16() const {
420-
return isAbsMem() && Mem.ModeSize == 16;
419+
bool isAbsMemMode16() const { return isAbsMem() && Mem.ModeSize == 16; }
420+
421+
bool isDispImm8() const {
422+
if (auto *CE = dyn_cast<MCConstantExpr>(getMemDisp()))
423+
return isImmSExti64i8Value(CE->getValue());
424+
return true;
421425
}
422426

427+
bool isAbsMem8() const { return isAbsMem() && isMem8() && isDispImm8(); }
428+
423429
bool isMemUseUpRegs() const override { return UseUpRegs; }
424430

425431
bool isSrcIdx() const {

llvm/lib/Target/X86/X86InstrControl.td

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,14 @@ let isBranch = 1, isTerminator = 1, hasSideEffects = 0, SchedRW = [WriteJump] in
9494
// 32-bit mode, the address size prefix is jcxz and the unprefixed version is
9595
// jecxz.
9696
let Uses = [CX] in
97-
def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
97+
def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
9898
"jcxz\t$dst", []>, AdSize16, Requires<[Not64BitMode]>;
9999
let Uses = [ECX] in
100-
def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
100+
def JECXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
101101
"jecxz\t$dst", []>, AdSize32;
102102

103103
let Uses = [RCX] in
104-
def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
104+
def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins i8imm_brtarget:$dst),
105105
"jrcxz\t$dst", []>, AdSize64, Requires<[In64BitMode]>;
106106
}
107107

@@ -193,9 +193,12 @@ def JMPABS64i : Ii64<0xA1, RawFrm, (outs), (ins i64imm:$dst), "jmpabs\t$dst", []
193193

194194
// Loop instructions
195195
let isBranch = 1, isTerminator = 1, SchedRW = [WriteJump] in {
196-
def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins brtarget8:$dst), "loop\t$dst", []>;
197-
def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins brtarget8:$dst), "loope\t$dst", []>;
198-
def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins brtarget8:$dst), "loopne\t$dst", []>;
196+
def LOOP : Ii8PCRel<0xE2, RawFrm, (outs), (ins i8imm_brtarget:$dst),
197+
"loop\t$dst", []>;
198+
def LOOPE : Ii8PCRel<0xE1, RawFrm, (outs), (ins i8imm_brtarget:$dst),
199+
"loope\t$dst", []>;
200+
def LOOPNE : Ii8PCRel<0xE0, RawFrm, (outs), (ins i8imm_brtarget:$dst),
201+
"loopne\t$dst", []>;
199202
}
200203

201204
//===----------------------------------------------------------------------===//

llvm/lib/Target/X86/X86InstrOperands.td

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,14 @@ def i64mem_TC : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64> {
142142
}
143143

144144
// Special parser to detect 16-bit mode to select 16-bit displacement.
145-
def X86AbsMem16AsmOperand : AsmOperandClass {
146-
let Name = "AbsMem16";
145+
def X86AbsMemMode16AsmOperand : AsmOperandClass {
146+
let Name = "AbsMemMode16";
147+
let RenderMethod = "addAbsMemOperands";
148+
let SuperClasses = [X86AbsMemAsmOperand];
149+
}
150+
151+
def X86AbsMem8AsmOperand : AsmOperandClass {
152+
let Name = "AbsMem8";
147153
let RenderMethod = "addAbsMemOperands";
148154
let SuperClasses = [X86AbsMemAsmOperand];
149155
}
@@ -157,6 +163,9 @@ class BranchTargetOperand<ValueType ty> : Operand<ty> {
157163

158164
def i32imm_brtarget : BranchTargetOperand<i32>;
159165
def i16imm_brtarget : BranchTargetOperand<i16>;
166+
def i8imm_brtarget : BranchTargetOperand<i8> {
167+
let ParserMatchClass = X86AbsMem8AsmOperand;
168+
}
160169

161170
// 64-bits but only 32 bits are significant, and those bits are treated as being
162171
// pc relative.
@@ -165,7 +174,7 @@ def i64i32imm_brtarget : BranchTargetOperand<i64>;
165174
def brtarget : BranchTargetOperand<OtherVT>;
166175
def brtarget8 : BranchTargetOperand<OtherVT>;
167176
def brtarget16 : BranchTargetOperand<OtherVT> {
168-
let ParserMatchClass = X86AbsMem16AsmOperand;
177+
let ParserMatchClass = X86AbsMemMode16AsmOperand;
169178
}
170179
def brtarget32 : BranchTargetOperand<OtherVT>;
171180

llvm/test/MC/X86/I386-32.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ iretl
176176
// CHECK: encoding: [0x66,0xcf]
177177
iretw
178178

179+
// CHECK: jcxz 64
180+
// CHECK: encoding: [0x67,0xe3,A]
181+
jcxz 64
182+
179183
// CHECK: jecxz 64
180184
// CHECK: encoding: [0xe3,A]
181185
jecxz 64

llvm/test/MC/X86/I386-64.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,14 @@ iretq
257257
// CHECK: encoding: [0x66,0xcf]
258258
iretw
259259

260+
// CHECK: jecxz 64
261+
// CHECK: encoding: [0x67,0xe3,A]
262+
jecxz 64
263+
264+
// CHECK: jrcxz 64
265+
// CHECK: encoding: [0xe3,A]
266+
jrcxz 64
267+
260268
// CHECK: lodsl %gs:(%rsi), %eax
261269
// CHECK: encoding: [0x65,0xad]
262270
lodsl %gs:(%rsi), %eax

llvm/test/MC/X86/intel-syntax.s

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// RUN: FileCheck < %t %s
33
// RUN: FileCheck --check-prefix=CHECK-STDERR < %t.err %s
44

5+
_nop_label:
6+
nop
7+
58
_test:
69
xor EAX, EAX
710
ret
@@ -72,6 +75,8 @@ main:
7275
jnc short _foo
7376
// CHECK: jecxz _foo
7477
jecxz short _foo
78+
// CHECK: jrcxz _nop_label+1
79+
jrcxz _nop_label+1
7580
// CHECK: jp _foo
7681
jpe short _foo
7782

@@ -825,8 +830,10 @@ fucomip st, st(2)
825830
// CHECK: fcompi %st(2)
826831
// CHECK: fucompi %st(2)
827832

833+
loop byte ptr [64]
828834
loopz _foo
829835
loopnz _foo
836+
// CHECK: loop 64
830837
// CHECK: loope _foo
831838
// CHECK: loopne _foo
832839

llvm/test/MC/X86/validate-inst-intel.s

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,39 @@
1313
# CHECK: int -129
1414
# CHECK: ^
1515

16+
.text
17+
loop WORD PTR [SYM+4]
18+
# CHECK: error: invalid operand for instruction
19+
# CHECK: loop WORD PTR [SYM+4]
20+
# CHECK: ^
21+
22+
.text
23+
loope BYTE PTR [128]
24+
# CHECK: error: invalid operand for instruction
25+
# CHECK: loope BYTE PTR [128]
26+
# CHECK: ^
27+
28+
.text
29+
loopne BYTE PTR [-129]
30+
# CHECK: error: invalid operand for instruction
31+
# CHECK: loopne BYTE PTR [-129]
32+
# CHECK: ^
33+
34+
.text
35+
jrcxz XMMWORD PTR [0]
36+
# CHECK: error: invalid operand for instruction
37+
# CHECK: jrcxz XMMWORD PTR [0]
38+
# CHECK: ^
39+
40+
.text
41+
jecxz BYTE PTR[-444]
42+
# CHECK: error: invalid operand for instruction
43+
# CHECK: jecxz BYTE PTR[-444]
44+
# CHECK: ^
45+
46+
.text
47+
jcxz BYTE PTR[444]
48+
# CHECK: error: invalid operand for instruction
49+
# CHECK: jcxz BYTE PTR[444]
50+
# CHECK: ^
51+

llvm/utils/TableGen/X86RecognizableInstr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
10871087
TYPE("i512mem_GR32", TYPE_M)
10881088
TYPE("i512mem_GR64", TYPE_M)
10891089
TYPE("i64i32imm_brtarget", TYPE_REL)
1090+
TYPE("i8imm_brtarget", TYPE_REL)
10901091
TYPE("i16imm_brtarget", TYPE_REL)
10911092
TYPE("i32imm_brtarget", TYPE_REL)
10921093
TYPE("ccode", TYPE_IMM)
@@ -1409,6 +1410,7 @@ RecognizableInstr::relocationEncodingFromString(const std::string &s,
14091410
ENCODING("i64i32imm_brtarget", ENCODING_ID)
14101411
ENCODING("i16imm_brtarget", ENCODING_IW)
14111412
ENCODING("i32imm_brtarget", ENCODING_ID)
1413+
ENCODING("i8imm_brtarget", ENCODING_IB)
14121414
ENCODING("brtarget32", ENCODING_ID)
14131415
ENCODING("brtarget16", ENCODING_IW)
14141416
ENCODING("brtarget8", ENCODING_IB)

0 commit comments

Comments
 (0)