Skip to content

Commit f2dfb79

Browse files
committed
[x86][MC]: Fix data16.
1 parent dd6ec68 commit f2dfb79

File tree

4 files changed

+66
-3
lines changed

4 files changed

+66
-3
lines changed

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3523,8 +3523,35 @@ bool X86AsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
35233523
PatchedName = Name;
35243524

35253525
// Hacks to handle 'data16' and 'data32'
3526-
if (PatchedName == "data16" && is16BitMode()) {
3527-
return Error(NameLoc, "redundant data16 prefix");
3526+
if (PatchedName == "data16") {
3527+
if (is16BitMode())
3528+
return Error(NameLoc, "redundant data16 prefix");
3529+
if (getLexer().isNot(AsmToken::EndOfStatement)) {
3530+
StringRef Next = Parser.getTok().getString();
3531+
getLexer().Lex();
3532+
// data16 effectively changes the instruction suffix.
3533+
// TODO Generalize.
3534+
if (Next == "call")
3535+
Next = "callw";
3536+
if (Next == "ljmp")
3537+
Next = "ljmpw";
3538+
if (Next == "retf")
3539+
Next = "retfw";
3540+
if (Next == "lgdt") {
3541+
if (is64BitMode()) {
3542+
// Use the special lgdtq variant with OpSize16 flag.
3543+
// I think the CPU ignores the prefix anyway--but hey.
3544+
Next = "lgdtq16";
3545+
} else {
3546+
Next = "lgdtw";
3547+
}
3548+
}
3549+
3550+
Name = Next;
3551+
PatchedName = Name;
3552+
ForcedDataPrefix = X86::Is16Bit;
3553+
IsPrefix = false;
3554+
}
35283555
}
35293556
if (PatchedName == "data32") {
35303557
if (is32BitMode())

llvm/lib/Target/X86/X86InstrAsmAlias.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ def : MnemonicAlias<"cqo", "cqto", "att">;
260260
// In 64-bit mode lret maps to lretl; it is not ambiguous with lretq.
261261
def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>;
262262
def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>;
263+
def : InstAlias<"lgdtw\t$src", (LGDT16m opaquemem:$src), 0>, Requires<[Not64BitMode]>;
264+
def : InstAlias<"lgdtq16\t$src", (LGDT64m_16 opaquemem:$src), 0>, Requires<[In64BitMode]>;
265+
def : InstAlias<"retfw", (LRET16), 0>;
263266

264267
def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>;
265268
def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>;
@@ -723,6 +726,7 @@ def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR3
723726
def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>;
724727

725728
// test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
729+
def : InstAlias<"ljmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>;
726730
def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}",
727731
(TEST8mr i8mem :$mem, GR8 :$val), 0>;
728732
def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}",

llvm/lib/Target/X86/X86InstrSystem.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@ def LGDT32m : I<0x01, MRM2m, (outs), (ins opaquemem:$src),
427427
"lgdt{l|d}\t$src", []>, OpSize32, TB, Requires<[Not64BitMode]>;
428428
def LGDT64m : I<0x01, MRM2m, (outs), (ins opaquemem:$src),
429429
"lgdt{q}\t$src", []>, TB, Requires<[In64BitMode]>;
430+
// Special variant with data16 prefix (OpSize16) for 64-bit mode
431+
def LGDT64m_16 : I<0x01, MRM2m, (outs), (ins opaquemem:$src),
432+
"lgdt{q}\t$src", []>, TB, OpSize16, Requires<[In64BitMode]>;
430433
def LIDT16m : I<0x01, MRM3m, (outs), (ins opaquemem:$src),
431434
"lidtw\t$src", []>, TB, OpSize16, Requires<[Not64BitMode]>;
432435
def LIDT32m : I<0x01, MRM3m, (outs), (ins opaquemem:$src),

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
1-
// RUN: llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel %s | FileCheck %s
1+
// RUN: llvm-mc -triple i686-unknown-unknown -x86-asm-syntax=intel --show-encoding %s | FileCheck %s
22

33
// CHECK: leaw (%bp,%si), %ax
4+
// CHECK: encoding: [0x67,0x66,0x8d,0x02]
45
lea ax, [bp+si]
56
// CHECK: leaw (%bp,%si), %ax
7+
// CHECK: encoding: [0x67,0x66,0x8d,0x02]
68
lea ax, [si+bp]
9+
10+
// CHECK: encoding: [0x66,0x6a,0x08]
11+
data16 push 8
12+
13+
// CHECK: encoding: [0x6a,0x08]
14+
push 8
15+
16+
// CHECK: encoding: [0x66,0xcb]
17+
data16 retf
18+
19+
// CHECK: encoding: [0xcb]
20+
retf
21+
22+
// CHECK: encoding: [0x66,0x9a,0xcd,0xab,0xce,0x7a]
23+
data16 call 0x7ace, 0xabcd
24+
25+
// CHECK: encoding: [0x9a,0xcd,0xab,0x00,0x00,0xce,0x7a]
26+
call 0x7ace, 0xabcd
27+
28+
// CHECK: encoding: [0xe8,A,A,A,A]
29+
call a
30+
31+
// CHECK: encoding: [0x66,0xea,0xcd,0xab,0xce,0x7a]
32+
data16 ljmp 0x7ace, 0xabcd
33+
34+
// CHECK: encoding: [0xea,0xcd,0xab,0x00,0x00,0xce,0x7a]
35+
ljmp 0x7ace, 0xabcd

0 commit comments

Comments
 (0)