[llvm] r282430 - Add support for Code16GCC

Nirav Dave via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 26 12:33:37 PDT 2016


Author: niravd
Date: Mon Sep 26 14:33:36 2016
New Revision: 282430

URL: http://llvm.org/viewvc/llvm-project?rev=282430&view=rev
Log:
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

Added:
    llvm/trunk/test/MC/X86/code16gcc.s
Modified:
    llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp

Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=282430&r1=282429&r2=282430&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Sep 26 14:33:36 2016
@@ -59,6 +59,7 @@ class X86AsmParser : public MCTargetAsmP
   const MCInstrInfo &MII;
   ParseInstructionInfo *InstInfo;
   std::unique_ptr<X86AsmInstrumentation> Instrumentation;
+  bool Code16GCC;
 
 private:
   SMLoc consumeToken() {
@@ -68,6 +69,19 @@ private:
     return Result;
   }
 
+  unsigned MatchInstruction(const OperandVector &Operands, MCInst &Inst,
+                            uint64_t &ErrorInfo, bool matchingInlineAsm,
+                            unsigned VariantID = 0) {
+    // In Code16GCC mode, match as 32-bit.
+    if (Code16GCC)
+      SwitchMode(X86::Mode32Bit);
+    unsigned rv = MatchInstructionImpl(Operands, Inst, ErrorInfo,
+                                       matchingInlineAsm, VariantID);
+    if (Code16GCC)
+      SwitchMode(X86::Mode16Bit);
+    return rv;
+  }
+
   enum InfixCalculatorTok {
     IC_OR = 0,
     IC_XOR,
@@ -794,7 +808,8 @@ private:
 public:
   X86AsmParser(const MCSubtargetInfo &sti, MCAsmParser &Parser,
                const MCInstrInfo &mii, const MCTargetOptions &Options)
-    : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr) {
+      : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr),
+        Code16GCC(false) {
 
     // Initialize the set of available features.
     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
@@ -983,20 +998,20 @@ void X86AsmParser::SetFrameRegister(unsi
 }
 
 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand(SMLoc Loc) {
-  unsigned basereg =
-    is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI);
+  bool Parse32 = is32BitMode() || Code16GCC;
+  unsigned Basereg = is64BitMode() ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
   const MCExpr *Disp = MCConstantExpr::create(0, getContext());
   return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
-                               /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
+                               /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
                                Loc, Loc, 0);
 }
 
 std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand(SMLoc Loc) {
-  unsigned basereg =
-    is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI);
+  bool Parse32 = is32BitMode() || Code16GCC;
+  unsigned Basereg = is64BitMode() ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
   const MCExpr *Disp = MCConstantExpr::create(0, getContext());
   return X86Operand::CreateMem(getPointerWidth(), /*SegReg=*/0, Disp,
-                               /*BaseReg=*/basereg, /*IndexReg=*/0, /*Scale=*/1,
+                               /*BaseReg=*/Basereg, /*IndexReg=*/0, /*Scale=*/1,
                                Loc, Loc, 0);
 }
 
@@ -1672,8 +1687,9 @@ std::unique_ptr<X86Operand> X86AsmParser
   // The offset operator will have an 'r' constraint, thus we need to create
   // register operand to ensure proper matching.  Just pick a GPR based on
   // the size of a pointer.
-  unsigned RegNo =
-      is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX);
+  bool Parse32 = is32BitMode() || Code16GCC;
+  unsigned RegNo = is64BitMode() ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
+
   return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
                                OffsetOfLoc, Identifier, Info.OpDecl);
 }
@@ -2585,9 +2601,8 @@ bool X86AsmParser::MatchAndEmitATTInstru
   MCInst Inst;
 
   // First, try a direct match.
-  switch (MatchInstructionImpl(Operands, Inst,
-                               ErrorInfo, MatchingInlineAsm,
-                               isParsingIntelSyntax())) {
+  switch (MatchInstruction(Operands, Inst, ErrorInfo, MatchingInlineAsm,
+                           isParsingIntelSyntax())) {
   default: llvm_unreachable("Unexpected match result!");
   case Match_Success:
     // Some instructions need post-processing to, for example, tweak which
@@ -2638,8 +2653,8 @@ bool X86AsmParser::MatchAndEmitATTInstru
 
   for (unsigned I = 0, E = array_lengthof(Match); I != E; ++I) {
     Tmp.back() = Suffixes[I];
-    Match[I] = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
-                                  MatchingInlineAsm, isParsingIntelSyntax());
+    Match[I] = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
+                                MatchingInlineAsm, isParsingIntelSyntax());
     // If this returned as a missing feature failure, remember that.
     if (Match[I] == Match_MissingFeature)
       ErrorInfoMissingFeature = ErrorInfoIgnore;
@@ -2785,9 +2800,8 @@ bool X86AsmParser::MatchAndEmitIntelInst
       UnsizedMemOp->Mem.Size = Size;
       uint64_t ErrorInfoIgnore;
       unsigned LastOpcode = Inst.getOpcode();
-      unsigned M =
-          MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore,
-                               MatchingInlineAsm, isParsingIntelSyntax());
+      unsigned M = MatchInstruction(Operands, Inst, ErrorInfoIgnore,
+                                    MatchingInlineAsm, isParsingIntelSyntax());
       if (Match.empty() || LastOpcode != Inst.getOpcode())
         Match.push_back(M);
 
@@ -2805,9 +2819,8 @@ bool X86AsmParser::MatchAndEmitIntelInst
   // operation.  There shouldn't be any ambiguity in our mnemonic table, so try
   // matching with the unsized operand.
   if (Match.empty()) {
-    Match.push_back(MatchInstructionImpl(Operands, Inst, ErrorInfo,
-                                         MatchingInlineAsm,
-                                         isParsingIntelSyntax()));
+    Match.push_back(MatchInstruction(
+        Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax()));
     // If this returned as a missing feature failure, remember that.
     if (Match.back() == Match_MissingFeature)
       ErrorInfoMissingFeature = ErrorInfo;
@@ -2967,11 +2980,20 @@ bool X86AsmParser::ParseDirectiveWord(un
 ///  ::= .code16 | .code32 | .code64
 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
   MCAsmParser &Parser = getParser();
+  Code16GCC = false;
   if (IDVal == ".code16") {
     Parser.Lex();
     if (!is16BitMode()) {
       SwitchMode(X86::Mode16Bit);
       getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
+    }
+  } else if (IDVal == ".code16gcc") {
+    // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
+    Parser.Lex();
+    Code16GCC = true;
+    if (!is16BitMode()) {
+      SwitchMode(X86::Mode16Bit);
+      getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
     }
   } else if (IDVal == ".code32") {
     Parser.Lex();

Added: llvm/trunk/test/MC/X86/code16gcc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/code16gcc.s?rev=282430&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/code16gcc.s (added)
+++ llvm/trunk/test/MC/X86/code16gcc.s Mon Sep 26 14:33:36 2016
@@ -0,0 +1,67 @@
+// RUN: llvm-mc -triple i386-unknown-unknown-unknown --show-encoding %s | FileCheck %s 
+
+	.code16gcc
+	//CHECK:	.code16
+	nop
+	//CHECK:	nop                             # encoding: [0x90]
+	lodsb
+	//CHECK:	lodsb	(%esi), %al             # encoding: [0x67,0xac]
+	lodsb (%si), %al
+	//CHECK:	lodsb	(%si), %al              # encoding: [0xac]
+	lodsb (%esi), %al
+	//CHECK:	lodsb	(%esi), %al             # encoding: [0x67,0xac]
+	lodsl %gs:(%esi)
+	//CHECK:	lodsl	%gs:(%esi), %eax        # encoding: [0x66,0x65,0x67,0xad]
+	lods (%esi), %ax
+	//CHECK:	lodsw	(%esi), %ax             # encoding: [0x67,0xad]
+	stosw
+	//CHECK:	stosw	%ax, %es:(%edi)         # encoding: [0x67,0xab]
+	stos %eax, (%edi)
+	//CHECK:	stosl	%eax, %es:(%edi)        # encoding: [0x66,0x67,0xab]
+	stosb %al, %es:(%edi)
+	//CHECK:	stosb	%al, %es:(%edi)         # encoding: [0x67,0xaa]
+	scas %es:(%edi), %al
+	//CHECK:	scasb	%es:(%edi), %al         # encoding: [0x67,0xae]
+	scas %es:(%di), %ax
+	//CHECK:	scasw	%es:(%di), %ax          # encoding: [0xaf]
+	cmpsb
+	//CHECK:	cmpsb	%es:(%edi), (%esi)      # encoding: [0x67,0xa6]
+	cmpsw (%edi), (%esi)
+	//CHECK:	cmpsw	%es:(%edi), (%esi)      # encoding: [0x67,0xa7]
+	cmpsl %es:(%edi), %ss:(%esi)
+	//CHECK:	cmpsl	%es:(%edi), %ss:(%esi)  # encoding: [0x66,0x36,0x67,0xa7]
+	movsb (%esi), (%edi)
+	//CHECK:	movsb	(%esi), %es:(%edi)      # encoding: [0x67,0xa4]
+	movsl %gs:(%esi), (%edi)
+	//CHECK:	movsl	%gs:(%esi), %es:(%edi)  # encoding: [0x66,0x65,0x67,0xa5]
+	outsb
+	//CHECK:	outsb	(%esi), %dx             # encoding: [0x67,0x6e]
+	outsw %fs:(%esi), %dx
+	//CHECK:	outsw	%fs:(%esi), %dx         # encoding: [0x64,0x67,0x6f]
+	insw %dx, (%di)
+	//CHECK:	insw	%dx, %es:(%di)          # encoding: [0x6d]
+	call $0x7ace,$0x7ace
+	//CHECK:	lcalll	$31438, $31438          # encoding: [0x66,0x9a,0xce,0x7a,0x00,0x00,0xce,0x7a]
+	ret
+	//CHECK:	retl                            # encoding: [0x66,0xc3]
+	pop %ss
+	//CHECK:	popl	%ss                     # encoding: [0x66,0x17]
+	enter $0x7ace,$0x7f
+	//CHECK:	enter	$31438, $127            # encoding: [0xc8,0xce,0x7a,0x7f]
+	leave
+	//CHECK:	leave                           # encoding: [0xc9]
+	push %ss
+	//CHECK:	pushl	%ss                     # encoding: [0x66,0x16]
+	pop %ss
+	//CHECK:	popl	%ss                     # encoding: [0x66,0x17]
+	popa
+	//CHECK:	popal                           # encoding: [0x66,0x61]
+	pushf
+	//CHECK:	pushfl                          # encoding: [0x66,0x9c]
+	popf
+	//CHECK:	popfl                           # encoding: [0x66,0x9d]
+	pushw 4
+	//CHECK:	pushw	4                       # encoding: [0xff,0x36,0x04,0x00]
+
+	
+




More information about the llvm-commits mailing list