mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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 llvm-svn: 327511
This commit is contained in:
parent
2dcfe7cbde
commit
0510f66dad
@ -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.
|
||||
|
@ -348,6 +348,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
||||
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::checkTargetMatchPredicate(MCInst &Inst) {
|
||||
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::parseSetNoMtDirective() {
|
||||
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(uint64_t Feature) {
|
||||
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::parseSSectionDirective(StringRef Section, unsigned Type) {
|
||||
/// ::= .module softfloat
|
||||
/// ::= .module hardfloat
|
||||
/// ::= .module mt
|
||||
/// ::= .module crc
|
||||
/// ::= .module nocrc
|
||||
bool MipsAsmParser::parseDirectiveModule() {
|
||||
MCAsmParser &Parser = getParser();
|
||||
MCAsmLexer &Lexer = getLexer();
|
||||
@ -7553,6 +7592,44 @@ bool MipsAsmParser::parseDirectiveModule() {
|
||||
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;
|
||||
}
|
||||
|
||||
return false; // parseDirectiveModule has finished successfully.
|
||||
} else {
|
||||
return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
|
||||
|
@ -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 &MI, InsnType Insn, uint64_t Address,
|
||||
|
||||
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,
|
||||
|
@ -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>
|
||||
|
@ -52,6 +52,8 @@ void MipsTargetStreamer::emitDirectiveSetMsa() { forbidModuleDirective(); }
|
||||
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::emitDirectiveModuleOddSPReg() {
|
||||
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::emitDirectiveSetNoMt() {
|
||||
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::emitDirectiveModuleMT() {
|
||||
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)
|
||||
|
@ -176,6 +176,8 @@ def FeatureMSA : SubtargetFeature<"msa", "HasMSA", "true", "Mips MSA ASE">;
|
||||
|
||||
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">;
|
||||
|
||||
|
@ -576,3 +576,18 @@ class COP2LDST_FM<OPCODE5 Operation> : MipsR6Inst {
|
||||
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";
|
||||
}
|
||||
|
@ -190,6 +190,13 @@ class CLZ_R6_ENC : SPECIAL_2R_FM<OPCODE6_CLZ>;
|
||||
|
||||
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 = [NotInMicroMips] in {
|
||||
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
|
||||
|
@ -39,6 +39,8 @@ class DMULU_ENC : SPECIAL_3R_FM<0b00010, 0b011101>;
|
||||
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<"jr.hb", GPR64Opnd> {
|
||||
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_BranchZero" in {
|
||||
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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -246,6 +246,8 @@ def UseIndirectJumpsHazard : Predicate<"Subtarget->useIndirectJumpsHazard()">,
|
||||
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 {
|
||||
|
@ -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 : ProcessorItineraries<[ALU, IMULDIV], [], [
|
||||
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]>]>
|
||||
]>;
|
||||
|
@ -78,7 +78,7 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
|
||||
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(
|
||||
|
@ -162,6 +162,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
|
||||
// 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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
9
test/MC/Disassembler/Mips/crc/valid-32r6-el.txt
Normal file
9
test/MC/Disassembler/Mips/crc/valid-32r6-el.txt
Normal file
@ -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
|
9
test/MC/Disassembler/Mips/crc/valid-32r6.txt
Normal file
9
test/MC/Disassembler/Mips/crc/valid-32r6.txt
Normal file
@ -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
|
11
test/MC/Disassembler/Mips/crc/valid-64r6-el.txt
Normal file
11
test/MC/Disassembler/Mips/crc/valid-64r6-el.txt
Normal file
@ -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
|
11
test/MC/Disassembler/Mips/crc/valid-64r6.txt
Normal file
11
test/MC/Disassembler/Mips/crc/valid-64r6.txt
Normal file
@ -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
|
65
test/MC/Mips/crc/invalid.s
Normal file
65
test/MC/Mips/crc/invalid.s
Normal file
@ -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
|
24
test/MC/Mips/crc/invalid64.s
Normal file
24
test/MC/Mips/crc/invalid64.s
Normal file
@ -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
|
22
test/MC/Mips/crc/module-crc.s
Normal file
22
test/MC/Mips/crc/module-crc.s
Normal file
@ -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.
|
21
test/MC/Mips/crc/module-nocrc.s
Normal file
21
test/MC/Mips/crc/module-nocrc.s
Normal file
@ -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.
|
7
test/MC/Mips/crc/set-crc-directive.s
Normal file
7
test/MC/Mips/crc/set-crc-directive.s
Normal file
@ -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]
|
9
test/MC/Mips/crc/set-nocrc-directive.s
Normal file
9
test/MC/Mips/crc/set-nocrc-directive.s
Normal file
@ -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
|
12
test/MC/Mips/crc/valid.s
Normal file
12
test/MC/Mips/crc/valid.s
Normal file
@ -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]
|
6
test/MC/Mips/crc/valid64.s
Normal file
6
test/MC/Mips/crc/valid64.s
Normal file
@ -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]
|
@ -2261,7 +2261,8 @@ static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
|
||||
{"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[] = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user