llvm.org GIT mirror llvm / 134d28b
Add support for Code16GCC [X86] The .code16gcc directive parses X86 assembly input in 32-bit mode and outputs in 16-bit mode. Teach parser to switch modes appropriately. Reviewers: dwmw2, craig.topper Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D20109 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282430 91177308-0d34-0410-b5e6-96231b3b80d8 Nirav Dave 4 years ago
2 changed file(s) with 109 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
5858 const MCInstrInfo &MII;
5959 ParseInstructionInfo *InstInfo;
6060 std::unique_ptr Instrumentation;
61 bool Code16GCC;
6162
6263 private:
6364 SMLoc consumeToken() {
6566 SMLoc Result = Parser.getTok().getLoc();
6667 Parser.Lex();
6768 return Result;
69 }
70
71 unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
72 uint64_t &ErrorInfo, bool matchingInlineAsm,
73 unsigned VariantID = 0) {
74 // In Code16GCC mode, match as 32-bit.
75 if (Code16GCC)
76 SwitchMode(X86::Mode32Bit);
77 unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
78 matchingInlineAsm, VariantID);
79 if (Code16GCC)
80 SwitchMode(X86::Mode16Bit);
81 return rv;
6882 }
6983
7084 enum InfixCalculatorTok {
793807 public:
794808 X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
795809 const MCInstrInfo &mii, const MCTargetOptions &Options)
796 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
810 : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
811 Code16GCC(false) {
797812
798813 // Initialize the set of available features.
799814 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
982997 }
983998
984999 std::unique_ptr X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
985 unsigned basereg =
986 is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
1000 bool Parse32 = is32BitMode() || Code16GCC;
1001 unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
9871002 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
9881003 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
989 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1004 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
9901005 Loc, Loc, 0);
9911006 }
9921007
9931008 std::unique_ptr X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
994 unsigned basereg =
995 is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
1009 bool Parse32 = is32BitMode() || Code16GCC;
1010 unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
9961011 const MCExpr *Disp = MCConstantExpr::create(0, getContext());
9971012 return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
998 /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
1013 /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
9991014 Loc, Loc, 0);
10001015 }
10011016
16711686 // The offset operator will have an 'r' constraint, thus we need to create
16721687 // register operand to ensure proper matching. Just pick a GPR based on
16731688 // the size of a pointer.
1674 unsigned RegNo =
1675 is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
1689 bool Parse32 = is32BitMode() || Code16GCC;
1690 unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1691
16761692 return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
16771693 OffsetOfLoc, Identifier, Info.OpDecl);
16781694 }
25842600 MCInst Inst;
25852601
25862602 // First, try a direct match.
2587 switch (MatchInstructionImpl(Operands, Inst,
2588 ErrorInfo, MatchingInlineAsm,
2589 isParsingIntelSyntax())) {
2603 switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
2604 isParsingIntelSyntax())) {
25902605 default: llvm_unreachable("Unexpected match result!");
25912606 case Match_Success:
25922607 // Some instructions need post-processing to, for example, tweak which
26372652
26382653 for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
26392654 Tmp.back() = Suffixes[I];
2640 Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2641 MatchingInlineAsm, isParsingIntelSyntax());
2655 Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2656 MatchingInlineAsm, isParsingIntelSyntax());
26422657 // If this returned as a missing feature failure, remember that.
26432658 if (Match[I] == Match_MissingFeature)
26442659 ErrorInfoMissingFeature = ErrorInfoIgnore;
27842799 UnsizedMemOp->Mem.Size = Size;
27852800 uint64_t ErrorInfoIgnore;
27862801 unsigned LastOpcode = Inst.getOpcode();
2787 unsigned M =
2788 MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
2789 MatchingInlineAsm, isParsingIntelSyntax());
2802 unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
2803 MatchingInlineAsm, isParsingIntelSyntax());
27902804 if (Match.empty() || LastOpcode != Inst.getOpcode())
27912805 Match.push_back(M);
27922806
28042818 // operation. There shouldn't be any ambiguity in our mnemonic table, so try
28052819 // matching with the unsized operand.
28062820 if (Match.empty()) {
2807 Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
2808 MatchingInlineAsm,
2809 isParsingIntelSyntax()));
2821 Match.push_back(MatchInstruction(
2822 Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
28102823 // If this returned as a missing feature failure, remember that.
28112824 if (Match.back() == Match_MissingFeature)
28122825 ErrorInfoMissingFeature = ErrorInfo;
29662979 /// ::= .code16 | .code32 | .code64
29672980 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
29682981 MCAsmParser &Parser = getParser();
2982 Code16GCC = false;
29692983 if (IDVal == ".code16") {
29702984 Parser.Lex();
29712985 if (!is16BitMode()) {
29722986 SwitchMode(X86::Mode16Bit);
29732987 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
29742988 }
2989 } else if (IDVal == ".code16gcc") {
2990 // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
2991 Parser.Lex();
2992 Code16GCC = true;
2993 if (!is16BitMode()) {
2994 SwitchMode(X86::Mode16Bit);
2995 getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
2996 }
29752997 } else if (IDVal == ".code32") {
29762998 Parser.Lex();
29772999 if (!is32BitMode()) {
0 // RUN: llvm-mc -triple i386-unknown-unknown-unknown --show-encoding %s | FileCheck %s
1
2 .code16gcc
3 //CHECK: .code16
4 nop
5 //CHECK: nop # encoding: [0x90]
6 lodsb
7 //CHECK: lodsb (%esi), %al # encoding: [0x67,0xac]
8 lodsb (%si), %al
9 //CHECK: lodsb (%si), %al # encoding: [0xac]
10 lodsb (%esi), %al
11 //CHECK: lodsb (%esi), %al # encoding: [0x67,0xac]
12 lodsl %gs:(%esi)
13 //CHECK: lodsl %gs:(%esi), %eax # encoding: [0x66,0x65,0x67,0xad]
14 lods (%esi), %ax
15 //CHECK: lodsw (%esi), %ax # encoding: [0x67,0xad]
16 stosw
17 //CHECK: stosw %ax, %es:(%edi) # encoding: [0x67,0xab]
18 stos %eax, (%edi)
19 //CHECK: stosl %eax, %es:(%edi) # encoding: [0x66,0x67,0xab]
20 stosb %al, %es:(%edi)
21 //CHECK: stosb %al, %es:(%edi) # encoding: [0x67,0xaa]
22 scas %es:(%edi), %al
23 //CHECK: scasb %es:(%edi), %al # encoding: [0x67,0xae]
24 scas %es:(%di), %ax
25 //CHECK: scasw %es:(%di), %ax # encoding: [0xaf]
26 cmpsb
27 //CHECK: cmpsb %es:(%edi), (%esi) # encoding: [0x67,0xa6]
28 cmpsw (%edi), (%esi)
29 //CHECK: cmpsw %es:(%edi), (%esi) # encoding: [0x67,0xa7]
30 cmpsl %es:(%edi), %ss:(%esi)
31 //CHECK: cmpsl %es:(%edi), %ss:(%esi) # encoding: [0x66,0x36,0x67,0xa7]
32 movsb (%esi), (%edi)
33 //CHECK: movsb (%esi), %es:(%edi) # encoding: [0x67,0xa4]
34 movsl %gs:(%esi), (%edi)
35 //CHECK: movsl %gs:(%esi), %es:(%edi) # encoding: [0x66,0x65,0x67,0xa5]
36 outsb
37 //CHECK: outsb (%esi), %dx # encoding: [0x67,0x6e]
38 outsw %fs:(%esi), %dx
39 //CHECK: outsw %fs:(%esi), %dx # encoding: [0x64,0x67,0x6f]
40 insw %dx, (%di)
41 //CHECK: insw %dx, %es:(%di) # encoding: [0x6d]
42 call $0x7ace,$0x7ace
43 //CHECK: lcalll $31438, $31438 # encoding: [0x66,0x9a,0xce,0x7a,0x00,0x00,0xce,0x7a]
44 ret
45 //CHECK: retl # encoding: [0x66,0xc3]
46 pop %ss
47 //CHECK: popl %ss # encoding: [0x66,0x17]
48 enter $0x7ace,$0x7f
49 //CHECK: enter $31438, $127 # encoding: [0xc8,0xce,0x7a,0x7f]
50 leave
51 //CHECK: leave # encoding: [0xc9]
52 push %ss
53 //CHECK: pushl %ss # encoding: [0x66,0x16]
54 pop %ss
55 //CHECK: popl %ss # encoding: [0x66,0x17]
56 popa
57 //CHECK: popal # encoding: [0x66,0x61]
58 pushf
59 //CHECK: pushfl # encoding: [0x66,0x9c]
60 popf
61 //CHECK: popfl # encoding: [0x66,0x9d]
62 pushw 4
63 //CHECK: pushw 4 # encoding: [0xff,0x36,0x04,0x00]
64
65
66