diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86.td | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 6 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 16 |
7 files changed, 79 insertions, 17 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 0f8e9f7b4ad..86ba1858190 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -544,9 +544,21 @@ private: // FIXME: Can tablegen auto-generate this? return (STI.getFeatureBits() & X86::Mode64Bit) != 0; } - void SwitchMode() { - unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit)); + bool is32BitMode() const { + // FIXME: Can tablegen auto-generate this? + return (STI.getFeatureBits() & X86::Mode32Bit) != 0; + } + bool is16BitMode() const { + // FIXME: Can tablegen auto-generate this? + return (STI.getFeatureBits() & X86::Mode16Bit) != 0; + } + void SwitchMode(uint64_t mode) { + uint64_t oldMode = STI.getFeatureBits() & + (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit); + unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(oldMode | mode)); setAvailableFeatures(FB); + assert(mode == (STI.getFeatureBits() & + (X86::Mode64Bit | X86::Mode32Bit | X86::Mode16Bit))); } bool isParsingIntelSyntax() { @@ -1033,7 +1045,8 @@ struct X86Operand : public MCParsedAsmOperand { } // end anonymous namespace. bool X86AsmParser::isSrcOp(X86Operand &Op) { - unsigned basereg = is64BitMode() ? X86::RSI : X86::ESI; + unsigned basereg = + is64BitMode() ? X86::RSI : (is32BitMode() ? X86::ESI : X86::SI); return (Op.isMem() && (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) && @@ -1043,7 +1056,8 @@ bool X86AsmParser::isSrcOp(X86Operand &Op) { } bool X86AsmParser::isDstOp(X86Operand &Op) { - unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI; + unsigned basereg = + is64BitMode() ? X86::RDI : (is32BitMode() ? X86::EDI : X86::DI); return Op.isMem() && (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) && @@ -1193,7 +1207,8 @@ X86AsmParser::CreateMemForInlineAsm(unsigned SegReg, const MCExpr *Disp, // operand to ensure proper matching. Just pick a GPR based on the size of // a pointer. if (!Info.IsVarDecl) { - unsigned RegNo = is64BitMode() ? X86::RBX : X86::EBX; + unsigned RegNo = + is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX); return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true, SMLoc(), Identifier, Info.OpDecl); } @@ -1612,7 +1627,8 @@ X86Operand *X86AsmParser::ParseIntelOffsetOfOperator() { // 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 : X86::EBX; + unsigned RegNo = + is64BitMode() ? X86::RBX : (is32BitMode() ? X86::EBX : X86::BX); return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true, OffsetOfLoc, Identifier, Info.OpDecl); } @@ -2679,18 +2695,24 @@ bool X86AsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { } /// ParseDirectiveCode -/// ::= .code32 | .code64 +/// ::= .code16 | .code32 | .code64 bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) { - if (IDVal == ".code32") { + if (IDVal == ".code16") { + Parser.Lex(); + if (!is16BitMode()) { + SwitchMode(X86::Mode16Bit); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); + } + } else if (IDVal == ".code32") { Parser.Lex(); - if (is64BitMode()) { - SwitchMode(); + if (!is32BitMode()) { + SwitchMode(X86::Mode32Bit); getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); } } else if (IDVal == ".code64") { Parser.Lex(); if (!is64BitMode()) { - SwitchMode(); + SwitchMode(X86::Mode64Bit); getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64); } } else { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 293541a8438..51b90b1c497 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -49,7 +49,12 @@ public: bool is32BitMode() const { // FIXME: Can tablegen auto-generate this? - return (STI.getFeatureBits() & X86::Mode64Bit) == 0; + return (STI.getFeatureBits() & X86::Mode32Bit) != 0; + } + + bool is16BitMode() const { + // FIXME: Can tablegen auto-generate this? + return (STI.getFeatureBits() & X86::Mode16Bit) != 0; } unsigned GetX86RegNum(const MCOperand &MO) const { @@ -1177,13 +1182,16 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, assert(!Is64BitMemOperand(MI, MemOperand)); need_address_override = Is16BitMemOperand(MI, MemOperand); } else { - need_address_override = false; + assert(is16BitMode()); + assert(!Is64BitMemOperand(MI, MemOperand)); + need_address_override = !Is16BitMemOperand(MI, MemOperand); } if (need_address_override) EmitByte(0x67, CurByte, OS); // Emit the operand size opcode prefix as needed. + // FIXME for is16BitMode(). if (TSFlags & X86II::OpSize) EmitByte(0x66, CurByte, OS); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index 403e50dbf8a..09803f372f5 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -47,9 +47,9 @@ std::string X86_MC::ParseX86Triple(StringRef TT) { Triple TheTriple(TT); std::string FS; if (TheTriple.getArch() == Triple::x86_64) - FS = "+64bit-mode"; + FS = "+64bit-mode,-32bit-mode,-16bit-mode"; else - FS = "-64bit-mode"; + FS = "-64bit-mode,+32bit-mode,-16bit-mode"; return FS; } diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index d55178ea12d..e755faeb171 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -22,6 +22,10 @@ include "llvm/Target/Target.td" def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true", "64-bit mode (x86_64)">; +def Mode32Bit : SubtargetFeature<"32bit-mode", "In32BitMode", "true", + "32-bit mode (80386)">; +def Mode16Bit : SubtargetFeature<"16bit-mode", "In16BitMode", "true", + "16-bit mode (i8086)">; //===----------------------------------------------------------------------===// // X86 Subtarget features diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 707a313f14b..9642a8926d5 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -700,6 +700,12 @@ def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">; def In64BitMode : Predicate<"Subtarget->is64Bit()">, AssemblerPredicate<"Mode64Bit", "64-bit mode">; +def In16BitMode : Predicate<"Subtarget->is16Bit()">, + AssemblerPredicate<"Mode16Bit", "16-bit mode">; +def Not16BitMode : Predicate<"!Subtarget->is16Bit()">, + AssemblerPredicate<"!Mode16Bit", "Not 16-bit mode">; +def In32BitMode : Predicate<"Subtarget->is32Bit()">, + AssemblerPredicate<"Mode32Bit", "32-bit mode">; def IsWin64 : Predicate<"Subtarget->isTargetWin64()">; def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 597fccb9fdb..5ee986c9a82 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -482,6 +482,12 @@ void X86Subtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) { // target data structure which is shared with MC code emitter, etc. if (In64BitMode) ToggleFeature(X86::Mode64Bit); + else if (In32BitMode) + ToggleFeature(X86::Mode32Bit); + else if (In16BitMode) + ToggleFeature(X86::Mode16Bit); + else + llvm_unreachable("Not 16-bit, 32-bit or 64-bit mode!"); DEBUG(dbgs() << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel @@ -551,7 +557,9 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU, , PICStyle(PICStyles::None) , TargetTriple(TT) , StackAlignOverride(StackAlignOverride) - , In64BitMode(is64Bit) { + , In64BitMode(is64Bit) + , In32BitMode(!is64Bit) + , In16BitMode(false) { initializeEnvironment(); resetSubtargetFeatures(CPU, FS); } diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 93d251a6794..f39389e08c6 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -205,9 +205,15 @@ private: /// StackAlignOverride - Override the stack alignment. unsigned StackAlignOverride; - /// In64BitMode - True if compiling for 64-bit, false for 32-bit. + /// In64BitMode - True if compiling for 64-bit, false for 16-bit or 32-bit. bool In64BitMode; + /// In32BitMode - True if compiling for 32-bit, false for 16-bit or 64-bit. + bool In32BitMode; + + /// In16BitMode - True if compiling for 16-bit, false for 32-bit or 64-bit. + bool In16BitMode; + public: /// This constructor initializes the data members to match that /// of the specified triple. @@ -244,6 +250,14 @@ public: return In64BitMode; } + bool is32Bit() const { + return In32BitMode; + } + + bool is16Bit() const { + return In16BitMode; + } + /// Is this x86_64 with the ILP32 programming model (x32 ABI)? bool isTarget64BitILP32() const { return In64BitMode && (TargetTriple.getEnvironment() == Triple::GNUX32 || |