[llvm] r327511 - [mips] Add support for CRC ASE

Petar Jovanovic via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 07:13:31 PDT 2018


Author: petarj
Date: Wed Mar 14 07:13:31 2018
New Revision: 327511

URL: http://llvm.org/viewvc/llvm-project?rev=327511&view=rev
Log:
[mips] Add support for CRC ASE

This includes

  Instructions: crc32b, crc32h, crc32w, crc32d,
                crc32cb, crc32ch, crc32cw, crc32cd

  Assembler directives: .set crc, .set nocrc, .module crc, .module nocrc

  Attribute: crc

  .MIPS.abiflags: CRC (0x8000)

Patch by Vladimir Stefanovic.

Differential Revision: https://reviews.llvm.org/D44176

Added:
    llvm/trunk/test/MC/Disassembler/Mips/crc/
    llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6-el.txt
    llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6.txt
    llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6-el.txt
    llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6.txt
    llvm/trunk/test/MC/Mips/crc/
    llvm/trunk/test/MC/Mips/crc/invalid.s
    llvm/trunk/test/MC/Mips/crc/invalid64.s
    llvm/trunk/test/MC/Mips/crc/module-crc.s
    llvm/trunk/test/MC/Mips/crc/module-nocrc.s
    llvm/trunk/test/MC/Mips/crc/set-crc-directive.s
    llvm/trunk/test/MC/Mips/crc/set-nocrc-directive.s
    llvm/trunk/test/MC/Mips/crc/valid.s
    llvm/trunk/test/MC/Mips/crc/valid64.s
Modified:
    llvm/trunk/include/llvm/Support/MipsABIFlags.h
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
    llvm/trunk/lib/Target/Mips/Mips.td
    llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td
    llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td
    llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsSchedule.td
    llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
    llvm/trunk/lib/Target/Mips/MipsSubtarget.h
    llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp

Modified: llvm/trunk/include/llvm/Support/MipsABIFlags.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MipsABIFlags.h?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/MipsABIFlags.h (original)
+++ llvm/trunk/include/llvm/Support/MipsABIFlags.h Wed Mar 14 07:13:31 2018
@@ -42,7 +42,8 @@ enum AFL_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
+  AFL_ASE_XPA = 0x00001000,       // XPA ASE
+  AFL_ASE_CRC = 0x00008000        // CRC ASE
 };
 
 // Values for the isa_ext word of an ABI flags structure.

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=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Wed Mar 14 07:13:31 2018
@@ -348,6 +348,7 @@ class MipsAsmParser : public MCTargetAsm
   bool parseSetHardFloatDirective();
   bool parseSetMtDirective();
   bool parseSetNoMtDirective();
+  bool parseSetNoCRCDirective();
 
   bool parseSetAssignment();
 
@@ -644,6 +645,10 @@ public:
     return getSTI().getFeatureBits()[Mips::FeatureMT];
   }
 
+  bool hasCRC() const {
+    return getSTI().getFeatureBits()[Mips::FeatureCRC];
+  }
+
   /// Warn if RegIndex is the same as the current AT.
   void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
 
@@ -5246,6 +5251,13 @@ unsigned MipsAsmParser::checkTargetMatch
       return Match_RequiresPosSizeRange33_64;
     return Match_Success;
   }
+  case Mips::CRC32B: case Mips::CRC32CB:
+  case Mips::CRC32H: case Mips::CRC32CH:
+  case Mips::CRC32W: case Mips::CRC32CW:
+  case Mips::CRC32D: case Mips::CRC32CD:
+    if (Inst.getOperand(0).getReg() != Inst.getOperand(2).getReg())
+      return Match_RequiresSameSrcAndDst;
+    return Match_Success;
   }
 
   uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags;
@@ -6665,6 +6677,23 @@ bool MipsAsmParser::parseSetNoMtDirectiv
   return false;
 }
 
+bool MipsAsmParser::parseSetNoCRCDirective() {
+  MCAsmParser &Parser = getParser();
+  Parser.Lex(); // Eat "nocrc".
+
+  // If this is not the end of the statement, report an error.
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    reportParseError("unexpected token, expected end of statement");
+    return false;
+  }
+
+  clearFeatureBits(Mips::FeatureCRC, "crc");
+
+  getTargetStreamer().emitDirectiveSetNoCRC();
+  Parser.Lex(); // Consume the EndOfStatement.
+  return false;
+}
+
 bool MipsAsmParser::parseSetPopDirective() {
   MCAsmParser &Parser = getParser();
   SMLoc Loc = getLexer().getLoc();
@@ -6886,6 +6915,10 @@ bool MipsAsmParser::parseSetFeature(uint
     selectArch("mips64r6");
     getTargetStreamer().emitDirectiveSetMips64R6();
     break;
+  case Mips::FeatureCRC:
+    setFeatureBits(Mips::FeatureCRC, "crc");
+    getTargetStreamer().emitDirectiveSetCRC();
+    break;
   }
   return false;
 }
@@ -7190,6 +7223,10 @@ bool MipsAsmParser::parseDirectiveSet()
     return parseSetSoftFloatDirective();
   } else if (Tok.getString() == "hardfloat") {
     return parseSetHardFloatDirective();
+  } else if (Tok.getString() == "crc") {
+    return parseSetFeature(Mips::FeatureCRC);
+  } else if (Tok.getString() == "nocrc") {
+    return parseSetNoCRCDirective();
   } else {
     // It is just an identifier, look for an assignment.
     parseSetAssignment();
@@ -7436,6 +7473,8 @@ bool MipsAsmParser::parseSSectionDirecti
 ///  ::= .module softfloat
 ///  ::= .module hardfloat
 ///  ::= .module mt
+///  ::= .module crc
+///  ::= .module nocrc
 bool MipsAsmParser::parseDirectiveModule() {
   MCAsmParser &Parser = getParser();
   MCAsmLexer &Lexer = getLexer();
@@ -7549,6 +7588,44 @@ bool MipsAsmParser::parseDirectiveModule
 
     // If this is not the end of the statement, report an error.
     if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      reportParseError("unexpected token, expected end of statement");
+      return false;
+    }
+
+    return false; // parseDirectiveModule has finished successfully.
+  } else if (Option == "crc") {
+    setModuleFeatureBits(Mips::FeatureCRC, "crc");
+
+    // Synchronize the ABI Flags information with the FeatureBits information we
+    // updated above.
+    getTargetStreamer().updateABIInfo(*this);
+
+    // If printing assembly, use the recently updated ABI Flags information.
+    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
+    // emitted later).
+    getTargetStreamer().emitDirectiveModuleCRC();
+
+    // If this is not the end of the statement, report an error.
+    if (getLexer().isNot(AsmToken::EndOfStatement)) {
+      reportParseError("unexpected token, expected end of statement");
+      return false;
+    }
+
+    return false; // parseDirectiveModule has finished successfully.
+  } else if (Option == "nocrc") {
+    clearModuleFeatureBits(Mips::FeatureCRC, "crc");
+
+    // Synchronize the ABI Flags information with the FeatureBits information we
+    // updated above.
+    getTargetStreamer().updateABIInfo(*this);
+
+    // If printing assembly, use the recently updated ABI Flags information.
+    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
+    // emitted later).
+    getTargetStreamer().emitDirectiveModuleNoCRC();
+
+    // If this is not the end of the statement, report an error.
+    if (getLexer().isNot(AsmToken::EndOfStatement)) {
       reportParseError("unexpected token, expected end of statement");
       return false;
     }

Modified: llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/Mips/Disassembler/MipsDisassembler.cpp Wed Mar 14 07:13:31 2018
@@ -517,6 +517,10 @@ template <typename InsnType>
 static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address,
                                const void *Decoder);
 
+template <typename InsnType>
+static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
+                              const void *Decoder);
+
 static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn,
                                          uint64_t Address,
                                          const void *Decoder);
@@ -1129,6 +1133,22 @@ static DecodeStatus DecodeDINS(MCInst &M
 
   return MCDisassembler::Success;
 }
+
+// Auto-generated decoder wouldn't add the third operand for CRC32*.
+template <typename InsnType>
+static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address,
+                              const void *Decoder) {
+  InsnType Rs = fieldFromInstruction(Insn, 21, 5);
+  InsnType Rt = fieldFromInstruction(Insn, 16, 5);
+  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
+                                     Rt)));
+  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
+                                     Rs)));
+  MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID,
+                                     Rt)));
+  return MCDisassembler::Success;
+}
+
 /// Read two bytes from the ArrayRef and return 16 bit halfword sorted
 /// according to the given endianness.
 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h Wed Mar 14 07:13:31 2018
@@ -161,6 +161,8 @@ public:
       ASESet |= Mips::AFL_ASE_MIPS16;
     if (P.hasMT())
       ASESet |= Mips::AFL_ASE_MT;
+    if (P.hasCRC())
+      ASESet |= Mips::AFL_ASE_CRC;
   }
 
   template <class PredicateLibrary>

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=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp Wed Mar 14 07:13:31 2018
@@ -52,6 +52,8 @@ void MipsTargetStreamer::emitDirectiveSe
 void MipsTargetStreamer::emitDirectiveSetNoMsa() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetMt() {}
 void MipsTargetStreamer::emitDirectiveSetNoMt() { forbidModuleDirective(); }
+void MipsTargetStreamer::emitDirectiveSetCRC() {}
+void MipsTargetStreamer::emitDirectiveSetNoCRC() {}
 void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
 void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
   forbidModuleDirective();
@@ -122,6 +124,8 @@ void MipsTargetStreamer::emitDirectiveMo
 void MipsTargetStreamer::emitDirectiveModuleSoftFloat() {}
 void MipsTargetStreamer::emitDirectiveModuleHardFloat() {}
 void MipsTargetStreamer::emitDirectiveModuleMT() {}
+void MipsTargetStreamer::emitDirectiveModuleCRC() {}
+void MipsTargetStreamer::emitDirectiveModuleNoCRC() {}
 void MipsTargetStreamer::emitDirectiveSetFp(
     MipsABIFlagsSection::FpABIKind Value) {
   forbidModuleDirective();
@@ -421,6 +425,16 @@ void MipsTargetAsmStreamer::emitDirectiv
   MipsTargetStreamer::emitDirectiveSetNoMt();
 }
 
+void MipsTargetAsmStreamer::emitDirectiveSetCRC() {
+  OS << "\t.set\tcrc\n";
+  MipsTargetStreamer::emitDirectiveSetCRC();
+}
+
+void MipsTargetAsmStreamer::emitDirectiveSetNoCRC() {
+  OS << "\t.set\tnocrc\n";
+  MipsTargetStreamer::emitDirectiveSetNoCRC();
+}
+
 void MipsTargetAsmStreamer::emitDirectiveSetAt() {
   OS << "\t.set\tat\n";
   MipsTargetStreamer::emitDirectiveSetAt();
@@ -694,6 +708,14 @@ void MipsTargetAsmStreamer::emitDirectiv
   OS << "\t.module\tmt\n";
 }
 
+void MipsTargetAsmStreamer::emitDirectiveModuleCRC() {
+  OS << "\t.module\tcrc\n";
+}
+
+void MipsTargetAsmStreamer::emitDirectiveModuleNoCRC() {
+  OS << "\t.module\tnocrc\n";
+}
+
 // This part is for ELF object output.
 MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
                                              const MCSubtargetInfo &STI)

Modified: llvm/trunk/lib/Target/Mips/Mips.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips.td Wed Mar 14 07:13:31 2018
@@ -176,6 +176,8 @@ def FeatureMSA : SubtargetFeature<"msa",
 
 def FeatureEVA : SubtargetFeature<"eva", "HasEVA", "true", "Mips EVA ASE">;
 
+def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true", "Mips R6 CRC ASE">;
+
 def FeatureMicroMips  : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
                                          "microMips mode">;
 

Modified: llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips32r6InstrFormats.td Wed Mar 14 07:13:31 2018
@@ -576,3 +576,18 @@ class COP2LDST_FM<OPCODE5 Operation> : M
   let Inst{15-11} = base;
   let Inst{10-0}  = offset;
 }
+
+class SPECIAL3_2R_SZ_CRC<bits<2> sz, bits<3> direction> : MipsR6Inst {
+  bits<5> rs;
+  bits<5> rt;
+
+  let Inst{31-26} = OPGROUP_SPECIAL3.Value;
+  let Inst{25-21} = rs;
+  let Inst{20-16} = rt;
+  let Inst{15-11} = 0b00000;
+  let Inst{10-8} = direction;
+  let Inst{7-6} = sz;
+  let Inst{5-0} = 0b001111;
+
+  string DecoderMethod = "DecodeCRC";
+}

Modified: llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips32r6InstrInfo.td Wed Mar 14 07:13:31 2018
@@ -190,6 +190,13 @@ class CLZ_R6_ENC : SPECIAL_2R_FM<OPCODE6
 
 class SDBBP_R6_ENC : SPECIAL_SDBBP_FM;
 
+class CRC32B_ENC  : SPECIAL3_2R_SZ_CRC<0,0>;
+class CRC32H_ENC  : SPECIAL3_2R_SZ_CRC<1,0>;
+class CRC32W_ENC  : SPECIAL3_2R_SZ_CRC<2,0>;
+class CRC32CB_ENC : SPECIAL3_2R_SZ_CRC<0,1>;
+class CRC32CH_ENC : SPECIAL3_2R_SZ_CRC<1,1>;
+class CRC32CW_ENC : SPECIAL3_2R_SZ_CRC<2,1>;
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Multiclasses
@@ -804,6 +811,22 @@ class SDBBP_R6_DESC {
   InstrItinClass Itinerary = II_SDBBP;
 }
 
+class CRC_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
+                    InstrItinClass itin> : MipsR6Arch<instr_asm> {
+  dag OutOperandList = (outs GPROpnd:$rd);
+  dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt);
+  string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt");
+  list<dag> Pattern = [];
+  InstrItinClass Itinerary = itin;
+}
+
+class CRC32B_DESC : CRC_DESC_BASE<"crc32b", GPR32Opnd, II_CRC32B>;
+class CRC32H_DESC : CRC_DESC_BASE<"crc32h", GPR32Opnd, II_CRC32H>;
+class CRC32W_DESC : CRC_DESC_BASE<"crc32w", GPR32Opnd, II_CRC32W>;
+class CRC32CB_DESC : CRC_DESC_BASE<"crc32cb", GPR32Opnd, II_CRC32CB>;
+class CRC32CH_DESC : CRC_DESC_BASE<"crc32ch", GPR32Opnd, II_CRC32CH>;
+class CRC32CW_DESC : CRC_DESC_BASE<"crc32cw", GPR32Opnd, II_CRC32CW>;
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Definitions
@@ -923,6 +946,15 @@ let AdditionalPredicates = [NotInMicroMi
   def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6;
 }
 
+let AdditionalPredicates = [NotInMicroMips] in {
+  def CRC32B : R6MMR6Rel, CRC32B_ENC, CRC32B_DESC, ISA_MIPS32R6, ASE_CRC;
+  def CRC32H : R6MMR6Rel, CRC32H_ENC, CRC32H_DESC, ISA_MIPS32R6, ASE_CRC;
+  def CRC32W : R6MMR6Rel, CRC32W_ENC, CRC32W_DESC, ISA_MIPS32R6, ASE_CRC;
+  def CRC32CB : R6MMR6Rel, CRC32CB_ENC, CRC32CB_DESC, ISA_MIPS32R6, ASE_CRC;
+  def CRC32CH : R6MMR6Rel, CRC32CH_ENC, CRC32CH_DESC, ISA_MIPS32R6, ASE_CRC;
+  def CRC32CW : R6MMR6Rel, CRC32CW_ENC, CRC32CW_DESC, ISA_MIPS32R6, ASE_CRC;
+}
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Aliases

Modified: llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips64r6InstrInfo.td Wed Mar 14 07:13:31 2018
@@ -39,6 +39,8 @@ class DMULU_ENC   : SPECIAL_3R_FM<0b0001
 class LDPC_ENC    : PCREL18_FM<OPCODE3_LDPC>;
 class LLD_R6_ENC : SPECIAL3_LL_SC_FM<OPCODE6_LLD>;
 class SCD_R6_ENC : SPECIAL3_LL_SC_FM<OPCODE6_SCD>;
+class CRC32D_ENC  : SPECIAL3_2R_SZ_CRC<3,0>;
+class CRC32CD_ENC : SPECIAL3_2R_SZ_CRC<3,1>;
 
 //===----------------------------------------------------------------------===//
 //
@@ -114,6 +116,10 @@ class JR_HB64_R6_DESC : JR_HB_DESC_BASE<
   bit isCTI = 1;
   InstrItinClass Itinerary = II_JR_HB;
 }
+
+class CRC32D_DESC  : CRC_DESC_BASE<"crc32d", GPR32Opnd, II_CRC32D>;
+class CRC32CD_DESC : CRC_DESC_BASE<"crc32cd", GPR32Opnd, II_CRC32CD>;
+
 //===----------------------------------------------------------------------===//
 //
 // Instruction Definitions
@@ -174,6 +180,10 @@ let DecoderNamespace = "Mips32r6_64r6_Br
 def BLTZC64 : BLTZC_ENC, BLTZC64_DESC, ISA_MIPS64R6, GPR_64;
 def BGEZC64 : BGEZC_ENC, BGEZC64_DESC, ISA_MIPS64R6, GPR_64;
 }
+let AdditionalPredicates = [NotInMicroMips] in {
+  def CRC32D : R6MMR6Rel, CRC32D_ENC, CRC32D_DESC, ISA_MIPS64R6, ASE_CRC;
+  def CRC32CD : R6MMR6Rel, CRC32CD_ENC, CRC32CD_DESC, ISA_MIPS64R6, ASE_CRC;
+}
 
 //===----------------------------------------------------------------------===//
 //

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Wed Mar 14 07:13:31 2018
@@ -246,6 +246,8 @@ def UseIndirectJumpsHazard : Predicate<"
                             AssemblerPredicate<"FeatureUseIndirectJumpsHazard">;
 def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">,
                            AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">;
+def HasCRC   : Predicate<"Subtarget->hasCRC()">,
+               AssemblerPredicate<"FeatureCRC">;
 //===----------------------------------------------------------------------===//
 // Mips GPR size adjectives.
 // They are mutually exclusive.
@@ -443,6 +445,10 @@ class ASE_MT {
   list <Predicate> ASEPredicate = [HasMT];
 }
 
+class ASE_CRC {
+  list <Predicate> ASEPredicate = [HasCRC];
+}
+
 // Class used for separating microMIPSr6 and microMIPS (r3) instruction.
 // It can be used only on instructions that doesn't inherit PredicateControl.
 class ISA_MICROMIPS_NOT_32R6 : PredicateControl {

Modified: llvm/trunk/lib/Target/Mips/MipsSchedule.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSchedule.td?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSchedule.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsSchedule.td Wed Mar 14 07:13:31 2018
@@ -57,6 +57,14 @@ def II_CFC1             : InstrItinClass
 def II_CFC2             : InstrItinClass;
 def II_CLO              : InstrItinClass;
 def II_CLZ              : InstrItinClass;
+def II_CRC32B           : InstrItinClass;
+def II_CRC32CB          : InstrItinClass;
+def II_CRC32CD          : InstrItinClass;
+def II_CRC32CH          : InstrItinClass;
+def II_CRC32CW          : InstrItinClass;
+def II_CRC32D           : InstrItinClass;
+def II_CRC32H           : InstrItinClass;
+def II_CRC32W           : InstrItinClass;
 def II_CTC1             : InstrItinClass;
 def II_CTC2             : InstrItinClass;
 def II_CVT              : InstrItinClass;
@@ -686,5 +694,13 @@ def MipsGenericItineraries : ProcessorIt
   InstrItinData<II_RDPGPR          , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_DVP             , [InstrStage<1,  [ALU]>]>,
   InstrItinData<II_EVP             , [InstrStage<1,  [ALU]>]>,
-  InstrItinData<II_YIELD           , [InstrStage<5,  [ALU]>]>
+  InstrItinData<II_YIELD           , [InstrStage<5,  [ALU]>]>,
+  InstrItinData<II_CRC32B          , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32H          , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32W          , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32D          , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32CB         , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32CH         , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32CW         , [InstrStage<1,  [ALU]>]>,
+  InstrItinData<II_CRC32CD         , [InstrStage<1,  [ALU]>]>
 ]>;

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp Wed Mar 14 07:13:31 2018
@@ -78,7 +78,7 @@ MipsSubtarget::MipsSubtarget(const Tripl
       InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
       HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
       Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
-      HasEVA(false), DisableMadd4(false), HasMT(false),
+      HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
       UseIndirectJumpsHazard(false), StackAlignOverride(StackAlignOverride),
       TM(TM), TargetTriple(TT), TSInfo(),
       InstrInfo(

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.h?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.h Wed Mar 14 07:13:31 2018
@@ -162,6 +162,9 @@ class MipsSubtarget : public MipsGenSubt
   // HasMT -- support MT ASE.
   bool HasMT;
 
+  // HasCRC -- supports R6 CRC ASE
+  bool HasCRC;
+
   // Use hazard variants of the jump register instructions for indirect
   // function calls and jump tables.
   bool UseIndirectJumpsHazard;
@@ -286,6 +289,7 @@ public:
   bool disableMadd4() const { return DisableMadd4; }
   bool hasEVA() const { return HasEVA; }
   bool hasMT() const { return HasMT; }
+  bool hasCRC() const { return HasCRC; }
   bool useIndirectJumpsHazard() const {
     return UseIndirectJumpsHazard && hasMips32r2();
   }

Modified: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h Wed Mar 14 07:13:31 2018
@@ -42,6 +42,8 @@ public:
   virtual void emitDirectiveSetNoMsa();
   virtual void emitDirectiveSetMt();
   virtual void emitDirectiveSetNoMt();
+  virtual void emitDirectiveSetCRC();
+  virtual void emitDirectiveSetNoCRC();
   virtual void emitDirectiveSetAt();
   virtual void emitDirectiveSetAtWithArg(unsigned RegNo);
   virtual void emitDirectiveSetNoAt();
@@ -103,6 +105,8 @@ public:
   virtual void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value);
   virtual void emitDirectiveSetOddSPReg();
   virtual void emitDirectiveSetNoOddSPReg();
+  virtual void emitDirectiveModuleCRC();
+  virtual void emitDirectiveModuleNoCRC();
 
   void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
              const MCSubtargetInfo *STI);
@@ -213,6 +217,8 @@ public:
   void emitDirectiveSetNoMsa() override;
   void emitDirectiveSetMt() override;
   void emitDirectiveSetNoMt() override;
+  void emitDirectiveSetCRC() override;
+  void emitDirectiveSetNoCRC() override;
   void emitDirectiveSetAt() override;
   void emitDirectiveSetAtWithArg(unsigned RegNo) override;
   void emitDirectiveSetNoAt() override;
@@ -278,6 +284,8 @@ public:
   void emitDirectiveModuleSoftFloat() override;
   void emitDirectiveModuleHardFloat() override;
   void emitDirectiveModuleMT() override;
+  void emitDirectiveModuleCRC() override;
+  void emitDirectiveModuleNoCRC() override;
   void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
   void emitDirectiveSetOddSPReg() override;
   void emitDirectiveSetNoOddSPReg() override;

Added: llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6-el.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6-el.txt?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6-el.txt (added)
+++ llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6-el.txt Wed Mar 14 07:13:31 2018
@@ -0,0 +1,9 @@
+# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux-gnu \
+# RUN:   -mcpu=mips32r6 -mattr=+crc | FileCheck %s
+
+0x0f 0x00 0x41 0x7c  # CHECK: crc32b $1, $2, $1
+0x4f 0x00 0xa4 0x7c  # CHECK: crc32h $4, $5, $4
+0x8f 0x00 0x07 0x7d  # CHECK: crc32w $7, $8, $7
+0x0f 0x01 0x41 0x7c  # CHECK: crc32cb $1, $2, $1
+0x4f 0x01 0xa4 0x7c  # CHECK: crc32ch $4, $5, $4
+0x8f 0x01 0x07 0x7d  # CHECK: crc32cw $7, $8, $7

Added: llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6.txt?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6.txt (added)
+++ llvm/trunk/test/MC/Disassembler/Mips/crc/valid-32r6.txt Wed Mar 14 07:13:31 2018
@@ -0,0 +1,9 @@
+# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux-gnu \
+# RUN:   -mcpu=mips32r6 -mattr=+crc | FileCheck %s
+
+0x7c 0x41 0x00 0x0f  # CHECK: crc32b $1, $2, $1
+0x7c 0xa4 0x00 0x4f  # CHECK: crc32h $4, $5, $4
+0x7d 0x07 0x00 0x8f  # CHECK: crc32w $7, $8, $7
+0x7c 0x41 0x01 0x0f  # CHECK: crc32cb $1, $2, $1
+0x7c 0xa4 0x01 0x4f  # CHECK: crc32ch $4, $5, $4
+0x7d 0x07 0x01 0x8f  # CHECK: crc32cw $7, $8, $7

Added: llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6-el.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6-el.txt?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6-el.txt (added)
+++ llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6-el.txt Wed Mar 14 07:13:31 2018
@@ -0,0 +1,11 @@
+# RUN: llvm-mc --disassemble %s -triple=mips64el-unknown-linux-gnu \
+# RUN:   -mcpu=mips64r6 -mattr=+crc | FileCheck %s
+
+0x0f 0x00 0x41 0x7c  # CHECK: crc32b $1, $2, $1
+0x4f 0x00 0xa4 0x7c  # CHECK: crc32h $4, $5, $4
+0x8f 0x00 0x07 0x7d  # CHECK: crc32w $7, $8, $7
+0xcf 0x00 0x6a 0x7d  # CHECK: crc32d $10, $11, $10
+0x0f 0x01 0x41 0x7c  # CHECK: crc32cb $1, $2, $1
+0x4f 0x01 0xa4 0x7c  # CHECK: crc32ch $4, $5, $4
+0x8f 0x01 0x07 0x7d  # CHECK: crc32cw $7, $8, $7
+0xcf 0x01 0x6a 0x7d  # CHECK: crc32cd $10, $11, $10

Added: llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6.txt?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6.txt (added)
+++ llvm/trunk/test/MC/Disassembler/Mips/crc/valid-64r6.txt Wed Mar 14 07:13:31 2018
@@ -0,0 +1,11 @@
+# RUN: llvm-mc --disassemble %s -triple=mips64-unknown-linux-gnu \
+# RUN:   -mcpu=mips64r6 -mattr=+crc | FileCheck %s
+
+0x7c 0x41 0x00 0x0f  # CHECK: crc32b $1, $2, $1
+0x7c 0xa4 0x00 0x4f  # CHECK: crc32h $4, $5, $4
+0x7d 0x07 0x00 0x8f  # CHECK: crc32w $7, $8, $7
+0x7d 0x6a 0x00 0xcf  # CHECK: crc32d $10, $11, $10
+0x7c 0x41 0x01 0x0f  # CHECK: crc32cb $1, $2, $1
+0x7c 0xa4 0x01 0x4f  # CHECK: crc32ch $4, $5, $4
+0x7d 0x07 0x01 0x8f  # CHECK: crc32cw $7, $8, $7
+0x7d 0x6a 0x01 0xcf  # CHECK: crc32cd $10, $11, $10

Added: llvm/trunk/test/MC/Mips/crc/invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/invalid.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/invalid.s (added)
+++ llvm/trunk/test/MC/Mips/crc/invalid.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,65 @@
+# Instructions that are invalid.
+#
+# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 -mattr=+crc 2>%t1
+# RUN: FileCheck %s < %t1
+# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 -mattr=+crc 2>%t1
+# RUN: FileCheck %s < %t1
+
+  .set noat
+  crc32b  $1, $2, $2      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32b  $1, $2, $3      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32b  $1, $2, 2       # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+  crc32b  $1, 2, $2       # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+  crc32b  1, $2, $2       # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+  crc32b  $1, $2          # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32b  $1              # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32b  $1, $2, 0($2)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+
+  crc32h  $1, $2, $2      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32h  $1, $2, $3      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32h  $1, $2, 2       # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+  crc32h  $1, 2, $2       # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+  crc32h  1, $2, $2       # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+  crc32h  $1, $2          # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32h  $1              # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32h  $1, $2, 0($2)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+
+  crc32w  $1, $2, $2      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32w  $1, $2, $3      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32w  $1, $2, 2       # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+  crc32w  $1, 2, $2       # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+  crc32w  1, $2, $2       # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+  crc32w  $1, $2          # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32w  $1              # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32w  $1, $2, 0($2)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+
+  crc32cb  $1, $2, $2     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cb  $1, $2, $3     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cb  $1, $2, 2      # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+  crc32cb  $1, 2, $2      # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+  crc32cb  1, $2, $2      # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
+  crc32cb  $1, $2         # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cb  $1             # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cb  $1, $2, 0($2)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+
+  crc32ch  $1, $2, $2     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32ch  $1, $2, $3     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32ch  $1, $2, 2      # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+  crc32ch  $1, 2, $2      # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+  crc32ch  1, $2, $2      # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
+  crc32ch  $1, $2         # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32ch  $1             # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32ch  $1, $2, 0($2)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+
+  crc32cw  $1, $2, $2     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cw  $1, $2, $3     # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cw  $1, $2, 2      # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+  crc32cw  $1, 2, $2      # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
+  crc32cw  1, $2, $2      # CHECK: :[[@LINE]]:12: error: invalid operand for instruction
+  crc32cw  $1, $2         # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cw  $1             # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cw  $1, $2, 0($2)  # CHECK: :[[@LINE]]:20: error: invalid operand for instruction
+
+  crc32 $1, $2, $2        # CHECK: :[[@LINE]]:3: error: unknown instruction
+  crcb $1, $2, $2         # CHECK: :[[@LINE]]:3: error: unknown instruction
+  crc $1, $2, $2          # CHECK: :[[@LINE]]:3: error: unknown instruction

Added: llvm/trunk/test/MC/Mips/crc/invalid64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/invalid64.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/invalid64.s (added)
+++ llvm/trunk/test/MC/Mips/crc/invalid64.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,24 @@
+# Instructions that are invalid.
+#
+# RUN: not llvm-mc %s -triple=mips64-unknown-linux-gnu -mcpu=mips64r6 \
+# RUN:     -mattr=+crc 2>%t1
+# RUN: FileCheck %s < %t1
+
+  .set noat
+  crc32d $1, $2, $2       # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32d $1, $2, $3       # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32d $1, $2, 2        # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+  crc32d $1, 2, $2        # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
+  crc32d 1, $2, $2        # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
+  crc32d $1, $2           # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32d $1               # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32d $1, $2, 0($2)    # CHECK: :[[@LINE]]:18: error: invalid operand for instruction
+
+  crc32cd $1, $2, $2      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cd $1, $2, $3      # CHECK: :[[@LINE]]:3: error: source and destination must match
+  crc32cd $1, $2, 2       # CHECK: :[[@LINE]]:19: error: invalid operand for instruction
+  crc32cd $1, 2, $2       # CHECK: :[[@LINE]]:15: error: invalid operand for instruction
+  crc32cd 1, $2, $2       # CHECK: :[[@LINE]]:11: error: invalid operand for instruction
+  crc32cd $1, $2          # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cd $1              # CHECK: :[[@LINE]]:3: error: too few operands for instruction
+  crc32cd $1, $2, 0($2)   # CHECK: :[[@LINE]]:19: error: invalid operand for instruction

Added: llvm/trunk/test/MC/Mips/crc/module-crc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/module-crc.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/module-crc.s (added)
+++ llvm/trunk/test/MC/Mips/crc/module-crc.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,22 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -mcpu=mips32r6 | \
+# RUN:   FileCheck %s -check-prefix=CHECK-ASM
+#
+# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -mcpu=mips32r6 \
+# RUN:   -filetype=obj -o - | \
+# RUN:   llvm-readobj -mips-abi-flags - | \
+# RUN:   FileCheck %s -check-prefix=CHECK-OBJ
+
+# CHECK-ASM: .module crc
+
+# Check if the MIPS.abiflags section was correctly emitted:
+# CHECK-OBJ: MIPS ABI Flags {
+# CHECK-OBJ:   ASEs [ (0x8000)
+# CHECK-OBJ:     CRC (0x8000)
+# CHECK-OBJ: }
+
+  .module crc
+  crc32b $2,$3,$2
+
+# 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/crc/module-nocrc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/module-nocrc.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/module-nocrc.s (added)
+++ llvm/trunk/test/MC/Mips/crc/module-nocrc.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,21 @@
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32r6 -mattr=+crc | \
+# RUN:   FileCheck %s -check-prefix=CHECK-ASM
+#
+# RUN: llvm-mc %s -arch=mips -mcpu=mips32r6 -filetype=obj -o - -mattr=+crc | \
+# RUN:   llvm-readobj -mips-abi-flags - | \
+# RUN:   FileCheck %s -check-prefix=CHECK-OBJ
+
+# CHECK-ASM: .module nocrc
+
+# Check that MIPS.abiflags has no CRC flag.
+# CHECK-OBJ: MIPS ABI Flags {
+# CHECK-OBJ:   ASEs [ (0x0)
+# CHECK-OBJ-NOT:   ASEs [ (0x8000)
+# CHECK-OBJ-NOT:     CRC (0x8000)
+# CHECK-OBJ: }
+
+  .module nocrc
+
+# 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/crc/set-crc-directive.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/set-crc-directive.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/set-crc-directive.s (added)
+++ llvm/trunk/test/MC/Mips/crc/set-crc-directive.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,7 @@
+# RUN: llvm-mc %s -show-encoding -triple=mips-unknown-linux-gnu \
+# RUN:   -mcpu=mips32r6 | FileCheck %s
+# RUN: llvm-mc %s -show-encoding -triple=mips64-unknown-linux-gnu \
+# RUN:   -mcpu=mips64r6 | FileCheck %s
+
+  .set crc
+  crc32b	$1, $2, $1 	# CHECK: crc32b	$1, $2, $1 # encoding: [0x7c,0x41,0x00,0x0f]

Added: llvm/trunk/test/MC/Mips/crc/set-nocrc-directive.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/set-nocrc-directive.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/set-nocrc-directive.s (added)
+++ llvm/trunk/test/MC/Mips/crc/set-nocrc-directive.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,9 @@
+# RUN: not llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
+# RUN:     -mcpu=mips32r6 -mattr=+crc 2>%t1
+# RUN: FileCheck %s < %t1
+# RUN: not llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
+# RUN:     -mcpu=mips64r6 -mattr=+crc 2>%t1
+# RUN: FileCheck %s < %t1
+
+  .set nocrc
+  crc32b	$1, $2, $1 	# CHECK: instruction requires a CPU feature not currently enabled

Added: llvm/trunk/test/MC/Mips/crc/valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/valid.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/valid.s (added)
+++ llvm/trunk/test/MC/Mips/crc/valid.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,12 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
+# RUN:   -mcpu=mips32r6 -mattr=+crc | FileCheck %s
+# RUN: llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
+# RUN:   -mcpu=mips64r6 -mattr=+crc | FileCheck %s
+
+  .set noat
+  crc32b $1, $2, $1      # CHECK: crc32b $1, $2, $1   # encoding: [0x7c,0x41,0x00,0x0f]
+  crc32h $4, $5, $4      # CHECK: crc32h $4, $5, $4   # encoding: [0x7c,0xa4,0x00,0x4f]
+  crc32w $7, $8, $7      # CHECK: crc32w $7, $8, $7   # encoding: [0x7d,0x07,0x00,0x8f]
+  crc32cb $1, $2, $1     # CHECK: crc32cb $1, $2, $1  # encoding: [0x7c,0x41,0x01,0x0f]
+  crc32ch $4, $5, $4     # CHECK: crc32ch $4, $5, $4  # encoding: [0x7c,0xa4,0x01,0x4f]
+  crc32cw $7, $8, $7     # CHECK: crc32cw $7, $8, $7  # encoding: [0x7d,0x07,0x01,0x8f]

Added: llvm/trunk/test/MC/Mips/crc/valid64.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/crc/valid64.s?rev=327511&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/crc/valid64.s (added)
+++ llvm/trunk/test/MC/Mips/crc/valid64.s Wed Mar 14 07:13:31 2018
@@ -0,0 +1,6 @@
+# RUN: llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
+# RUN:   -mcpu=mips64r6 -mattr=+crc | FileCheck %s
+
+  .set noat
+  crc32d $10, $11, $10   # CHECK: crc32d  $10, $11, $10  # encoding: [0x7d,0x6a,0x00,0xcf]
+  crc32cd $10, $11, $10  # CHECK: crc32cd $10, $11, $10  # encoding: [0x7d,0x6a,0x01,0xcf]

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=327511&r1=327510&r2=327511&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Mar 14 07:13:31 2018
@@ -2261,7 +2261,8 @@ static const EnumEntry<unsigned> ElfMips
   {"MSA",                Mips::AFL_ASE_MSA},
   {"MIPS16",             Mips::AFL_ASE_MIPS16},
   {"microMIPS",          Mips::AFL_ASE_MICROMIPS},
-  {"XPA",                Mips::AFL_ASE_XPA}
+  {"XPA",                Mips::AFL_ASE_XPA},
+  {"CRC",                Mips::AFL_ASE_CRC},
 };
 
 static const EnumEntry<unsigned> ElfMipsFpABIType[] = {




More information about the llvm-commits mailing list