[llvm] r212519 - Mips.abiflags is a new implicitly generated section that will be present on all new modules. The section contains a versioned data structure which represents essentially information to allow a program loader to determine the requireme

Daniel Sanders Daniel.Sanders at imgtec.com
Tue Jul 8 03:20:32 PDT 2014


Committed a follow-on to improve the encapsulation and reduce the scope of the enums in r212522.

> -----Original Message-----
> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
> bounces at cs.uiuc.edu] On Behalf Of Vladimir Medic
> Sent: 08 July 2014 09:59
> To: llvm-commits at cs.uiuc.edu
> Subject: [llvm] r212519 - Mips.abiflags is a new implicitly generated section
> that will be present on all new modules. The section contains a versioned
> data structure which represents essentially information to allow a program
> loader to determine the requiremen...
> 
> Author: vmedic
> Date: Tue Jul  8 03:59:22 2014
> New Revision: 212519
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=212519&view=rev
> Log:
> Mips.abiflags is a new implicitly generated section that  will be present on all
> new modules. The section contains a versioned data structure which
> represents essentially information to allow a program loader to determine
> the requirements of the application. This patch implements mips.abiflags
> section and provides test cases for it.
> 
> Added:
>     llvm/trunk/test/CodeGen/Mips/abiflags-xx.ll
>     llvm/trunk/test/CodeGen/Mips/abiflags32.ll
>     llvm/trunk/test/MC/Mips/mips-abi-bad.s
>     llvm/trunk/test/MC/Mips/mips32/abiflags.s
>     llvm/trunk/test/MC/Mips/mips32r2/abiflags.s
>     llvm/trunk/test/MC/Mips/mips64/abiflags.s
>     llvm/trunk/test/MC/Mips/mips64r2/abi-bad.s
>     llvm/trunk/test/MC/Mips/mips64r2/abiflags.s
>     llvm/trunk/test/MC/Mips/mips_abi_flags_xx.s
>     llvm/trunk/test/MC/Mips/mips_abi_flags_xx_set.s
> Modified:
>     llvm/trunk/include/llvm/Support/ELF.h
>     llvm/trunk/lib/MC/ELFObjectWriter.cpp
>     llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
>     llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
>     llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
>     llvm/trunk/lib/Target/Mips/MipsSubtarget.h
>     llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
>     llvm/trunk/test/MC/Mips/mips-data-directives.s
> 
> Modified: llvm/trunk/include/llvm/Support/ELF.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/include/llvm/Support/ELF.h?rev=212519&r1=212518&r2=
> 212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/include/llvm/Support/ELF.h (original)
> +++ llvm/trunk/include/llvm/Support/ELF.h Tue Jul  8 03:59:22 2014
> @@ -1299,6 +1299,7 @@ enum : unsigned {
> 
>    SHT_MIPS_REGINFO        = 0x70000006, // Register usage information
>    SHT_MIPS_OPTIONS        = 0x7000000d, // General options
> +  SHT_MIPS_ABIFLAGS       = 0x7000002a, // ABI information.
> 
>    SHT_HIPROC        = 0x7fffffff, // Highest processor arch-specific type.
>    SHT_LOUSER        = 0x80000000, // Lowest type reserved for applications.
> @@ -1616,7 +1617,8 @@ enum {
>    // MIPS program header types.
>    PT_MIPS_REGINFO  = 0x70000000,  // Register usage information.
>    PT_MIPS_RTPROC   = 0x70000001,  // Runtime procedure table.
> -  PT_MIPS_OPTIONS  = 0x70000002   // Options segment.
> +  PT_MIPS_OPTIONS  = 0x70000002,  // Options segment.
> +  PT_MIPS_ABIFLAGS = 0x70000003   // Abiflags segment.
>  };
> 
>  // Segment flag bits.
> 
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=212519&r1=212518&r2
> =212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Tue Jul  8 03:59:22 2014
> @@ -1565,6 +1565,7 @@ void ELFObjectWriter::WriteSection(MCAss
>    case ELF::SHT_X86_64_UNWIND:
>    case ELF::SHT_MIPS_REGINFO:
>    case ELF::SHT_MIPS_OPTIONS:
> +  case ELF::SHT_MIPS_ABIFLAGS:
>      // Nothing to do.
>      break;
> 
> 
> Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=21
> 2519&r1=212518&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Tue Jul  8
> 03:59:22 2014
> @@ -38,7 +38,7 @@ class MCInstrInfo;
>  namespace {
>  class MipsAssemblerOptions {
>  public:
> -  MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
> +  MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true),
> fpAbiMode(0) {}
> 
>    unsigned getATRegNum() { return aTReg; }
>    bool setATReg(unsigned Reg);
> @@ -46,15 +46,18 @@ public:
>    bool isReorder() { return reorder; }
>    void setReorder() { reorder = true; }
>    void setNoreorder() { reorder = false; }
> +  void setFpAbiMode(int Mode) { fpAbiMode = Mode; }
> 
>    bool isMacro() { return macro; }
>    void setMacro() { macro = true; }
>    void setNomacro() { macro = false; }
> +  int getFpAbiMode() { return fpAbiMode; }
> 
>  private:
>    unsigned aTReg;
>    bool reorder;
>    bool macro;
> +  int fpAbiMode;
>  };
>  }
> 
> @@ -156,39 +159,17 @@ class MipsAsmParser : public MCTargetAsm
>    bool parseSetReorderDirective();
>    bool parseSetNoReorderDirective();
>    bool parseSetNoMips16Directive();
> +  bool parseSetFpDirective();
> 
>    bool parseSetAssignment();
> 
>    bool parseDataDirective(unsigned Size, SMLoc L);
>    bool parseDirectiveGpWord();
>    bool parseDirectiveGpDWord();
> +  bool parseDirectiveModule();
> 
>    MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
> 
> -  bool isGP64() const {
> -    return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
> -  }
> -
> -  bool isFP64() const {
> -    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
> -  }
> -
> -  bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
> -  bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
> -
> -  bool isMicroMips() const {
> -    return STI.getFeatureBits() & Mips::FeatureMicroMips;
> -  }
> -
> -  bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4;
> }
> -  bool hasMips32() const { return STI.getFeatureBits() &
> Mips::FeatureMips32; }
> -  bool hasMips32r6() const {
> -    return STI.getFeatureBits() & Mips::FeatureMips32r6;
> -  }
> -  bool hasMips64r6() const {
> -    return STI.getFeatureBits() & Mips::FeatureMips64r6;
> -  }
> -
>    bool eatComma(StringRef ErrorStr);
> 
>    int matchCPURegisterName(StringRef Symbol);
> @@ -243,12 +224,13 @@ public:
>    };
> 
>    MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
> -                const MCInstrInfo &MII,
> -                const MCTargetOptions &Options)
> +                const MCInstrInfo &MII, const MCTargetOptions &Options)
>        : MCTargetAsmParser(), STI(sti), Parser(parser) {
>      // Initialize the set of available features.
>      setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
> 
> +    getTargetStreamer().updateABIInfo(*this);
> +
>      // Assert exactly one ABI was chosen.
>      assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
>              ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
> @@ -262,6 +244,49 @@ public:
>    /// True if all of $fcc0 - $fcc7 exist for the current ISA.
>    bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
> 
> +  bool isGP64bit() const { return STI.getFeatureBits() &
> Mips::FeatureGP64Bit; }
> +  bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit;
> }
> +  bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
> +  bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
> +  bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
> +  bool isABI_FPXX() const { return false; } // TODO: add check for FeatureXX
> +
> +  bool inMicroMipsMode() const {
> +    return STI.getFeatureBits() & Mips::FeatureMicroMips;
> +  }
> +  bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1;
> }
> +  bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2;
> }
> +  bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3;
> }
> +  bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4;
> }
> +  bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5;
> }
> +  bool hasMips32() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips32);
> +  }
> +  bool hasMips64() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips64);
> +  }
> +  bool hasMips32r2() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips32r2);
> +  }
> +  bool hasMips64r2() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips64r2);
> +  }
> +  bool hasMips32r6() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips32r6);
> +  }
> +  bool hasMips64r6() const {
> +    return (STI.getFeatureBits() & Mips::FeatureMips64r6);
> +  }
> +  bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
> +  bool hasDSPR2() const { return (STI.getFeatureBits() &
> Mips::FeatureDSPR2); }
> +  bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
> +
> +  bool inMips16Mode() const {
> +    return STI.getFeatureBits() & Mips::FeatureMips16;
> +  }
> +  // TODO: see how can we get this info.
> +  bool mipsSEUsesSoftFloat() const { return false; }
> +
>    /// Warn if RegNo is the current assembler temporary.
>    void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
>  };
> @@ -276,9 +301,9 @@ public:
>    /// Broad categories of register classes
>    /// The exact class is finalized by the render method.
>    enum RegKind {
> -    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64())
> +    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
>      RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context
> and
> -                          /// isFP64())
> +                          /// isFP64bit())
>      RegKind_FCC = 4,      /// FCC
>      RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
>      RegKind_MSACtrl = 16, /// MSA control registers
> @@ -882,9 +907,10 @@ bool MipsAsmParser::processInstruction(M
>        Offset = Inst.getOperand(2);
>        if (!Offset.isImm())
>          break; // We'll deal with this situation later on when applying fixups.
> -      if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
> +      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
>          return Error(IDLoc, "branch target out of range");
> -      if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
> +      if (OffsetToAlignment(Offset.getImm(),
> +                            1LL << (inMicroMipsMode() ? 1 : 2)))
>          return Error(IDLoc, "branch to misaligned address");
>        break;
>      case Mips::BGEZ:
> @@ -907,9 +933,10 @@ bool MipsAsmParser::processInstruction(M
>        Offset = Inst.getOperand(1);
>        if (!Offset.isImm())
>          break; // We'll deal with this situation later on when applying fixups.
> -      if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
> +      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
>          return Error(IDLoc, "branch target out of range");
> -      if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
> +      if (OffsetToAlignment(Offset.getImm(),
> +                            1LL << (inMicroMipsMode() ? 1 : 2)))
>          return Error(IDLoc, "branch to misaligned address");
>        break;
>      }
> @@ -994,12 +1021,13 @@ bool MipsAsmParser::needsExpansion(MCIns
>  bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
>                                        SmallVectorImpl<MCInst> &Instructions) {
>    switch (Inst.getOpcode()) {
> -  default: assert(0 && "unimplemented expansion");
> +  default:
> +    assert(0 && "unimplemented expansion");
>      return true;
>    case Mips::LoadImm32Reg:
>      return expandLoadImm(Inst, IDLoc, Instructions);
>    case Mips::LoadImm64Reg:
> -    if (!isGP64()) {
> +    if (!isGP64bit()) {
>        Error(IDLoc, "instruction requires a CPU feature not currently enabled");
>        return true;
>      }
> @@ -1074,8 +1102,8 @@ bool MipsAsmParser::expandLoadImm(MCInst
>      Instructions.push_back(tmpInst);
>      createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
>    } else if ((ImmValue & (0xffffLL << 48)) == 0) {
> -    if (!isGP64()) {
> -      Error (IDLoc, "instruction requires a CPU feature not currently enabled");
> +    if (!isGP64bit()) {
> +      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
>        return true;
>      }
> 
> @@ -1101,8 +1129,8 @@ bool MipsAsmParser::expandLoadImm(MCInst
>      createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
>      createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
>    } else {
> -    if (!isGP64()) {
> -      Error (IDLoc, "instruction requires a CPU feature not currently enabled");
> +    if (!isGP64bit()) {
> +      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
>        return true;
>      }
> 
> @@ -1274,8 +1302,8 @@ void MipsAsmParser::expandMemInst(MCInst
>      // not available.
>      if (!AT)
>        return;
> -    TmpRegNum =
> -        getReg((isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
> AT);
> +    TmpRegNum = getReg(
> +        (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
>    }
> 
>    TempInst.setOpcode(Mips::LUi);
> @@ -1433,7 +1461,7 @@ int MipsAsmParser::matchCPURegisterName(
>             .Case("t9", 25)
>             .Default(-1);
> 
> -  if (isN32() || isN64()) {
> +  if (isABI_N32() || isABI_N64()) {
>      // Although SGI documentation just cuts out t0-t3 for n32/n64,
>      // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
>      // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
> @@ -1546,7 +1574,7 @@ unsigned MipsAsmParser::getReg(int RC, i
>  }
> 
>  unsigned MipsAsmParser::getGPR(int RegNo) {
> -  return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
> +  return getReg(isGP64bit() ? Mips::GPR64RegClassID :
> Mips::GPR32RegClassID,
>                  RegNo);
>  }
> 
> @@ -1771,7 +1799,7 @@ bool MipsAsmParser::ParseRegister(unsign
>      // register is a parse error.
>      if (Operand.isGPRAsmReg()) {
>        // Resolve to GPR32 or GPR64 appropriately.
> -      RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
> +      RegNo = isGP64bit() ? Operand.getGPR64Reg() :
> Operand.getGPR32Reg();
>      }
> 
>      return (RegNo == (unsigned)-1);
> @@ -2227,6 +2255,9 @@ bool MipsAsmParser::ParseBracketSuffix(S
>  bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef
> Name,
>                                       SMLoc NameLoc, OperandVector &Operands) {
>    DEBUG(dbgs() << "ParseInstruction\n");
> +  // We have reached first instruction, module directive after
> +  // this is forbidden.
> +  getTargetStreamer().setCanHaveModuleDir(false);
>    // Check if we have valid mnemonic
>    if (!mnemonicIsValid(Name, 0)) {
>      Parser.eatToEndOfStatement();
> @@ -2413,6 +2444,60 @@ bool MipsAsmParser::parseSetNoMips16Dire
>    return false;
>  }
> 
> +bool MipsAsmParser::parseSetFpDirective() {
> +  int FpAbiMode;
> +  // Line can be: .set fp=32
> +  //              .set fp=xx
> +  //              .set fp=64
> +  Parser.Lex(); // Eat fp token
> +  AsmToken Tok = Parser.getTok();
> +  if (Tok.isNot(AsmToken::Equal)) {
> +    reportParseError("unexpected token in statement");
> +    return false;
> +  }
> +  Parser.Lex(); // Eat '=' token.
> +  Tok = Parser.getTok();
> +  if (Tok.is(AsmToken::Identifier)) {
> +    StringRef XX = Tok.getString();
> +    if (XX != "xx") {
> +      reportParseError("unsupported option");
> +      return false;
> +    }
> +    if (!isABI_O32()) {
> +      reportParseError("'set fp=xx'option requires O32 ABI");
> +      return false;
> +    }
> +    FpAbiMode = Val_GNU_MIPS_ABI_FP_XX;
> +  } else if (Tok.is(AsmToken::Integer)) {
> +    unsigned Value = Tok.getIntVal();
> +    if (Value != 32 && Value != 64) {
> +      reportParseError("unsupported option");
> +      return false;
> +    }
> +    if (Value == 32) {
> +      if (!isABI_O32()) {
> +        reportParseError("'set fp=32'option requires O32 ABI");
> +        return false;
> +      }
> +      FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +    } else {
> +      if (isABI_N32() || isABI_N64())
> +        FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +      else if (isABI_O32())
> +        FpAbiMode = Val_GNU_MIPS_ABI_FP_64;
> +    }
> +  }
> +  Parser.Lex(); // Eat option token.
> +  if (getLexer().isNot(AsmToken::EndOfStatement)) {
> +    reportParseError("unexpected token in statement");
> +    return false;
> +  }
> +  Options.setFpAbiMode(FpAbiMode);
> +  getTargetStreamer().emitDirectiveSetFp(FpAbiMode, isABI_O32());
> +  Parser.Lex(); // Consume the EndOfStatement.
> +  return false;
> +}
> +
>  bool MipsAsmParser::parseSetAssignment() {
>    StringRef Name;
>    const MCExpr *Value;
> @@ -2594,6 +2679,8 @@ bool MipsAsmParser::parseDirectiveSet()
>      return parseSetNoAtDirective();
>    } else if (Tok.getString() == "at") {
>      return parseSetAtDirective();
> +  } else if (Tok.getString() == "fp") {
> +    return parseSetFpDirective();
>    } else if (Tok.getString() == "reorder") {
>      return parseSetReorderDirective();
>    } else if (Tok.getString() == "noreorder") {
> @@ -2726,6 +2813,61 @@ bool MipsAsmParser::parseDirectiveOption
>    return false;
>  }
> 
> +bool MipsAsmParser::parseDirectiveModule() {
> +  // Line can be: .module fp=32
> +  //              .module fp=xx
> +  //              .module fp=64
> +  unsigned FpAbiVal = 0;
> +  if (!getTargetStreamer().getCanHaveModuleDir()) {
> +    // TODO : get a better message.
> +    reportParseError(".module directive must appear before any code");
> +    return false;
> +  }
> +  AsmToken Tok = Parser.getTok();
> +  if (Tok.isNot(AsmToken::Identifier) && Tok.getString() != "fp") {
> +    reportParseError("unexpected token in .module directive, 'fp'
> expected");
> +    return false;
> +  }
> +  Parser.Lex(); // Eat fp token
> +  Tok = Parser.getTok();
> +  if (Tok.isNot(AsmToken::Equal)) {
> +    reportParseError("unexpected token in statement");
> +    return false;
> +  }
> +  Parser.Lex(); // Eat '=' token.
> +  Tok = Parser.getTok();
> +  if (Tok.is(AsmToken::Identifier)) {
> +    StringRef XX = Tok.getString();
> +    if (XX != "xx") {
> +      reportParseError("unsupported option");
> +      return false;
> +    }
> +    FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
> +  } else if (Tok.is(AsmToken::Integer)) {
> +    unsigned Value = Tok.getIntVal();
> +    if (Value != 32 && Value != 64) {
> +      reportParseError("unsupported value, expected 32 or 64");
> +      return false;
> +    }
> +    if (Value == 64) {
> +      if (isABI_N32() || isABI_N64())
> +        FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +      else if (isABI_O32())
> +        FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
> +    } else if (isABI_O32())
> +      FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +  }
> +  Parser.Lex(); // Eat option token.
> +  if (getLexer().isNot(AsmToken::EndOfStatement)) {
> +    reportParseError("unexpected token in statement");
> +    return false;
> +  }
> +  // Emit appropriate flags.
> +  getTargetStreamer().emitDirectiveModule(FpAbiVal, isABI_O32());
> +  getTargetStreamer().setFpABI(FpAbiVal);
> +  Parser.Lex(); // Consume the EndOfStatement.
> +  return false;
> +}
>  bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
>    StringRef IDVal = DirectiveID.getString();
> 
> @@ -2804,6 +2946,9 @@ bool MipsAsmParser::ParseDirective(AsmTo
>    if (IDVal == ".cpsetup")
>      return parseDirectiveCPSetup();
> 
> +  if (IDVal == ".module")
> +    return parseDirectiveModule();
> +
>    return true;
>  }
> 
> 
> Modified:
> llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
> ?rev=212519&r1=212518&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
> (original)
> +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
> Tue Jul  8 03:59:22 2014
> @@ -27,7 +27,8 @@
> 
>  using namespace llvm;
> 
> -MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S) :
> MCTargetStreamer(S) {}
> +MipsTargetStreamer::MipsTargetStreamer(MCStreamer &S)
> +    : MCTargetStreamer(S), canHaveModuleDirective(true) {}
>  void MipsTargetStreamer::emitDirectiveSetMicroMips() {}
>  void MipsTargetStreamer::emitDirectiveSetNoMicroMips() {}
>  void MipsTargetStreamer::emitDirectiveSetMips16() {}
> @@ -65,42 +66,52 @@ MipsTargetAsmStreamer::MipsTargetAsmStre
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMicroMips() {
>    OS << "\t.set\tmicromips\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetNoMicroMips() {
>    OS << "\t.set\tnomicromips\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMips16() {
>    OS << "\t.set\tmips16\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetNoMips16() {
>    OS << "\t.set\tnomips16\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetReorder() {
>    OS << "\t.set\treorder\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetNoReorder() {
>    OS << "\t.set\tnoreorder\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMacro() {
>    OS << "\t.set\tmacro\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetNoMacro() {
>    OS << "\t.set\tnomacro\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetAt() {
>    OS << "\t.set\tat\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetNoAt() {
>    OS << "\t.set\tnoat\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveEnd(StringRef Name) {
> @@ -137,24 +148,28 @@ void MipsTargetAsmStreamer::emitFrame(un
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMips32R2() {
>    OS << "\t.set\tmips32r2\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMips64() {
>    OS << "\t.set\tmips64\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetMips64R2() {
>    OS << "\t.set\tmips64r2\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveSetDsp() {
>    OS << "\t.set\tdsp\n";
> +  setCanHaveModuleDir(false);
>  }
>  // Print a 32 bit hex number with all numbers.
>  static void printHex32(unsigned Value, raw_ostream &OS) {
>    OS << "0x";
>    for (int i = 7; i >= 0; i--)
> -    OS.write_hex((Value & (0xF << (i*4))) >> (i*4));
> +    OS.write_hex((Value & (0xF << (i * 4))) >> (i * 4));
>  }
> 
>  void MipsTargetAsmStreamer::emitMask(unsigned CPUBitmask,
> @@ -174,6 +189,7 @@ void MipsTargetAsmStreamer::emitFMask(un
>  void MipsTargetAsmStreamer::emitDirectiveCpload(unsigned RegNo) {
>    OS << "\t.cpload\t$"
>       << StringRef(MipsInstPrinter::getRegisterName(RegNo)).lower() << "\n";
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
> @@ -192,6 +208,57 @@ void MipsTargetAsmStreamer::emitDirectiv
>    OS << ", ";
> 
>    OS << Sym.getName() << "\n";
> +  setCanHaveModuleDir(false);
> +}
> +
> +void MipsTargetAsmStreamer::emitDirectiveModule(unsigned Value,
> +                                                bool is32BitAbi) {
> +  StringRef ModuleValue;
> +  OS << "\t.module\tfp=";
> +  switch (Value) {
> +  case Val_GNU_MIPS_ABI_FP_XX:
> +    ModuleValue = "xx";
> +    break;
> +  case Val_GNU_MIPS_ABI_FP_64:
> +    ModuleValue = "64";
> +    break;
> +  case Val_GNU_MIPS_ABI_FP_DOUBLE:
> +    if (is32BitAbi)
> +      ModuleValue = "32";
> +    else
> +      ModuleValue = "64";
> +    break;
> +  default:
> +    llvm_unreachable("unsupported .module value");
> +  }
> +  OS << ModuleValue << "\n";
> +}
> +
> +void MipsTargetAsmStreamer::emitDirectiveSetFp(unsigned Value,
> +                                               bool is32BitAbi) {
> +  StringRef ModuleValue;
> +  OS << "\t.set\tfp=";
> +  switch (Value) {
> +  case Val_GNU_MIPS_ABI_FP_XX:
> +    ModuleValue = "xx";
> +    break;
> +  case Val_GNU_MIPS_ABI_FP_64:
> +    ModuleValue = "64";
> +    break;
> +  case Val_GNU_MIPS_ABI_FP_DOUBLE:
> +    if (is32BitAbi)
> +      ModuleValue = "32";
> +    else
> +      ModuleValue = "64";
> +    break;
> +  default:
> +    llvm_unreachable("unsupported .set fp value");
> +  }
> +  OS << ModuleValue << "\n";
> +}
> +
> +void MipsTargetAsmStreamer::emitMipsAbiFlags() {
> +  // No action required for text output.
>  }
> 
>  // This part is for ELF object output.
> @@ -201,7 +268,7 @@ MipsTargetELFStreamer::MipsTargetELFStre
>    MCAssembler &MCA = getStreamer().getAssembler();
>    uint64_t Features = STI.getFeatureBits();
>    Triple T(STI.getTargetTriple());
> -  Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() ==  Reloc::PIC_)
> +  Pic = (MCA.getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_)
>              ? true
>              : false;
> 
> @@ -283,17 +350,17 @@ void MipsTargetELFStreamer::finish() {
>          ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP,
> SectionKind::getMetadata());
>      OS.SwitchSection(Sec);
> 
> -    OS.EmitIntValue(1, 1); // kind
> +    OS.EmitIntValue(1, 1);  // kind
>      OS.EmitIntValue(40, 1); // size
> -    OS.EmitIntValue(0, 2); // section
> -    OS.EmitIntValue(0, 4); // info
> -    OS.EmitIntValue(0, 4); // ri_gprmask
> -    OS.EmitIntValue(0, 4); // pad
> -    OS.EmitIntValue(0, 4); // ri_cpr[0]mask
> -    OS.EmitIntValue(0, 4); // ri_cpr[1]mask
> -    OS.EmitIntValue(0, 4); // ri_cpr[2]mask
> -    OS.EmitIntValue(0, 4); // ri_cpr[3]mask
> -    OS.EmitIntValue(0, 8); // ri_gp_value
> +    OS.EmitIntValue(0, 2);  // section
> +    OS.EmitIntValue(0, 4);  // info
> +    OS.EmitIntValue(0, 4);  // ri_gprmask
> +    OS.EmitIntValue(0, 4);  // pad
> +    OS.EmitIntValue(0, 4);  // ri_cpr[0]mask
> +    OS.EmitIntValue(0, 4);  // ri_cpr[1]mask
> +    OS.EmitIntValue(0, 4);  // ri_cpr[2]mask
> +    OS.EmitIntValue(0, 4);  // ri_cpr[3]mask
> +    OS.EmitIntValue(0, 8);  // ri_gp_value
>    } else {
>      const MCSectionELF *Sec =
>          Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO,
> ELF::SHF_ALLOC,
> @@ -307,6 +374,7 @@ void MipsTargetELFStreamer::finish() {
>      OS.EmitIntValue(0, 4); // ri_cpr[3]mask
>      OS.EmitIntValue(0, 4); // ri_gp_value
>    }
> +  emitMipsAbiFlags();
>  }
> 
>  void MipsTargetELFStreamer::emitAssignment(MCSymbol *Symbol,
> @@ -315,11 +383,11 @@ void MipsTargetELFStreamer::emitAssignme
>    if (Value->getKind() != MCExpr::SymbolRef)
>      return;
>    const MCSymbol &RhsSym =
> -    static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
> +      static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
>    MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
>    uint8_t Type = MCELF::GetType(Data);
> -  if ((Type != ELF::STT_FUNC)
> -      || !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2)))
> +  if ((Type != ELF::STT_FUNC) ||
> +      !(MCELF::getOther(Data) & (ELF::STO_MIPS_MICROMIPS >> 2)))
>      return;
> 
>    MCSymbolData &SymbolData =
> getStreamer().getOrCreateSymbolData(Symbol);
> @@ -344,6 +412,7 @@ void MipsTargetELFStreamer::emitDirectiv
> 
>  void MipsTargetELFStreamer::emitDirectiveSetNoMicroMips() {
>    MicroMipsEnabled = false;
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetMips16() {
> @@ -351,14 +420,17 @@ void MipsTargetELFStreamer::emitDirectiv
>    unsigned Flags = MCA.getELFHeaderEFlags();
>    Flags |= ELF::EF_MIPS_ARCH_ASE_M16;
>    MCA.setELFHeaderEFlags(Flags);
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetNoMips16() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetReorder() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetNoReorder() {
> @@ -366,22 +438,27 @@ void MipsTargetELFStreamer::emitDirectiv
>    unsigned Flags = MCA.getELFHeaderEFlags();
>    Flags |= ELF::EF_MIPS_NOREORDER;
>    MCA.setELFHeaderEFlags(Flags);
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetMacro() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetNoMacro() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetAt() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetNoAt() {
>    // FIXME: implement.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
> @@ -450,19 +527,19 @@ void MipsTargetELFStreamer::emitFMask(un
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetMips32R2() {
> -  // No action required for ELF output.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetMips64() {
> -  // No action required for ELF output.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetMips64R2() {
> -  // No action required for ELF output.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveSetDsp() {
> -  // No action required for ELF output.
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveCpload(unsigned RegNo) {
> @@ -512,6 +589,8 @@ void MipsTargetELFStreamer::emitDirectiv
>    TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
>    TmpInst.addOperand(MCOperand::CreateReg(RegNo));
>    getStreamer().EmitInstruction(TmpInst, STI);
> +
> +  setCanHaveModuleDir(false);
>  }
> 
>  void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
> @@ -567,4 +646,30 @@ void MipsTargetELFStreamer::emitDirectiv
>    Inst.addOperand(MCOperand::CreateReg(Mips::GP));
>    Inst.addOperand(MCOperand::CreateReg(RegNo));
>    getStreamer().EmitInstruction(Inst, STI);
> +
> +  setCanHaveModuleDir(false);
> +}
> +
> +void MipsTargetELFStreamer::emitMipsAbiFlags() {
> +  MCAssembler &MCA = getStreamer().getAssembler();
> +  MCContext &Context = MCA.getContext();
> +  MCStreamer &OS = getStreamer();
> +  const MCSectionELF *Sec =
> +      Context.getELFSection(".MIPS.abiflags", ELF::SHT_MIPS_ABIFLAGS,
> +                            ELF::SHF_ALLOC, SectionKind::getMetadata());
> +  MCSectionData &ABIShndxSD = MCA.getOrCreateSectionData(*Sec);
> +  ABIShndxSD.setAlignment(8);
> +  OS.SwitchSection(Sec);
> +
> +  OS.EmitIntValue(MipsABIFlags.version, 2);   // version
> +  OS.EmitIntValue(MipsABIFlags.isa_level, 1); // isa_level
> +  OS.EmitIntValue(MipsABIFlags.isa_rev, 1);   // isa_rev
> +  OS.EmitIntValue(MipsABIFlags.gpr_size, 1);  // gpr_size
> +  OS.EmitIntValue(MipsABIFlags.cpr1_size, 1); // cpr1_size
> +  OS.EmitIntValue(MipsABIFlags.cpr2_size, 1); // cpr2_size
> +  OS.EmitIntValue(MipsABIFlags.fp_abi, 1);    // fp_abi
> +  OS.EmitIntValue(MipsABIFlags.isa_ext, 4);   // isa_ext
> +  OS.EmitIntValue(MipsABIFlags.ases, 4);      // ases
> +  OS.EmitIntValue(MipsABIFlags.flags1, 4);    // flags1
> +  OS.EmitIntValue(MipsABIFlags.flags2, 4);    // flags2
>  }
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=212519&r1=21
> 2518&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Tue Jul  8 03:59:22 2014
> @@ -92,6 +92,8 @@ bool MipsAsmPrinter::lowerOperand(const
>  #include "MipsGenMCPseudoLowering.inc"
> 
>  void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
> +  MipsTargetStreamer &TS = getTargetStreamer();
> +  TS.setCanHaveModuleDir(false);
>    if (MI->isDebugValue()) {
>      SmallString<128> Str;
>      raw_svector_ostream OS(Str);
> @@ -657,6 +659,19 @@ void MipsAsmPrinter::EmitStartOfAsmFile(
>            OutContext.getELFSection(".gcc_compiled_long64",
> ELF::SHT_PROGBITS, 0,
>                                     SectionKind::getDataRel()));
>    }
> +  getTargetStreamer().updateABIInfo(*Subtarget);
> +  unsigned FpAbiVal;
> +  if (Subtarget->isABI_N32() || Subtarget->isABI_N64())
> +    FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +  else if(Subtarget->isABI_O32()) {
> +    if (Subtarget->isFP64bit())
> +      FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
> +    else if(Subtarget->isABI_FPXX())
> +      FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
> +    else
> +      FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
> +  }
> +  getTargetStreamer().emitDirectiveModule(FpAbiVal, Subtarget-
> >isABI_O32());
>  }
> 
>  void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) {
> @@ -852,7 +867,7 @@ void MipsAsmPrinter::EmitFPCallStub(
>    TS.emitDirectiveSetNoMicroMips();
>    //
>    // .ent __call_stub_fp_xxxx
> -  // .type	__call_stub_fp_xxxx, at function
> +  // .type  __call_stub_fp_xxxx, at function
>    //  __call_stub_fp_xxxx:
>    //
>    std::string x = "__call_stub_fp_" + std::string(Symbol);
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/Mips/MipsSubtarget.h?rev=212519&r1=21251
> 8&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/Target/Mips/MipsSubtarget.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsSubtarget.h Tue Jul  8 03:59:22 2014
> @@ -162,6 +162,7 @@ public:
>    bool isABI_N64() const { return MipsABI == N64; }
>    bool isABI_N32() const { return MipsABI == N32; }
>    bool isABI_O32() const { return MipsABI == O32; }
> +  bool isABI_FPXX() const { return false; } // TODO: add check for FPXX
>    unsigned getTargetABI() const { return MipsABI; }
> 
>    /// This constructor initializes the data members to match that
> @@ -174,8 +175,11 @@ public:
>    /// subtarget options.  Definition of function is auto generated by tblgen.
>    void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
> 
> +  bool hasMips1() const { return MipsArchVersion >= Mips1; }
>    bool hasMips2() const { return MipsArchVersion >= Mips2; }
>    bool hasMips3() const { return MipsArchVersion >= Mips3; }
> +  bool hasMips4() const { return MipsArchVersion >= Mips4; }
> +  bool hasMips5() const { return MipsArchVersion >= Mips5; }
>    bool hasMips4_32() const { return HasMips4_32; }
>    bool hasMips4_32r2() const { return HasMips4_32r2; }
>    bool hasMips32() const {
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h?rev=212519&r1=
> 212518&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h Tue Jul  8 03:59:22
> 2014
> @@ -14,6 +14,88 @@
>  #include "llvm/MC/MCStreamer.h"
> 
>  namespace llvm {
> +struct Elf_Internal_ABIFlags_v0 {
> +  // Version of flags structure.
> +  uint16_t version;
> +  // The level of the ISA: 1-5, 32, 64.
> +  uint8_t isa_level;
> +  // The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
> +  uint8_t isa_rev;
> +  // The size of general purpose registers.
> +  uint8_t gpr_size;
> +  // The size of co-processor 1 registers.
> +  uint8_t cpr1_size;
> +  // The size of co-processor 2 registers.
> +  uint8_t cpr2_size;
> +  // The floating-point ABI.
> +  uint8_t fp_abi;
> +  // Processor-specific extension.
> +  uint32_t isa_ext;
> +  // Mask of ASEs used.
> +  uint32_t ases;
> +  // Mask of general flags.
> +  uint32_t flags1;
> +  uint32_t flags2;
> +
> +  Elf_Internal_ABIFlags_v0()
> +      : version(0), isa_level(0), isa_rev(0), gpr_size(0), cpr1_size(0),
> +        cpr2_size(0), fp_abi(0), isa_ext(0), ases(0), flags1(0), flags2(0) {}
> +};
> +
> +// Values for the xxx_size bytes of an ABI flags structure.
> +enum {
> +  AFL_REG_NONE = 0x00, // No registers.
> +  AFL_REG_32 = 0x01,   // 32-bit registers.
> +  AFL_REG_64 = 0x02,   // 64-bit registers.
> +  AFL_REG_128 = 0x03   // 128-bit registers.
> +};
> +
> +// Masks for the ases word of an ABI flags structure.
> +enum {
> +  AFL_ASE_DSP = 0x00000001,       // DSP ASE.
> +  AFL_ASE_DSPR2 = 0x00000002,     // DSP R2 ASE.
> +  AFL_ASE_EVA = 0x00000004,       // Enhanced VA Scheme.
> +  AFL_ASE_MCU = 0x00000008,       // MCU (MicroController) ASE.
> +  AFL_ASE_MDMX = 0x00000010,      // MDMX ASE.
> +  AFL_ASE_MIPS3D = 0x00000020,    // MIPS-3D ASE.
> +  AFL_ASE_MT = 0x00000040,        // MT ASE.
> +  AFL_ASE_SMARTMIPS = 0x00000080, // SmartMIPS ASE.
> +  AFL_ASE_VIRT = 0x00000100,      // VZ ASE.
> +  AFL_ASE_MSA = 0x00000200,       // MSA ASE.
> +  AFL_ASE_MIPS16 = 0x00000400,    // MIPS16 ASE.
> +  AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS ASE.
> +  AFL_ASE_XPA = 0x00001000        // XPA ASE.
> +};
> +
> +// Values for the isa_ext word of an ABI flags structure.
> +enum {
> +  AFL_EXT_XLR = 1,          // RMI Xlr instruction.
> +  AFL_EXT_OCTEON2 = 2,      // Cavium Networks Octeon2.
> +  AFL_EXT_OCTEONP = 3,      // Cavium Networks OcteonP.
> +  AFL_EXT_LOONGSON_3A = 4,  // Loongson 3A.
> +  AFL_EXT_OCTEON = 5,       // Cavium Networks Octeon.
> +  AFL_EXT_5900 = 6,         // MIPS R5900 instruction.
> +  AFL_EXT_4650 = 7,         // MIPS R4650 instruction.
> +  AFL_EXT_4010 = 8,         // LSI R4010 instruction.
> +  AFL_EXT_4100 = 9,         // NEC VR4100 instruction.
> +  AFL_EXT_3900 = 10,        // Toshiba R3900 instruction.
> +  AFL_EXT_10000 = 11,       // MIPS R10000 instruction.
> +  AFL_EXT_SB1 = 12,         // Broadcom SB-1 instruction.
> +  AFL_EXT_4111 = 13,        // NEC VR4111/VR4181 instruction.
> +  AFL_EXT_4120 = 14,        // NEC VR4120 instruction.
> +  AFL_EXT_5400 = 15,        // NEC VR5400 instruction.
> +  AFL_EXT_5500 = 16,        // NEC VR5500 instruction.
> +  AFL_EXT_LOONGSON_2E = 17, // ST Microelectronics Loongson 2E.
> +  AFL_EXT_LOONGSON_2F = 18  // ST Microelectronics Loongson 2F.
> +};
> +
> +// Values for the fp_abi word of an ABI flags structure.
> +enum {
> +  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
> +  Val_GNU_MIPS_ABI_FP_XX = 5,
> +  Val_GNU_MIPS_ABI_FP_64 = 6
> +};
> +
>  class MipsTargetStreamer : public MCTargetStreamer {
>  public:
>    MipsTargetStreamer(MCStreamer &S);
> @@ -50,6 +132,109 @@ public:
>    virtual void emitDirectiveCpload(unsigned RegNo);
>    virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
>                                      const MCSymbol &Sym, bool IsReg);
> +  // ABI Flags
> +  virtual void emitDirectiveModule(unsigned Value, bool is32BitAbi){};
> +  virtual void emitDirectiveSetFp(unsigned Value, bool is32BitAbi){};
> +  virtual void emitMipsAbiFlags(){};
> +  void setCanHaveModuleDir(bool Can) { canHaveModuleDirective = Can; }
> +  bool getCanHaveModuleDir() { return canHaveModuleDirective; }
> +
> +  void setVersion(uint16_t Version) { MipsABIFlags.version = Version; }
> +  void setISALevel(uint8_t Level) { MipsABIFlags.isa_level = Level; }
> +  void setISARev(uint8_t Rev) { MipsABIFlags.isa_rev = Rev; }
> +  void setGprSize(uint8_t Size) { MipsABIFlags.gpr_size = Size; }
> +  void setCpr1Size(uint8_t Size) { MipsABIFlags.cpr1_size = Size; }
> +  void setCpr2Size(uint8_t Size) { MipsABIFlags.cpr2_size = Size; }
> +  void setFpABI(uint8_t Abi) { MipsABIFlags.fp_abi = Abi; }
> +  void setIsaExt(uint32_t IsaExt) { MipsABIFlags.isa_ext = IsaExt; }
> +  void setASEs(uint32_t Ases) { MipsABIFlags.ases = Ases; }
> +  void setFlags1(uint32_t Flags) { MipsABIFlags.flags1 = Flags; }
> +  void setFlags2(uint32_t Flags) { MipsABIFlags.flags2 = Flags; }
> +
> +  uint8_t getFPAbi() { return MipsABIFlags.fp_abi; }
> +  // This method enables template classes to set internal abi flags
> +  // structure values.
> +  template <class PredicateLibrary>
> +  void updateABIInfo(const PredicateLibrary &P) {
> +    setVersion(0); // Version, default value is 0.
> +
> +    if (P.hasMips64()) { // isa_level
> +      setISALevel(64);
> +      if (P.hasMips64r6())
> +        setISARev(6);
> +      else if (P.hasMips64r2())
> +        setISARev(2);
> +      else
> +        setISARev(1);
> +    } else if (P.hasMips32()) {
> +      setISALevel(32);
> +      if (P.hasMips32r6())
> +        setISARev(6);
> +      else if (P.hasMips32r2())
> +        setISARev(2);
> +      else
> +        setISARev(1);
> +    } else {
> +      setISARev(0);
> +      if (P.hasMips5())
> +        setISALevel(5);
> +      else if (P.hasMips4())
> +        setISALevel(4);
> +      else if (P.hasMips3())
> +        setISALevel(3);
> +      else if (P.hasMips2())
> +        setISALevel(2);
> +      else if (P.hasMips1())
> +        setISALevel(1);
> +      else
> +        llvm_unreachable("Unknown ISA level!");
> +    }
> +
> +    if (P.isGP64bit()) // GPR size.
> +      setGprSize(AFL_REG_64);
> +    else
> +      setGprSize(AFL_REG_32);
> +
> +    // TODO: check for MSA128 value.
> +    if (P.mipsSEUsesSoftFloat())
> +      setCpr1Size(AFL_REG_NONE);
> +    else if (P.isFP64bit())
> +      setCpr1Size(AFL_REG_64);
> +    else
> +      setCpr1Size(AFL_REG_32);
> +    setCpr2Size(AFL_REG_NONE); // Default value.
> +
> +    // Set ASE.
> +    unsigned AseFlags = 0;
> +    if (P.hasDSP())
> +      AseFlags |= AFL_ASE_DSP;
> +    if (P.hasDSPR2())
> +      AseFlags |= AFL_ASE_DSPR2;
> +    if (P.hasMSA())
> +      AseFlags |= AFL_ASE_MSA;
> +    if (P.inMicroMipsMode())
> +      AseFlags |= AFL_ASE_MICROMIPS;
> +    if (P.inMips16Mode())
> +      AseFlags |= AFL_ASE_MIPS16;
> +
> +    if (P.isABI_N32() || P.isABI_N64())
> +      setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
> +    else if (P.isABI_O32()) {
> +      if (P.isFP64bit())
> +        setFpABI(Val_GNU_MIPS_ABI_FP_64);
> +      else if (P.isABI_FPXX())
> +        setFpABI(Val_GNU_MIPS_ABI_FP_XX);
> +      else
> +        setFpABI(Val_GNU_MIPS_ABI_FP_DOUBLE);
> +    } else
> +      setFpABI(0); // Default value.
> +  }
> +
> +protected:
> +  Elf_Internal_ABIFlags_v0 MipsABIFlags;
> +
> +private:
> +  bool canHaveModuleDirective;
>  };
> 
>  // This part is for ascii assembly output
> @@ -91,6 +276,11 @@ public:
>    virtual void emitDirectiveCpload(unsigned RegNo);
>    void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
>                              const MCSymbol &Sym, bool IsReg) override;
> +
> +  // ABI Flags
> +  void emitDirectiveModule(unsigned Value, bool is32BitAbi) override;
> +  void emitDirectiveSetFp(unsigned Value, bool is32BitAbi) override;
> +  void emitMipsAbiFlags() override;
>  };
> 
>  // This part is for ELF object output
> @@ -142,6 +332,9 @@ public:
>    void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
>                              const MCSymbol &Sym, bool IsReg) override;
> 
> +  // ABI Flags
> +  void emitMipsAbiFlags() override;
> +
>  protected:
>    bool isO32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
>    bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
> 
> Added: llvm/trunk/test/CodeGen/Mips/abiflags-xx.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/CodeGen/Mips/abiflags-
> xx.ll?rev=212519&view=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/CodeGen/Mips/abiflags-xx.ll (added)
> +++ llvm/trunk/test/CodeGen/Mips/abiflags-xx.ll Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,6 @@
> +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -
> mattr=fpxx %s -o - | FileCheck %s
> +; XFAIL: *
> +
> +; CHECK: .nan    legacy
> +; CHECK: .module fp=xx
> +
> 
> Added: llvm/trunk/test/CodeGen/Mips/abiflags32.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/CodeGen/Mips/abiflags32.ll?rev=212519&view=aut
> o
> ==========================================================
> ====================
> --- llvm/trunk/test/CodeGen/Mips/abiflags32.ll (added)
> +++ llvm/trunk/test/CodeGen/Mips/abiflags32.ll Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,12 @@
> +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 %s -
> o - | FileCheck %s
> +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -
> mattr=fp64 %s -o - | FileCheck  -check-prefix=CHECK-64 %s
> +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips64 -
> mattr=-n64,n32 %s -o - | FileCheck  -check-prefix=CHECK-64n %s
> +
> +; CHECK: .nan    legacy
> +; CHECK: .module fp=32
> +
> +; CHECK-64: .nan    legacy
> +; CHECK-64: .module fp=64
> +
> +; CHECK-64n: .nan    legacy
> +; CHECK-64n: .module fp=64
> 
> Added: llvm/trunk/test/MC/Mips/mips-abi-bad.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-
> abi-bad.s?rev=212519&view=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips-abi-bad.s (added)
> +++ llvm/trunk/test/MC/Mips/mips-abi-bad.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,20 @@
> +# Error checking for malformed abi related directives
> +# RUN: not llvm-mc -triple mips-unknown-unknown %s 2>&1 | FileCheck %s
> +# CHECK: .text
> +    .module fp=3
> +# CHECK      : mips-abi-bad.s:4:16: error: unsupported option
> +# CHECK-NEXT : .module fp=3
> +# CHECK-NEXT :           ^
> +
> +    .set fp=xx,6
> +# CHECK      :mips-abi-bad.s:5:15: error: unexpected token in statement
> +# CHECK-NEXT :    .set fp=xx,6
> +# CHECK-NEXT :              ^
> +
> +# CHECK       :.set mips16
> +    .set mips16
> +    .module fp=32
> +
> +# CHECK      :mips-abi-bad.s:14:13: error: .module directive must come
> before any code
> +# CHECK-NEXT :    .module fp=32
> +# CHECK-NEXT :            ^
> 
> Modified: llvm/trunk/test/MC/Mips/mips-data-directives.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-
> data-directives.s?rev=212519&r1=212518&r2=212519&view=diff
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips-data-directives.s (original)
> +++ llvm/trunk/test/MC/Mips/mips-data-directives.s Tue Jul  8 03:59:22 2014
> @@ -12,7 +12,7 @@
> 
>  # Checking if the data and reloations were correctly emitted
>  # CHECK-OBJ:  Section {
> -# CHECK-OBJ:    Name: .data (51)
> +# CHECK-OBJ:    Name: .data (66)
>  # CHECK-OBJ:    SectionData (
>  # CHECK-OBJ:      0000: DEADC0DE DEADC0DE DEADBEEF 00000000
>  # CHECK-OBJ:      0010: 00000000 00000000
> @@ -20,7 +20,7 @@
>  # CHECK-OBJ:  }
> 
>  # CHECK-OBJ:  Section {
> -# CHECK-OBJ:    Name: .rel.data (47)
> +# CHECK-OBJ:    Name: .rel.data (62)
>  # CHECK-OBJ:    Relocations [
>  # CHECK-OBJ:      0xC R_MIPS_32 .data 0x0
>  # CHECK-OBJ:      0x10 R_MIPS_64 .data 0x0
> 
> Added: llvm/trunk/test/MC/Mips/mips32/abiflags.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips32/abiflags.s?rev=212519&view=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips32/abiflags.s (added)
> +++ llvm/trunk/test/MC/Mips/mips32/abiflags.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,37 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=32
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00002001 01010001 00000000 00000000  |.. .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=32
> +
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> Added: llvm/trunk/test/MC/Mips/mips32r2/abiflags.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips32r2/abiflags.s?rev=212519&view=au
> to
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips32r2/abiflags.s (added)
> +++ llvm/trunk/test/MC/Mips/mips32r2/abiflags.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,38 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32r2 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=32
> +# CHECK-ASM: .set fp=64
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00002002 01010001 00000000 00000000  |.. .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=32
> +        .set fp=64
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> Added: llvm/trunk/test/MC/Mips/mips64/abiflags.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips64/abiflags.s?rev=212519&view=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips64/abiflags.s (added)
> +++ llvm/trunk/test/MC/Mips/mips64/abiflags.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,37 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips64 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips64 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=64
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00004001 02020001 00000000 00000000  |.. at .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=64
> +
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> Added: llvm/trunk/test/MC/Mips/mips64r2/abi-bad.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips64r2/abi-
> bad.s?rev=212519&view=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips64r2/abi-bad.s (added)
> +++ llvm/trunk/test/MC/Mips/mips64r2/abi-bad.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,9 @@
> +# RUN: not llvm-mc %s -triple mips-unknown-unknown -mcpu=mips64r2
> 2>&1 | FileCheck %s
> +# CHECK: .text
> +
> +
> +
> +        .set fp=xx
> +# CHECK     : error: 'set fp=xx'option requires O32 ABI
> +# CHECK     : .set fp=xx
> +# CHECK     :          ^
> 
> Added: llvm/trunk/test/MC/Mips/mips64r2/abiflags.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips64r2/abiflags.s?rev=212519&view=au
> to
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips64r2/abiflags.s (added)
> +++ llvm/trunk/test/MC/Mips/mips64r2/abiflags.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,37 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips64r2 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips64r2 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=64
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00004002 02020001 00000000 00000000  |.. at .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=64
> +
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> Added: llvm/trunk/test/MC/Mips/mips_abi_flags_xx.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips_abi_flags_xx.s?rev=212519&view=a
> uto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips_abi_flags_xx.s (added)
> +++ llvm/trunk/test/MC/Mips/mips_abi_flags_xx.s Tue Jul  8 03:59:22 2014
> @@ -0,0 +1,37 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=xx
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00002001 01010005 00000000 00000000  |.. .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=xx
> +
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> Added: llvm/trunk/test/MC/Mips/mips_abi_flags_xx_set.s
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/MC/Mips/mips_abi_flags_xx_set.s?rev=212519&vie
> w=auto
> ==========================================================
> ====================
> --- llvm/trunk/test/MC/Mips/mips_abi_flags_xx_set.s (added)
> +++ llvm/trunk/test/MC/Mips/mips_abi_flags_xx_set.s Tue Jul  8 03:59:22
> 2014
> @@ -0,0 +1,38 @@
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 | \
> +# RUN:   FileCheck %s -check-prefix=CHECK-ASM
> +#
> +# RUN: llvm-mc %s -arch=mips -mcpu=mips32 -filetype=obj -o - | \
> +# RUN:   llvm-readobj -sections -section-data -section-relocations - | \
> +# RUN:     FileCheck %s -check-prefix=CHECK-OBJ
> +
> +# CHECK-ASM: .module fp=xx
> +# CHECK-ASM: .set    fp=64
> +
> +# Checking if the Mips.abiflags were correctly emitted.
> +# CHECK-OBJ:  Section {
> +# CHECK-OBJ:    Index: 5
> +# CHECK-OBJ:    Name: .MIPS.abiflags (12)
> +# CHECK-OBJ:    Type:  (0x7000002A)
> +# CHECK-OBJ:     Flags [ (0x2)
> +# CHECK-OBJ:      SHF_ALLOC (0x2)
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    Address: 0x0
> +# CHECK-OBJ:    Offset: 0x50
> +# CHECK-OBJ:    Size: 24
> +# CHECK-OBJ:    Link: 0
> +# CHECK-OBJ:    Info: 0
> +# CHECK-OBJ:    AddressAlignment: 8
> +# CHECK-OBJ:    EntrySize: 0
> +# CHECK-OBJ:    Relocations [
> +# CHECK-OBJ:    ]
> +# CHECK-OBJ:    SectionData (
> +# CHECK-OBJ:      0000: 00002001 01010005 00000000 00000000  |.. .............|
> +# CHECK-OBJ:      0010: 00000000 00000000                    |........|
> +# CHECK-OBJ:    )
> +# CHECK-OBJ:  }
> +
> +        .module fp=xx
> +        .set    fp=64
> +# FIXME: Test should include gnu_attributes directive when implemented.
> +#        An explicit .gnu_attribute must be checked against the effective
> +#        command line options and any inconsistencies reported via a warning.
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list