@@ -59,6 +59,7 @@ class X86AsmParser : public MCTargetAsmParser {
59
59
const MCInstrInfo &MII;
60
60
ParseInstructionInfo *InstInfo;
61
61
std::unique_ptr<X86AsmInstrumentation> Instrumentation;
62
+ bool Code16GCC;
62
63
63
64
private:
64
65
SMLoc consumeToken () {
@@ -68,6 +69,19 @@ class X86AsmParser : public MCTargetAsmParser {
68
69
return Result;
69
70
}
70
71
72
+ unsigned MatchInstruction (const OperandVector &Operands, MCInst &Inst,
73
+ uint64_t &ErrorInfo, bool matchingInlineAsm,
74
+ unsigned VariantID = 0 ) {
75
+ // In Code16GCC mode, match as 32-bit.
76
+ if (Code16GCC)
77
+ SwitchMode (X86::Mode32Bit);
78
+ unsigned rv = MatchInstructionImpl (Operands, Inst, ErrorInfo,
79
+ matchingInlineAsm, VariantID);
80
+ if (Code16GCC)
81
+ SwitchMode (X86::Mode16Bit);
82
+ return rv;
83
+ }
84
+
71
85
enum InfixCalculatorTok {
72
86
IC_OR = 0 ,
73
87
IC_XOR,
@@ -794,7 +808,8 @@ class X86AsmParser : public MCTargetAsmParser {
794
808
public:
795
809
X86AsmParser (const MCSubtargetInfo &sti, MCAsmParser &Parser,
796
810
const MCInstrInfo &mii, const MCTargetOptions &Options)
797
- : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr ) {
811
+ : MCTargetAsmParser(Options, sti), MII(mii), InstInfo(nullptr ),
812
+ Code16GCC (false ) {
798
813
799
814
// Initialize the set of available features.
800
815
setAvailableFeatures (ComputeAvailableFeatures (getSTI ().getFeatureBits ()));
@@ -983,20 +998,20 @@ void X86AsmParser::SetFrameRegister(unsigned RegNo) {
983
998
}
984
999
985
1000
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemSIOperand (SMLoc Loc) {
986
- unsigned basereg =
987
- is64BitMode () ? X86::RSI : (is32BitMode () ? X86::ESI : X86::SI);
1001
+ bool Parse32 = is32BitMode () || Code16GCC;
1002
+ unsigned Basereg = is64BitMode () ? X86::RSI : (Parse32 ? X86::ESI : X86::SI);
988
1003
const MCExpr *Disp = MCConstantExpr::create (0 , getContext ());
989
1004
return X86Operand::CreateMem (getPointerWidth (), /* SegReg=*/ 0 , Disp,
990
- /* BaseReg=*/ basereg , /* IndexReg=*/ 0 , /* Scale=*/ 1 ,
1005
+ /* BaseReg=*/ Basereg , /* IndexReg=*/ 0 , /* Scale=*/ 1 ,
991
1006
Loc, Loc, 0 );
992
1007
}
993
1008
994
1009
std::unique_ptr<X86Operand> X86AsmParser::DefaultMemDIOperand (SMLoc Loc) {
995
- unsigned basereg =
996
- is64BitMode () ? X86::RDI : (is32BitMode () ? X86::EDI : X86::DI);
1010
+ bool Parse32 = is32BitMode () || Code16GCC;
1011
+ unsigned Basereg = is64BitMode () ? X86::RDI : (Parse32 ? X86::EDI : X86::DI);
997
1012
const MCExpr *Disp = MCConstantExpr::create (0 , getContext ());
998
1013
return X86Operand::CreateMem (getPointerWidth (), /* SegReg=*/ 0 , Disp,
999
- /* BaseReg=*/ basereg , /* IndexReg=*/ 0 , /* Scale=*/ 1 ,
1014
+ /* BaseReg=*/ Basereg , /* IndexReg=*/ 0 , /* Scale=*/ 1 ,
1000
1015
Loc, Loc, 0 );
1001
1016
}
1002
1017
@@ -1672,8 +1687,9 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOffsetOfOperator() {
1672
1687
// The offset operator will have an 'r' constraint, thus we need to create
1673
1688
// register operand to ensure proper matching. Just pick a GPR based on
1674
1689
// the size of a pointer.
1675
- unsigned RegNo =
1676
- is64BitMode () ? X86::RBX : (is32BitMode () ? X86::EBX : X86::BX);
1690
+ bool Parse32 = is32BitMode () || Code16GCC;
1691
+ unsigned RegNo = is64BitMode () ? X86::RBX : (Parse32 ? X86::EBX : X86::BX);
1692
+
1677
1693
return X86Operand::CreateReg (RegNo, Start, End, /* GetAddress=*/ true ,
1678
1694
OffsetOfLoc, Identifier, Info.OpDecl );
1679
1695
}
@@ -2585,9 +2601,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2585
2601
MCInst Inst;
2586
2602
2587
2603
// First, try a direct match.
2588
- switch (MatchInstructionImpl (Operands, Inst,
2589
- ErrorInfo, MatchingInlineAsm,
2590
- isParsingIntelSyntax ())) {
2604
+ switch (MatchInstruction (Operands, Inst, ErrorInfo, MatchingInlineAsm,
2605
+ isParsingIntelSyntax ())) {
2591
2606
default : llvm_unreachable (" Unexpected match result!" );
2592
2607
case Match_Success:
2593
2608
// Some instructions need post-processing to, for example, tweak which
@@ -2638,8 +2653,8 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
2638
2653
2639
2654
for (unsigned I = 0 , E = array_lengthof (Match); I != E; ++I) {
2640
2655
Tmp.back () = Suffixes[I];
2641
- Match[I] = MatchInstructionImpl (Operands, Inst, ErrorInfoIgnore,
2642
- MatchingInlineAsm, isParsingIntelSyntax ());
2656
+ Match[I] = MatchInstruction (Operands, Inst, ErrorInfoIgnore,
2657
+ MatchingInlineAsm, isParsingIntelSyntax ());
2643
2658
// If this returned as a missing feature failure, remember that.
2644
2659
if (Match[I] == Match_MissingFeature)
2645
2660
ErrorInfoMissingFeature = ErrorInfoIgnore;
@@ -2785,9 +2800,8 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2785
2800
UnsizedMemOp->Mem .Size = Size;
2786
2801
uint64_t ErrorInfoIgnore;
2787
2802
unsigned LastOpcode = Inst.getOpcode ();
2788
- unsigned M =
2789
- MatchInstructionImpl (Operands, Inst, ErrorInfoIgnore,
2790
- MatchingInlineAsm, isParsingIntelSyntax ());
2803
+ unsigned M = MatchInstruction (Operands, Inst, ErrorInfoIgnore,
2804
+ MatchingInlineAsm, isParsingIntelSyntax ());
2791
2805
if (Match.empty () || LastOpcode != Inst.getOpcode ())
2792
2806
Match.push_back (M);
2793
2807
@@ -2805,9 +2819,8 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
2805
2819
// operation. There shouldn't be any ambiguity in our mnemonic table, so try
2806
2820
// matching with the unsized operand.
2807
2821
if (Match.empty ()) {
2808
- Match.push_back (MatchInstructionImpl (Operands, Inst, ErrorInfo,
2809
- MatchingInlineAsm,
2810
- isParsingIntelSyntax ()));
2822
+ Match.push_back (MatchInstruction (
2823
+ Operands, Inst, ErrorInfo, MatchingInlineAsm, isParsingIntelSyntax ()));
2811
2824
// If this returned as a missing feature failure, remember that.
2812
2825
if (Match.back () == Match_MissingFeature)
2813
2826
ErrorInfoMissingFeature = ErrorInfo;
@@ -2967,12 +2980,21 @@ bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
2967
2980
// / ::= .code16 | .code32 | .code64
2968
2981
bool X86AsmParser::ParseDirectiveCode (StringRef IDVal, SMLoc L) {
2969
2982
MCAsmParser &Parser = getParser ();
2983
+ Code16GCC = false ;
2970
2984
if (IDVal == " .code16" ) {
2971
2985
Parser.Lex ();
2972
2986
if (!is16BitMode ()) {
2973
2987
SwitchMode (X86::Mode16Bit);
2974
2988
getParser ().getStreamer ().EmitAssemblerFlag (MCAF_Code16);
2975
2989
}
2990
+ } else if (IDVal == " .code16gcc" ) {
2991
+ // .code16gcc parses as if in 32-bit mode, but emits code in 16-bit mode.
2992
+ Parser.Lex ();
2993
+ Code16GCC = true ;
2994
+ if (!is16BitMode ()) {
2995
+ SwitchMode (X86::Mode16Bit);
2996
+ getParser ().getStreamer ().EmitAssemblerFlag (MCAF_Code16);
2997
+ }
2976
2998
} else if (IDVal == " .code32" ) {
2977
2999
Parser.Lex ();
2978
3000
if (!is32BitMode ()) {
0 commit comments