mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-03-03 01:48:15 +00:00
[mips] Add support for Global INValidate ASE
This includes Instructions: ginvi, ginvt, Assembler directives: .set ginv, .set noginv, .module ginv, .module noginv Attribute: ginv .MIPS.abiflags: GINV (0x20000) Patch by Vladimir Stefanovic. Differential Revision: https://reviews.llvm.org/D46268 llvm-svn: 332624
This commit is contained in:
parent
690b210089
commit
0d488852fe
@ -43,7 +43,8 @@ enum AFL_ASE {
|
|||||||
AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE
|
AFL_ASE_MIPS16 = 0x00000400, // MIPS16 ASE
|
||||||
AFL_ASE_MICROMIPS = 0x00000800, // MICROMIPS 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
|
AFL_ASE_CRC = 0x00008000, // CRC ASE
|
||||||
|
AFL_ASE_GINV = 0x00020000 // GINV ASE
|
||||||
};
|
};
|
||||||
|
|
||||||
// Values for the isa_ext word of an ABI flags structure.
|
// Values for the isa_ext word of an ABI flags structure.
|
||||||
|
@ -350,6 +350,7 @@ class MipsAsmParser : public MCTargetAsmParser {
|
|||||||
bool parseSetNoMtDirective();
|
bool parseSetNoMtDirective();
|
||||||
bool parseSetNoCRCDirective();
|
bool parseSetNoCRCDirective();
|
||||||
bool parseSetNoVirtDirective();
|
bool parseSetNoVirtDirective();
|
||||||
|
bool parseSetNoGINVDirective();
|
||||||
|
|
||||||
bool parseSetAssignment();
|
bool parseSetAssignment();
|
||||||
|
|
||||||
@ -654,6 +655,10 @@ public:
|
|||||||
return getSTI().getFeatureBits()[Mips::FeatureVirt];
|
return getSTI().getFeatureBits()[Mips::FeatureVirt];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasGINV() const {
|
||||||
|
return getSTI().getFeatureBits()[Mips::FeatureGINV];
|
||||||
|
}
|
||||||
|
|
||||||
/// Warn if RegIndex is the same as the current AT.
|
/// Warn if RegIndex is the same as the current AT.
|
||||||
void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
|
void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
|
||||||
|
|
||||||
@ -6740,6 +6745,23 @@ bool MipsAsmParser::parseSetNoVirtDirective() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MipsAsmParser::parseSetNoGINVDirective() {
|
||||||
|
MCAsmParser &Parser = getParser();
|
||||||
|
Parser.Lex(); // Eat "noginv".
|
||||||
|
|
||||||
|
// 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::FeatureGINV, "ginv");
|
||||||
|
|
||||||
|
getTargetStreamer().emitDirectiveSetNoGINV();
|
||||||
|
Parser.Lex(); // Consume the EndOfStatement.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool MipsAsmParser::parseSetPopDirective() {
|
bool MipsAsmParser::parseSetPopDirective() {
|
||||||
MCAsmParser &Parser = getParser();
|
MCAsmParser &Parser = getParser();
|
||||||
SMLoc Loc = getLexer().getLoc();
|
SMLoc Loc = getLexer().getLoc();
|
||||||
@ -6969,6 +6991,10 @@ bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
|
|||||||
setFeatureBits(Mips::FeatureVirt, "virt");
|
setFeatureBits(Mips::FeatureVirt, "virt");
|
||||||
getTargetStreamer().emitDirectiveSetVirt();
|
getTargetStreamer().emitDirectiveSetVirt();
|
||||||
break;
|
break;
|
||||||
|
case Mips::FeatureGINV:
|
||||||
|
setFeatureBits(Mips::FeatureGINV, "ginv");
|
||||||
|
getTargetStreamer().emitDirectiveSetGINV();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -7281,6 +7307,10 @@ bool MipsAsmParser::parseDirectiveSet() {
|
|||||||
return parseSetFeature(Mips::FeatureVirt);
|
return parseSetFeature(Mips::FeatureVirt);
|
||||||
} else if (Tok.getString() == "novirt") {
|
} else if (Tok.getString() == "novirt") {
|
||||||
return parseSetNoVirtDirective();
|
return parseSetNoVirtDirective();
|
||||||
|
} else if (Tok.getString() == "ginv") {
|
||||||
|
return parseSetFeature(Mips::FeatureGINV);
|
||||||
|
} else if (Tok.getString() == "noginv") {
|
||||||
|
return parseSetNoGINVDirective();
|
||||||
} else {
|
} else {
|
||||||
// It is just an identifier, look for an assignment.
|
// It is just an identifier, look for an assignment.
|
||||||
parseSetAssignment();
|
parseSetAssignment();
|
||||||
@ -7531,6 +7561,8 @@ bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
|
|||||||
/// ::= .module nocrc
|
/// ::= .module nocrc
|
||||||
/// ::= .module virt
|
/// ::= .module virt
|
||||||
/// ::= .module novirt
|
/// ::= .module novirt
|
||||||
|
/// ::= .module ginv
|
||||||
|
/// ::= .module noginv
|
||||||
bool MipsAsmParser::parseDirectiveModule() {
|
bool MipsAsmParser::parseDirectiveModule() {
|
||||||
MCAsmParser &Parser = getParser();
|
MCAsmParser &Parser = getParser();
|
||||||
MCAsmLexer &Lexer = getLexer();
|
MCAsmLexer &Lexer = getLexer();
|
||||||
@ -7724,6 +7756,44 @@ bool MipsAsmParser::parseDirectiveModule() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false; // parseDirectiveModule has finished successfully.
|
||||||
|
} else if (Option == "ginv") {
|
||||||
|
setModuleFeatureBits(Mips::FeatureGINV, "ginv");
|
||||||
|
|
||||||
|
// 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().emitDirectiveModuleGINV();
|
||||||
|
|
||||||
|
// 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 == "noginv") {
|
||||||
|
clearModuleFeatureBits(Mips::FeatureGINV, "ginv");
|
||||||
|
|
||||||
|
// 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().emitDirectiveModuleNoGINV();
|
||||||
|
|
||||||
|
// 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.
|
return false; // parseDirectiveModule has finished successfully.
|
||||||
} else {
|
} else {
|
||||||
return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
|
return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
|
||||||
|
@ -165,6 +165,8 @@ public:
|
|||||||
ASESet |= Mips::AFL_ASE_CRC;
|
ASESet |= Mips::AFL_ASE_CRC;
|
||||||
if (P.hasVirt())
|
if (P.hasVirt())
|
||||||
ASESet |= Mips::AFL_ASE_VIRT;
|
ASESet |= Mips::AFL_ASE_VIRT;
|
||||||
|
if (P.hasGINV())
|
||||||
|
ASESet |= Mips::AFL_ASE_GINV;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class PredicateLibrary>
|
template <class PredicateLibrary>
|
||||||
|
@ -56,6 +56,8 @@ void MipsTargetStreamer::emitDirectiveSetCRC() {}
|
|||||||
void MipsTargetStreamer::emitDirectiveSetNoCRC() {}
|
void MipsTargetStreamer::emitDirectiveSetNoCRC() {}
|
||||||
void MipsTargetStreamer::emitDirectiveSetVirt() {}
|
void MipsTargetStreamer::emitDirectiveSetVirt() {}
|
||||||
void MipsTargetStreamer::emitDirectiveSetNoVirt() {}
|
void MipsTargetStreamer::emitDirectiveSetNoVirt() {}
|
||||||
|
void MipsTargetStreamer::emitDirectiveSetGINV() {}
|
||||||
|
void MipsTargetStreamer::emitDirectiveSetNoGINV() {}
|
||||||
void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
|
void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); }
|
||||||
void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
|
void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) {
|
||||||
forbidModuleDirective();
|
forbidModuleDirective();
|
||||||
@ -130,6 +132,8 @@ void MipsTargetStreamer::emitDirectiveModuleCRC() {}
|
|||||||
void MipsTargetStreamer::emitDirectiveModuleNoCRC() {}
|
void MipsTargetStreamer::emitDirectiveModuleNoCRC() {}
|
||||||
void MipsTargetStreamer::emitDirectiveModuleVirt() {}
|
void MipsTargetStreamer::emitDirectiveModuleVirt() {}
|
||||||
void MipsTargetStreamer::emitDirectiveModuleNoVirt() {}
|
void MipsTargetStreamer::emitDirectiveModuleNoVirt() {}
|
||||||
|
void MipsTargetStreamer::emitDirectiveModuleGINV() {}
|
||||||
|
void MipsTargetStreamer::emitDirectiveModuleNoGINV() {}
|
||||||
void MipsTargetStreamer::emitDirectiveSetFp(
|
void MipsTargetStreamer::emitDirectiveSetFp(
|
||||||
MipsABIFlagsSection::FpABIKind Value) {
|
MipsABIFlagsSection::FpABIKind Value) {
|
||||||
forbidModuleDirective();
|
forbidModuleDirective();
|
||||||
@ -449,6 +453,16 @@ void MipsTargetAsmStreamer::emitDirectiveSetNoVirt() {
|
|||||||
MipsTargetStreamer::emitDirectiveSetNoVirt();
|
MipsTargetStreamer::emitDirectiveSetNoVirt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MipsTargetAsmStreamer::emitDirectiveSetGINV() {
|
||||||
|
OS << "\t.set\tginv\n";
|
||||||
|
MipsTargetStreamer::emitDirectiveSetGINV();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsTargetAsmStreamer::emitDirectiveSetNoGINV() {
|
||||||
|
OS << "\t.set\tnoginv\n";
|
||||||
|
MipsTargetStreamer::emitDirectiveSetNoGINV();
|
||||||
|
}
|
||||||
|
|
||||||
void MipsTargetAsmStreamer::emitDirectiveSetAt() {
|
void MipsTargetAsmStreamer::emitDirectiveSetAt() {
|
||||||
OS << "\t.set\tat\n";
|
OS << "\t.set\tat\n";
|
||||||
MipsTargetStreamer::emitDirectiveSetAt();
|
MipsTargetStreamer::emitDirectiveSetAt();
|
||||||
@ -738,6 +752,14 @@ void MipsTargetAsmStreamer::emitDirectiveModuleNoVirt() {
|
|||||||
OS << "\t.module\tnovirt\n";
|
OS << "\t.module\tnovirt\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MipsTargetAsmStreamer::emitDirectiveModuleGINV() {
|
||||||
|
OS << "\t.module\tginv\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void MipsTargetAsmStreamer::emitDirectiveModuleNoGINV() {
|
||||||
|
OS << "\t.module\tnoginv\n";
|
||||||
|
}
|
||||||
|
|
||||||
// This part is for ELF object output.
|
// This part is for ELF object output.
|
||||||
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
|
MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S,
|
||||||
const MCSubtargetInfo &STI)
|
const MCSubtargetInfo &STI)
|
||||||
|
@ -889,6 +889,23 @@ class POOL32A_MFTC0_FM_MMR6<string instr_asm, bits<5> funct, bits<6> opcode>
|
|||||||
let Inst{5-0} = opcode;
|
let Inst{5-0} = opcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class POOL32A_GINV_FM_MMR6<string instr_asm, bits<2> ginv>
|
||||||
|
: MMR6Arch<instr_asm>, MipsR6Inst {
|
||||||
|
bits<5> rs;
|
||||||
|
bits<2> type;
|
||||||
|
|
||||||
|
bits<32> Inst;
|
||||||
|
|
||||||
|
let Inst{31-26} = 0x0;
|
||||||
|
let Inst{25-21} = 0x0;
|
||||||
|
let Inst{20-16} = rs;
|
||||||
|
let Inst{15-13} = 0b011;
|
||||||
|
let Inst{12-11} = ginv;
|
||||||
|
let Inst{10-9} = type;
|
||||||
|
let Inst{8-6} = 0b101;
|
||||||
|
let Inst{5-0} = 0b111100;
|
||||||
|
}
|
||||||
|
|
||||||
class POOL32F_MFTC1_FM_MMR6<string instr_asm, bits<8> funct>
|
class POOL32F_MFTC1_FM_MMR6<string instr_asm, bits<8> funct>
|
||||||
: MMR6Arch<instr_asm> {
|
: MMR6Arch<instr_asm> {
|
||||||
bits<5> rt;
|
bits<5> rt;
|
||||||
|
@ -106,6 +106,8 @@ class DI_MMR6_ENC : POOL32A_EIDI_MMR6_ENC<"di", 0b0100011101>;
|
|||||||
class ERET_MMR6_ENC : POOL32A_ERET_FM_MMR6<"eret", 0x3cd>;
|
class ERET_MMR6_ENC : POOL32A_ERET_FM_MMR6<"eret", 0x3cd>;
|
||||||
class DERET_MMR6_ENC : POOL32A_ERET_FM_MMR6<"eret", 0b1110001101>;
|
class DERET_MMR6_ENC : POOL32A_ERET_FM_MMR6<"eret", 0b1110001101>;
|
||||||
class ERETNC_MMR6_ENC : ERETNC_FM_MMR6<"eretnc">;
|
class ERETNC_MMR6_ENC : ERETNC_FM_MMR6<"eretnc">;
|
||||||
|
class GINVI_MMR6_ENC : POOL32A_GINV_FM_MMR6<"ginvi", 0b00>;
|
||||||
|
class GINVT_MMR6_ENC : POOL32A_GINV_FM_MMR6<"ginvt", 0b10>;
|
||||||
class JALRC16_MMR6_ENC : POOL16C_JALRC_FM_MM16R6<0xb>;
|
class JALRC16_MMR6_ENC : POOL16C_JALRC_FM_MM16R6<0xb>;
|
||||||
class JIALC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b100000>;
|
class JIALC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b100000>;
|
||||||
class JIC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b101000>;
|
class JIC_MMR6_ENC : JMP_IDX_COMPACT_FM<0b101000>;
|
||||||
@ -826,6 +828,25 @@ class SDC2_SWC2_MMR6_DESC_BASE<string opstr, InstrItinClass itin> {
|
|||||||
class SDC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"sdc2", II_SDC2>;
|
class SDC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"sdc2", II_SDC2>;
|
||||||
class SWC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"swc2", II_SWC2>;
|
class SWC2_MMR6_DESC : SDC2_SWC2_MMR6_DESC_BASE<"swc2", II_SWC2>;
|
||||||
|
|
||||||
|
class GINV_MMR6_DESC_BASE<string opstr,
|
||||||
|
RegisterOperand SrcRC, InstrItinClass Itin> {
|
||||||
|
dag InOperandList = (ins SrcRC:$rs, uimm2:$type);
|
||||||
|
dag OutOperandList = (outs);
|
||||||
|
string AsmString = !strconcat(opstr, "\t$rs, $type");
|
||||||
|
list<dag> Pattern = [];
|
||||||
|
Format f = FrmFR;
|
||||||
|
string BaseOpcode = opstr;
|
||||||
|
InstrItinClass Itinerary = Itin;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GINVI_MMR6_DESC : GINV_MMR6_DESC_BASE<"ginvi", GPR32Opnd,
|
||||||
|
II_GINVI> {
|
||||||
|
dag InOperandList = (ins GPR32Opnd:$rs);
|
||||||
|
string AsmString = "ginvi\t$rs";
|
||||||
|
}
|
||||||
|
class GINVT_MMR6_DESC : GINV_MMR6_DESC_BASE<"ginvt", GPR32Opnd,
|
||||||
|
II_GINVT>;
|
||||||
|
|
||||||
/// Floating Point Instructions
|
/// Floating Point Instructions
|
||||||
class FARITH_MMR6_DESC_BASE<string instr_asm, RegisterOperand RC,
|
class FARITH_MMR6_DESC_BASE<string instr_asm, RegisterOperand RC,
|
||||||
InstrItinClass Itin, bit isComm,
|
InstrItinClass Itin, bit isComm,
|
||||||
@ -1346,6 +1367,10 @@ def ERET_MMR6 : StdMMR6Rel, ERET_MMR6_DESC, ERET_MMR6_ENC, ISA_MICROMIPS32R6;
|
|||||||
def DERET_MMR6 : StdMMR6Rel, DERET_MMR6_DESC, DERET_MMR6_ENC, ISA_MICROMIPS32R6;
|
def DERET_MMR6 : StdMMR6Rel, DERET_MMR6_DESC, DERET_MMR6_ENC, ISA_MICROMIPS32R6;
|
||||||
def ERETNC_MMR6 : R6MMR6Rel, ERETNC_MMR6_DESC, ERETNC_MMR6_ENC,
|
def ERETNC_MMR6 : R6MMR6Rel, ERETNC_MMR6_DESC, ERETNC_MMR6_ENC,
|
||||||
ISA_MICROMIPS32R6;
|
ISA_MICROMIPS32R6;
|
||||||
|
def GINVI_MMR6 : R6MMR6Rel, GINVI_MMR6_ENC, GINVI_MMR6_DESC,
|
||||||
|
ISA_MICROMIPS32R6, ASE_GINV;
|
||||||
|
def GINVT_MMR6 : R6MMR6Rel, GINVT_MMR6_ENC, GINVT_MMR6_DESC,
|
||||||
|
ISA_MICROMIPS32R6, ASE_GINV;
|
||||||
def JALRC16_MMR6 : R6MMR6Rel, JALRC16_MMR6_DESC, JALRC16_MMR6_ENC,
|
def JALRC16_MMR6 : R6MMR6Rel, JALRC16_MMR6_DESC, JALRC16_MMR6_ENC,
|
||||||
ISA_MICROMIPS32R6;
|
ISA_MICROMIPS32R6;
|
||||||
def JIALC_MMR6 : R6MMR6Rel, JIALC_MMR6_ENC, JIALC_MMR6_DESC, ISA_MICROMIPS32R6;
|
def JIALC_MMR6 : R6MMR6Rel, JIALC_MMR6_ENC, JIALC_MMR6_DESC, ISA_MICROMIPS32R6;
|
||||||
|
@ -182,6 +182,9 @@ def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true", "Mips R6 CRC ASE">;
|
|||||||
def FeatureVirt : SubtargetFeature<"virt", "HasVirt", "true",
|
def FeatureVirt : SubtargetFeature<"virt", "HasVirt", "true",
|
||||||
"Mips Virtualization ASE">;
|
"Mips Virtualization ASE">;
|
||||||
|
|
||||||
|
def FeatureGINV : SubtargetFeature<"ginv", "HasGINV", "true",
|
||||||
|
"Mips Global Invalidate ASE">;
|
||||||
|
|
||||||
def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
|
def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true",
|
||||||
"microMips mode">;
|
"microMips mode">;
|
||||||
|
|
||||||
|
@ -591,3 +591,15 @@ class SPECIAL3_2R_SZ_CRC<bits<2> sz, bits<3> direction> : MipsR6Inst {
|
|||||||
|
|
||||||
string DecoderMethod = "DecodeCRC";
|
string DecoderMethod = "DecodeCRC";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SPECIAL3_GINV<bits<2> ginv> : MipsR6Inst {
|
||||||
|
bits<5> rs;
|
||||||
|
bits<2> type_;
|
||||||
|
|
||||||
|
let Inst{31-26} = OPGROUP_SPECIAL3.Value;
|
||||||
|
let Inst{25-21} = rs;
|
||||||
|
let Inst{20-10} = 0x0;
|
||||||
|
let Inst{9-8} = type_;
|
||||||
|
let Inst{7-6} = ginv;
|
||||||
|
let Inst{5-0} = 0b111101;
|
||||||
|
}
|
||||||
|
@ -197,6 +197,9 @@ class CRC32CB_ENC : SPECIAL3_2R_SZ_CRC<0,1>;
|
|||||||
class CRC32CH_ENC : SPECIAL3_2R_SZ_CRC<1,1>;
|
class CRC32CH_ENC : SPECIAL3_2R_SZ_CRC<1,1>;
|
||||||
class CRC32CW_ENC : SPECIAL3_2R_SZ_CRC<2,1>;
|
class CRC32CW_ENC : SPECIAL3_2R_SZ_CRC<2,1>;
|
||||||
|
|
||||||
|
class GINVI_ENC : SPECIAL3_GINV<0>;
|
||||||
|
class GINVT_ENC : SPECIAL3_GINV<2>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Instruction Multiclasses
|
// Instruction Multiclasses
|
||||||
@ -827,6 +830,22 @@ class CRC32CB_DESC : CRC_DESC_BASE<"crc32cb", GPR32Opnd, II_CRC32CB>;
|
|||||||
class CRC32CH_DESC : CRC_DESC_BASE<"crc32ch", GPR32Opnd, II_CRC32CH>;
|
class CRC32CH_DESC : CRC_DESC_BASE<"crc32ch", GPR32Opnd, II_CRC32CH>;
|
||||||
class CRC32CW_DESC : CRC_DESC_BASE<"crc32cw", GPR32Opnd, II_CRC32CW>;
|
class CRC32CW_DESC : CRC_DESC_BASE<"crc32cw", GPR32Opnd, II_CRC32CW>;
|
||||||
|
|
||||||
|
class GINV_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
|
||||||
|
InstrItinClass itin> : MipsR6Arch<instr_asm> {
|
||||||
|
dag OutOperandList = (outs);
|
||||||
|
dag InOperandList = (ins GPROpnd:$rs, uimm2:$type_);
|
||||||
|
string AsmString = !strconcat(instr_asm, "\t$rs, $type_");
|
||||||
|
list<dag> Pattern = [];
|
||||||
|
InstrItinClass Itinerary = itin;
|
||||||
|
bit hasSideEffects = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
class GINVI_DESC : GINV_DESC_BASE<"ginvi", GPR32Opnd, II_GINVI> {
|
||||||
|
dag InOperandList = (ins GPR32Opnd:$rs);
|
||||||
|
string AsmString = "ginvi\t$rs";
|
||||||
|
}
|
||||||
|
class GINVT_DESC : GINV_DESC_BASE<"ginvt", GPR32Opnd, II_GINVT>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Instruction Definitions
|
// Instruction Definitions
|
||||||
@ -955,6 +974,11 @@ let AdditionalPredicates = [NotInMicroMips] in {
|
|||||||
def CRC32CW : R6MMR6Rel, CRC32CW_ENC, CRC32CW_DESC, ISA_MIPS32R6, ASE_CRC;
|
def CRC32CW : R6MMR6Rel, CRC32CW_ENC, CRC32CW_DESC, ISA_MIPS32R6, ASE_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let AdditionalPredicates = [NotInMicroMips] in {
|
||||||
|
def GINVI : R6MMR6Rel, GINVI_ENC, GINVI_DESC, ISA_MIPS32R6, ASE_GINV;
|
||||||
|
def GINVT : R6MMR6Rel, GINVT_ENC, GINVT_DESC, ISA_MIPS32R6, ASE_GINV;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Instruction Aliases
|
// Instruction Aliases
|
||||||
|
@ -252,6 +252,8 @@ def HasCRC : Predicate<"Subtarget->hasCRC()">,
|
|||||||
AssemblerPredicate<"FeatureCRC">;
|
AssemblerPredicate<"FeatureCRC">;
|
||||||
def HasVirt : Predicate<"Subtarget->hasVirt()">,
|
def HasVirt : Predicate<"Subtarget->hasVirt()">,
|
||||||
AssemblerPredicate<"FeatureVirt">;
|
AssemblerPredicate<"FeatureVirt">;
|
||||||
|
def HasGINV : Predicate<"Subtarget->hasGINV()">,
|
||||||
|
AssemblerPredicate<"FeatureGINV">;
|
||||||
// TODO: Add support for FPOpFusion::Standard
|
// TODO: Add support for FPOpFusion::Standard
|
||||||
def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
|
def AllowFPOpFusion : Predicate<"TM.Options.AllowFPOpFusion =="
|
||||||
" FPOpFusion::Fast">;
|
" FPOpFusion::Fast">;
|
||||||
@ -468,6 +470,10 @@ class ASE_VIRT {
|
|||||||
list <Predicate> ASEPredicate = [HasVirt];
|
list <Predicate> ASEPredicate = [HasVirt];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ASE_GINV {
|
||||||
|
list <Predicate> ASEPredicate = [HasGINV];
|
||||||
|
}
|
||||||
|
|
||||||
// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
|
// Class used for separating microMIPSr6 and microMIPS (r3) instruction.
|
||||||
// It can be used only on instructions that doesn't inherit PredicateControl.
|
// It can be used only on instructions that doesn't inherit PredicateControl.
|
||||||
class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
|
class ISA_MICROMIPS_NOT_32R6 : PredicateControl {
|
||||||
|
@ -130,6 +130,8 @@ def II_EVPE : InstrItinClass;
|
|||||||
def II_EXT : InstrItinClass; // Any EXT instruction
|
def II_EXT : InstrItinClass; // Any EXT instruction
|
||||||
def II_FLOOR : InstrItinClass;
|
def II_FLOOR : InstrItinClass;
|
||||||
def II_FORK : InstrItinClass;
|
def II_FORK : InstrItinClass;
|
||||||
|
def II_GINVI : InstrItinClass;
|
||||||
|
def II_GINVT : InstrItinClass;
|
||||||
def II_HYPCALL : InstrItinClass;
|
def II_HYPCALL : InstrItinClass;
|
||||||
def II_INS : InstrItinClass; // Any INS instruction
|
def II_INS : InstrItinClass; // Any INS instruction
|
||||||
def II_IndirectBranchPseudo : InstrItinClass; // Indirect branch pseudo.
|
def II_IndirectBranchPseudo : InstrItinClass; // Indirect branch pseudo.
|
||||||
@ -728,5 +730,7 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
|
|||||||
InstrItinData<II_TLBWI , [InstrStage<2, [ALU]>]>,
|
InstrItinData<II_TLBWI , [InstrStage<2, [ALU]>]>,
|
||||||
InstrItinData<II_TLBWR , [InstrStage<2, [ALU]>]>,
|
InstrItinData<II_TLBWR , [InstrStage<2, [ALU]>]>,
|
||||||
InstrItinData<II_DMFGC0 , [InstrStage<2, [ALU]>]>,
|
InstrItinData<II_DMFGC0 , [InstrStage<2, [ALU]>]>,
|
||||||
InstrItinData<II_DMTGC0 , [InstrStage<2, [ALU]>]>
|
InstrItinData<II_DMTGC0 , [InstrStage<2, [ALU]>]>,
|
||||||
|
InstrItinData<II_GINVI , [InstrStage<1, [ALU]>]>,
|
||||||
|
InstrItinData<II_GINVT , [InstrStage<1, [ALU]>]>
|
||||||
]>;
|
]>;
|
||||||
|
@ -79,7 +79,7 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
|
|||||||
HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
|
HasDSPR2(false), HasDSPR3(false), AllowMixed16_32(Mixed16_32 | Mips_Os16),
|
||||||
Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
|
Os16(Mips_Os16), HasMSA(false), UseTCCInDIV(false), HasSym32(false),
|
||||||
HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
|
HasEVA(false), DisableMadd4(false), HasMT(false), HasCRC(false),
|
||||||
HasVirt(false), UseIndirectJumpsHazard(false),
|
HasVirt(false), HasGINV(false), UseIndirectJumpsHazard(false),
|
||||||
StackAlignOverride(StackAlignOverride),
|
StackAlignOverride(StackAlignOverride),
|
||||||
TM(TM), TargetTriple(TT), TSInfo(),
|
TM(TM), TargetTriple(TT), TSInfo(),
|
||||||
InstrInfo(
|
InstrInfo(
|
||||||
|
@ -168,6 +168,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
|
|||||||
// HasVirt -- supports Virtualization ASE
|
// HasVirt -- supports Virtualization ASE
|
||||||
bool HasVirt;
|
bool HasVirt;
|
||||||
|
|
||||||
|
// HasGINV -- supports R6 Global INValidate ASE
|
||||||
|
bool HasGINV;
|
||||||
|
|
||||||
// Use hazard variants of the jump register instructions for indirect
|
// Use hazard variants of the jump register instructions for indirect
|
||||||
// function calls and jump tables.
|
// function calls and jump tables.
|
||||||
bool UseIndirectJumpsHazard;
|
bool UseIndirectJumpsHazard;
|
||||||
@ -294,6 +297,7 @@ public:
|
|||||||
bool hasMT() const { return HasMT; }
|
bool hasMT() const { return HasMT; }
|
||||||
bool hasCRC() const { return HasCRC; }
|
bool hasCRC() const { return HasCRC; }
|
||||||
bool hasVirt() const { return HasVirt; }
|
bool hasVirt() const { return HasVirt; }
|
||||||
|
bool hasGINV() const { return HasGINV; }
|
||||||
bool useIndirectJumpsHazard() const {
|
bool useIndirectJumpsHazard() const {
|
||||||
return UseIndirectJumpsHazard && hasMips32r2();
|
return UseIndirectJumpsHazard && hasMips32r2();
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
virtual void emitDirectiveSetNoCRC();
|
virtual void emitDirectiveSetNoCRC();
|
||||||
virtual void emitDirectiveSetVirt();
|
virtual void emitDirectiveSetVirt();
|
||||||
virtual void emitDirectiveSetNoVirt();
|
virtual void emitDirectiveSetNoVirt();
|
||||||
|
virtual void emitDirectiveSetGINV();
|
||||||
|
virtual void emitDirectiveSetNoGINV();
|
||||||
virtual void emitDirectiveSetAt();
|
virtual void emitDirectiveSetAt();
|
||||||
virtual void emitDirectiveSetAtWithArg(unsigned RegNo);
|
virtual void emitDirectiveSetAtWithArg(unsigned RegNo);
|
||||||
virtual void emitDirectiveSetNoAt();
|
virtual void emitDirectiveSetNoAt();
|
||||||
@ -111,6 +113,8 @@ public:
|
|||||||
virtual void emitDirectiveModuleNoCRC();
|
virtual void emitDirectiveModuleNoCRC();
|
||||||
virtual void emitDirectiveModuleVirt();
|
virtual void emitDirectiveModuleVirt();
|
||||||
virtual void emitDirectiveModuleNoVirt();
|
virtual void emitDirectiveModuleNoVirt();
|
||||||
|
virtual void emitDirectiveModuleGINV();
|
||||||
|
virtual void emitDirectiveModuleNoGINV();
|
||||||
|
|
||||||
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
|
void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
|
||||||
const MCSubtargetInfo *STI);
|
const MCSubtargetInfo *STI);
|
||||||
@ -225,6 +229,8 @@ public:
|
|||||||
void emitDirectiveSetNoCRC() override;
|
void emitDirectiveSetNoCRC() override;
|
||||||
void emitDirectiveSetVirt() override;
|
void emitDirectiveSetVirt() override;
|
||||||
void emitDirectiveSetNoVirt() override;
|
void emitDirectiveSetNoVirt() override;
|
||||||
|
void emitDirectiveSetGINV() override;
|
||||||
|
void emitDirectiveSetNoGINV() override;
|
||||||
void emitDirectiveSetAt() override;
|
void emitDirectiveSetAt() override;
|
||||||
void emitDirectiveSetAtWithArg(unsigned RegNo) override;
|
void emitDirectiveSetAtWithArg(unsigned RegNo) override;
|
||||||
void emitDirectiveSetNoAt() override;
|
void emitDirectiveSetNoAt() override;
|
||||||
@ -294,6 +300,8 @@ public:
|
|||||||
void emitDirectiveModuleNoCRC() override;
|
void emitDirectiveModuleNoCRC() override;
|
||||||
void emitDirectiveModuleVirt() override;
|
void emitDirectiveModuleVirt() override;
|
||||||
void emitDirectiveModuleNoVirt() override;
|
void emitDirectiveModuleNoVirt() override;
|
||||||
|
void emitDirectiveModuleGINV() override;
|
||||||
|
void emitDirectiveModuleNoGINV() override;
|
||||||
void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
|
void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override;
|
||||||
void emitDirectiveSetOddSPReg() override;
|
void emitDirectiveSetOddSPReg() override;
|
||||||
void emitDirectiveSetNoOddSPReg() override;
|
void emitDirectiveSetNoOddSPReg() override;
|
||||||
|
5
test/MC/Disassembler/Mips/ginv/valid-el.txt
Normal file
5
test/MC/Disassembler/Mips/ginv/valid-el.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux-gnu \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+ginv | FileCheck %s
|
||||||
|
|
||||||
|
0x3d 0x02 0x40 0x7c # CHECK: ginvi $2
|
||||||
|
0xbd 0x02 0x40 0x7c # CHECK: ginvt $2, 2
|
5
test/MC/Disassembler/Mips/ginv/valid-micromips-el.txt
Normal file
5
test/MC/Disassembler/Mips/ginv/valid-micromips-el.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# RUN: llvm-mc --disassemble %s -triple=mipsel-unknown-linux-gnu \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+micromips,+ginv | FileCheck %s
|
||||||
|
|
||||||
|
0x02 0x00 0x7c 0x65 # CHECK: ginvi $2
|
||||||
|
0x02 0x00 0x7c 0x75 # CHECK: ginvt $2, 2
|
5
test/MC/Disassembler/Mips/ginv/valid-micromips.txt
Normal file
5
test/MC/Disassembler/Mips/ginv/valid-micromips.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux-gnu \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+micromips,+ginv | FileCheck %s
|
||||||
|
|
||||||
|
0x00 0x02 0x65 0x7c # CHECK: ginvi $2
|
||||||
|
0x00 0x02 0x75 0x7c # CHECK: ginvt $2, 2
|
5
test/MC/Disassembler/Mips/ginv/valid.txt
Normal file
5
test/MC/Disassembler/Mips/ginv/valid.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux-gnu \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+ginv | FileCheck %s
|
||||||
|
|
||||||
|
0x7c 0x40 0x02 0x3d # CHECK: ginvi $2
|
||||||
|
0x7c 0x40 0x02 0xbd # CHECK: ginvt $2, 2
|
23
test/MC/Mips/ginv/invalid.s
Normal file
23
test/MC/Mips/ginv/invalid.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Instructions that are invalid.
|
||||||
|
#
|
||||||
|
# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 -mattr=+ginv 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
# RUN: not llvm-mc %s -arch=mips64 -mcpu=mips64r6 -mattr=+ginv 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
# RUN: not llvm-mc %s -arch=mips -mcpu=mips32r6 \
|
||||||
|
# RUN: -mattr=+micromips,+ginv 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
|
||||||
|
ginvi # CHECK: :[[@LINE]]:3: error: too few operands for instruction
|
||||||
|
ginvi 0 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
|
||||||
|
ginvi $4, 0 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
|
||||||
|
ginvi $4, $5 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
|
||||||
|
ginvi 0($4) # CHECK: :[[@LINE]]:10: error: unexpected token in argument list
|
||||||
|
ginvt # CHECK: :[[@LINE]]:3: error: too few operands for instruction
|
||||||
|
ginvt 0 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction
|
||||||
|
ginvt $4 # CHECK: :[[@LINE]]:3: error: too few operands for instruction
|
||||||
|
ginvt $4, $5 # CHECK: :[[@LINE]]:13: error: expected 2-bit unsigned immediate
|
||||||
|
ginvt $4, 4 # CHECK: :[[@LINE]]:13: error: expected 2-bit unsigned immediate
|
||||||
|
ginvt $4, -1 # CHECK: :[[@LINE]]:13: error: expected 2-bit unsigned immediate
|
||||||
|
ginvt $4, 0, 1 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction
|
||||||
|
ginvt $4, 0($4) # CHECK: :[[@LINE]]:14: error: invalid operand for instruction
|
22
test/MC/Mips/ginv/module-ginv.s
Normal file
22
test/MC/Mips/ginv/module-ginv.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 ginv
|
||||||
|
|
||||||
|
# Check if the MIPS.abiflags section was correctly emitted:
|
||||||
|
# CHECK-OBJ: MIPS ABI Flags {
|
||||||
|
# CHECK-OBJ: ASEs [ (0x20000)
|
||||||
|
# CHECK-OBJ: GINV (0x20000)
|
||||||
|
# CHECK-OBJ: }
|
||||||
|
|
||||||
|
.module ginv
|
||||||
|
ginvi $4
|
||||||
|
|
||||||
|
# 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/ginv/module-noginv.s
Normal file
21
test/MC/Mips/ginv/module-noginv.s
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# RUN: llvm-mc %s -arch=mips -mcpu=mips32r6 -mattr=+ginv | \
|
||||||
|
# RUN: FileCheck %s -check-prefix=CHECK-ASM
|
||||||
|
#
|
||||||
|
# RUN: llvm-mc %s -arch=mips -mcpu=mips32r6 -filetype=obj -o - -mattr=+ginv | \
|
||||||
|
# RUN: llvm-readobj -mips-abi-flags - | \
|
||||||
|
# RUN: FileCheck %s -check-prefix=CHECK-OBJ
|
||||||
|
|
||||||
|
# CHECK-ASM: .module noginv
|
||||||
|
|
||||||
|
# Check that MIPS.abiflags has no GINV flag.
|
||||||
|
# CHECK-OBJ: MIPS ABI Flags {
|
||||||
|
# CHECK-OBJ: ASEs [ (0x0)
|
||||||
|
# CHECK-OBJ-NOT: ASEs [ (0x20000)
|
||||||
|
# CHECK-OBJ-NOT: GINV (0x20000)
|
||||||
|
# CHECK-OBJ: }
|
||||||
|
|
||||||
|
.module noginv
|
||||||
|
|
||||||
|
# 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/ginv/set-ginv-directive.s
Normal file
7
test/MC/Mips/ginv/set-ginv-directive.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+ginv | FileCheck %s
|
||||||
|
# RUN: llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips64r6 -mattr=+ginv | FileCheck %s
|
||||||
|
|
||||||
|
.set ginv
|
||||||
|
ginvi $4 # CHECK: ginvi $4 # encoding: [0x7c,0x80,0x00,0x3d]
|
9
test/MC/Mips/ginv/set-noginv-directive.s
Normal file
9
test/MC/Mips/ginv/set-noginv-directive.s
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# RUN: not llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+ginv 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
# RUN: not llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips64r6 -mattr=+ginv 2>%t1
|
||||||
|
# RUN: FileCheck %s < %t1
|
||||||
|
|
||||||
|
.set noginv
|
||||||
|
ginvi $4, 2 # CHECK: instruction requires a CPU feature not currently enabled
|
5
test/MC/Mips/ginv/valid-micromips.s
Normal file
5
test/MC/Mips/ginv/valid-micromips.s
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+micromips,+ginv | FileCheck %s
|
||||||
|
|
||||||
|
ginvi $4 # CHECK: ginvi $4 # encoding: [0x00,0x04,0x61,0x7c]
|
||||||
|
ginvt $4, 2 # CHECK: ginvt $4, 2 # encoding: [0x00,0x04,0x75,0x7c]
|
7
test/MC/Mips/ginv/valid.s
Normal file
7
test/MC/Mips/ginv/valid.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=mips-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips32r6 -mattr=+ginv | FileCheck %s
|
||||||
|
# RUN: llvm-mc %s -triple=mips64-unknown-linux-gnu -show-encoding \
|
||||||
|
# RUN: -mcpu=mips64r6 -mattr=+ginv | FileCheck %s
|
||||||
|
|
||||||
|
ginvi $4 # CHECK: ginvi $4 # encoding: [0x7c,0x80,0x00,0x3d]
|
||||||
|
ginvt $4, 2 # CHECK: ginvt $4, 2 # encoding: [0x7c,0x80,0x02,0xbd]
|
@ -2233,6 +2233,7 @@ static const EnumEntry<unsigned> ElfMipsASEFlags[] = {
|
|||||||
{"microMIPS", Mips::AFL_ASE_MICROMIPS},
|
{"microMIPS", Mips::AFL_ASE_MICROMIPS},
|
||||||
{"XPA", Mips::AFL_ASE_XPA},
|
{"XPA", Mips::AFL_ASE_XPA},
|
||||||
{"CRC", Mips::AFL_ASE_CRC},
|
{"CRC", Mips::AFL_ASE_CRC},
|
||||||
|
{"GINV", Mips::AFL_ASE_GINV},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
|
static const EnumEntry<unsigned> ElfMipsFpABIType[] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user