[PATCH v2 02/14] [x86] Add basic support for .code16
Craig Topper
craig.topper at gmail.com
Sun Jan 5 05:32:36 PST 2014
Is it possible to do this with only one new feature bit. Can we just have
Mode16Bit and Mode64Bit with Mode32 implied if the others aren't set?
I believe AssemblerPredicate takes a comma separated list of feature names
with negations.
On Wed, Dec 18, 2013 at 12:08 PM, David Woodhouse <dwmw2 at infradead.org>wrote:
>
> ---
> lib/Target/X86/AsmParser/X86AsmParser.cpp | 41
> +++++++++++++++++++-----
> lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 12 ++++++-
> lib/Target/X86/X86.td | 2 ++
> lib/Target/X86/X86Subtarget.h | 9 +++++-
> 4 files changed, 54 insertions(+), 10 deletions(-)
>
> diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp
> b/lib/Target/X86/AsmParser/X86AsmParser.cpp
> index 15dcc5c..3f5b266 100644
> --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp
> +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp
> @@ -544,10 +544,18 @@ private:
> // FIXME: Can tablegen auto-generate this?
> return (STI.getFeatureBits() & X86::Mode64Bit) != 0;
> }
> - void SwitchMode() {
> + bool is16BitMode() const {
> + // FIXME: Can tablegen auto-generate this?
> + return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
> + }
> + void SwitchMode64() {
> unsigned FB =
> ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode64Bit));
> setAvailableFeatures(FB);
> }
> + void SwitchMode16() {
> + unsigned FB =
> ComputeAvailableFeatures(STI.ToggleFeature(X86::Mode16Bit));
> + setAvailableFeatures(FB);
> + }
>
> bool isParsingIntelSyntax() {
> return getParser().getAssemblerDialect();
> @@ -1033,7 +1041,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 :
> + (is16BitMode() ? X86::SI : X86::ESI);
>
> return (Op.isMem() &&
> (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::DS) &&
> @@ -1043,7 +1052,8 @@ bool X86AsmParser::isSrcOp(X86Operand &Op) {
> }
>
> bool X86AsmParser::isDstOp(X86Operand &Op) {
> - unsigned basereg = is64BitMode() ? X86::RDI : X86::EDI;
> + unsigned basereg = is64BitMode() ? X86::RDI :
> + (is16BitMode() ? X86::DI : X86::EDI);
>
> return Op.isMem() &&
> (Op.Mem.SegReg == 0 || Op.Mem.SegReg == X86::ES) &&
> @@ -1193,7 +1203,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 :
> + (is16BitMode() ? X86::BX : X86::EBX);
> return X86Operand::CreateReg(RegNo, Start, End, /*AddressOf=*/true,
> SMLoc(), Identifier, Info.OpDecl);
> }
> @@ -1587,7 +1598,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 :
> + (is16BitMode() ? X86::BX : X86::EBX);
> return X86Operand::CreateReg(RegNo, Start, End, /*GetAddress=*/true,
> OffsetOfLoc, Identifier, Info.OpDecl);
> }
> @@ -2648,16 +2660,29 @@ bool X86AsmParser::ParseDirectiveWord(unsigned
> Size, SMLoc L) {
> /// ParseDirectiveCode
> /// ::= .code32 | .code64
> bool X86AsmParser::ParseDirectiveCode(StringRef IDVal, SMLoc L) {
> - if (IDVal == ".code32") {
> + if (IDVal == ".code16") {
> + Parser.Lex();
> + if (!is16BitMode()) {
> + if (is64BitMode())
> + SwitchMode64();
> + SwitchMode16();
> + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16);
> + }
> + } else if (IDVal == ".code32") {
> Parser.Lex();
> if (is64BitMode()) {
> - SwitchMode();
> + SwitchMode64();
> + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
> + } else if (is16BitMode()) {
> + SwitchMode16();
> getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32);
> }
> } else if (IDVal == ".code64") {
> Parser.Lex();
> if (!is64BitMode()) {
> - SwitchMode();
> + if (is16BitMode())
> + SwitchMode16();
> + SwitchMode64();
> getParser().getStreamer().EmitAssemblerFlag(MCAF_Code64);
> }
> } else {
> diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> index 7a8e71d..1ce876b 100644
> --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
> @@ -49,7 +49,13 @@ public:
>
> bool is32BitMode() const {
> // FIXME: Can tablegen auto-generate this?
> - return (STI.getFeatureBits() & X86::Mode64Bit) == 0;
> + return (STI.getFeatureBits() & X86::Mode64Bit) == 0 &&
> + (STI.getFeatureBits() & X86::Mode16Bit) == 0;
> + }
> +
> + bool is16BitMode() const {
> + // FIXME: Can tablegen auto-generate this?
> + return (STI.getFeatureBits() & X86::Mode16Bit) != 0;
> }
>
> unsigned GetX86RegNum(const MCOperand &MO) const {
> @@ -1146,6 +1152,9 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t
> TSFlags, unsigned &CurByte,
> } else if (is64BitMode()) {
> assert(!Is16BitMemOperand(MI, MemOperand));
> need_address_override = Is32BitMemOperand(MI, MemOperand);
> + } else if (is16BitMode()) {
> + assert(!Is64BitMemOperand(MI, MemOperand));
> + need_address_override = !Is16BitMemOperand(MI, MemOperand);
> } else if (is32BitMode()) {
> assert(!Is64BitMemOperand(MI, MemOperand));
> need_address_override = Is16BitMemOperand(MI, MemOperand);
> @@ -1157,6 +1166,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t
> TSFlags, unsigned &CurByte,
> 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/lib/Target/X86/X86.td b/lib/Target/X86/X86.td
> index d55178e..7ec9468 100644
> --- a/lib/Target/X86/X86.td
> +++ b/lib/Target/X86/X86.td
> @@ -22,6 +22,8 @@ include "llvm/Target/Target.td"
>
> def Mode64Bit : SubtargetFeature<"64bit-mode", "In64BitMode", "true",
> "64-bit mode (x86_64)">;
> +def Mode16Bit : SubtargetFeature<"16bit-mode", "In16BitMode", "true",
> + "16-bit mode (i8086)">;
>
>
> //===----------------------------------------------------------------------===//
> // X86 Subtarget features
> diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
> index 08dbf02..449df8f 100644
> --- a/lib/Target/X86/X86Subtarget.h
> +++ b/lib/Target/X86/X86Subtarget.h
> @@ -205,9 +205,12 @@ 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 32-bit or
> 16-bit
> bool In64BitMode;
>
> + /// 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 +247,10 @@ public:
> return In64BitMode;
> }
>
> + 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);
> --
> 1.8.3.1
>
>
> --
> David Woodhouse Open Source Technology Centre
> David.Woodhouse at intel.com Intel Corporation
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
--
~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140105/4be52e7c/attachment.html>
More information about the llvm-commits
mailing list