[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