diff options
| author | Petar Jovanovic <petar.jovanovic@mips.com> | 2018-04-27 09:12:08 +0000 |
|---|---|---|
| committer | Petar Jovanovic <petar.jovanovic@mips.com> | 2018-04-27 09:12:08 +0000 |
| commit | d4349f3bf676c0fcb4242b5abe8f5f6043ed4b34 (patch) | |
| tree | da1d4b030f24702932f2e94539dd63f05496dfc1 /llvm/lib/Target | |
| parent | 21dc68fe7b4cd06b2ac194a66467352ddc2c4ecb (diff) | |
| download | bcm5719-llvm-d4349f3bf676c0fcb4242b5abe8f5f6043ed4b34.tar.gz bcm5719-llvm-d4349f3bf676c0fcb4242b5abe8f5f6043ed4b34.zip | |
[mips] Add support for Virtualization ASE
This includes
Instructions: tlbginv, tlbginvf, tlbgp, tlbgr, tlbgwi, tlbgwr, hypcall
mfgc0, mtgc0, mfhgc0, mthgc0, dmfgc0, dmtgc0,
Assembler directives: .set virt, .set novirt, .module virt, .module novirt
Attribute: virt
.MIPS.abiflags: VZ (0x100)
Patch by Vladimir Stefanovic.
Differential Revision: https://reviews.llvm.org/D44905
llvm-svn: 331024
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 70 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrFormats.td | 36 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MicroMipsInstrInfo.td | 68 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Mips.td | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 29 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrFormats.td | 19 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 89 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsSchedule.td | 28 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsSubtarget.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsSubtarget.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsTargetStreamer.h | 8 |
13 files changed, 357 insertions, 24 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 59eeefe2f68..b3cfc869f29 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -349,6 +349,7 @@ class MipsAsmParser : public MCTargetAsmParser { bool parseSetMtDirective(); bool parseSetNoMtDirective(); bool parseSetNoCRCDirective(); + bool parseSetNoVirtDirective(); bool parseSetAssignment(); @@ -649,6 +650,10 @@ public: return getSTI().getFeatureBits()[Mips::FeatureCRC]; } + bool hasVirt() const { + return getSTI().getFeatureBits()[Mips::FeatureVirt]; + } + /// Warn if RegIndex is the same as the current AT. void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc); @@ -6718,6 +6723,23 @@ bool MipsAsmParser::parseSetNoCRCDirective() { return false; } +bool MipsAsmParser::parseSetNoVirtDirective() { + MCAsmParser &Parser = getParser(); + Parser.Lex(); // Eat "novirt". + + // 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::FeatureVirt, "virt"); + + getTargetStreamer().emitDirectiveSetNoVirt(); + Parser.Lex(); // Consume the EndOfStatement. + return false; +} + bool MipsAsmParser::parseSetPopDirective() { MCAsmParser &Parser = getParser(); SMLoc Loc = getLexer().getLoc(); @@ -6943,6 +6965,10 @@ bool MipsAsmParser::parseSetFeature(uint64_t Feature) { setFeatureBits(Mips::FeatureCRC, "crc"); getTargetStreamer().emitDirectiveSetCRC(); break; + case Mips::FeatureVirt: + setFeatureBits(Mips::FeatureVirt, "virt"); + getTargetStreamer().emitDirectiveSetVirt(); + break; } return false; } @@ -7251,6 +7277,10 @@ bool MipsAsmParser::parseDirectiveSet() { return parseSetFeature(Mips::FeatureCRC); } else if (Tok.getString() == "nocrc") { return parseSetNoCRCDirective(); + } else if (Tok.getString() == "virt") { + return parseSetFeature(Mips::FeatureVirt); + } else if (Tok.getString() == "novirt") { + return parseSetNoVirtDirective(); } else { // It is just an identifier, look for an assignment. parseSetAssignment(); @@ -7499,6 +7529,8 @@ bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) { /// ::= .module mt /// ::= .module crc /// ::= .module nocrc +/// ::= .module virt +/// ::= .module novirt bool MipsAsmParser::parseDirectiveModule() { MCAsmParser &Parser = getParser(); MCAsmLexer &Lexer = getLexer(); @@ -7655,6 +7687,44 @@ bool MipsAsmParser::parseDirectiveModule() { } return false; // parseDirectiveModule has finished successfully. + } else if (Option == "virt") { + setModuleFeatureBits(Mips::FeatureVirt, "virt"); + + // 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().emitDirectiveModuleVirt(); + + // 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 == "novirt") { + clearModuleFeatureBits(Mips::FeatureVirt, "virt"); + + // 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().emitDirectiveModuleNoVirt(); + + // 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."); } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h index ea75d981684..bced1e96002 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h @@ -163,6 +163,8 @@ public: ASESet |= Mips::AFL_ASE_MT; if (P.hasCRC()) ASESet |= Mips::AFL_ASE_CRC; + if (P.hasVirt()) + ASESet |= Mips::AFL_ASE_VIRT; } template <class PredicateLibrary> diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 7f0cc9e33f4..96c6f08908e 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -54,6 +54,8 @@ void MipsTargetStreamer::emitDirectiveSetMt() {} void MipsTargetStreamer::emitDirectiveSetNoMt() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetCRC() {} void MipsTargetStreamer::emitDirectiveSetNoCRC() {} +void MipsTargetStreamer::emitDirectiveSetVirt() {} +void MipsTargetStreamer::emitDirectiveSetNoVirt() {} void MipsTargetStreamer::emitDirectiveSetAt() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetAtWithArg(unsigned RegNo) { forbidModuleDirective(); @@ -126,6 +128,8 @@ void MipsTargetStreamer::emitDirectiveModuleHardFloat() {} void MipsTargetStreamer::emitDirectiveModuleMT() {} void MipsTargetStreamer::emitDirectiveModuleCRC() {} void MipsTargetStreamer::emitDirectiveModuleNoCRC() {} +void MipsTargetStreamer::emitDirectiveModuleVirt() {} +void MipsTargetStreamer::emitDirectiveModuleNoVirt() {} void MipsTargetStreamer::emitDirectiveSetFp( MipsABIFlagsSection::FpABIKind Value) { forbidModuleDirective(); @@ -435,6 +439,16 @@ void MipsTargetAsmStreamer::emitDirectiveSetNoCRC() { MipsTargetStreamer::emitDirectiveSetNoCRC(); } +void MipsTargetAsmStreamer::emitDirectiveSetVirt() { + OS << "\t.set\tvirt\n"; + MipsTargetStreamer::emitDirectiveSetVirt(); +} + +void MipsTargetAsmStreamer::emitDirectiveSetNoVirt() { + OS << "\t.set\tnovirt\n"; + MipsTargetStreamer::emitDirectiveSetNoVirt(); +} + void MipsTargetAsmStreamer::emitDirectiveSetAt() { OS << "\t.set\tat\n"; MipsTargetStreamer::emitDirectiveSetAt(); @@ -716,6 +730,14 @@ void MipsTargetAsmStreamer::emitDirectiveModuleNoCRC() { OS << "\t.module\tnocrc\n"; } +void MipsTargetAsmStreamer::emitDirectiveModuleVirt() { + OS << "\t.module\tvirt\n"; +} + +void MipsTargetAsmStreamer::emitDirectiveModuleNoVirt() { + OS << "\t.module\tnovirt\n"; +} + // This part is for ELF object output. MipsTargetELFStreamer::MipsTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI) diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td index 050f8ba1e47..a72078c0f6e 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrFormats.td @@ -1053,3 +1053,39 @@ class POOL32A_CFTC2_FM_MM<bits<10> funct> : MMArch { let Inst{15-6} = funct; let Inst{5-0} = 0b111100; } + +class POOL32A_TLBINV_FM_MM<bits<10> funct> : MMArch { + bits<32> Inst; + + let Inst{31-26} = 0x0; + let Inst{25-16} = 0x0; + let Inst{15-6} = funct; + let Inst{5-0} = 0b111100; +} + +class POOL32A_MFTC0_FM_MM<bits<5> funct, bits<6> opcode> : MMArch { + bits<5> rt; + bits<5> rs; + bits<3> sel; + + bits<32> Inst; + + let Inst{31-26} = 0b000000; + let Inst{25-21} = rt; + let Inst{20-16} = rs; + let Inst{15-14} = 0; + let Inst{13-11} = sel; + let Inst{10-6} = funct; + let Inst{5-0} = opcode; +} + +class POOL32A_HYPCALL_FM_MM : MMArch { + bits<32> Inst; + + bits<10> code_; + + let Inst{31-26} = 0x0; + let Inst{25-16} = code_; + let Inst{15-6} = 0b1100001101; + let Inst{5-0} = 0b111100; +} diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td index 3e560f5e576..f83d9e64d1f 100644 --- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td @@ -595,6 +595,31 @@ class UncondBranchMM16<string opstr> : let Defs = [AT]; } +class HypcallMM<string opstr> : + InstSE<(outs), (ins uimm10:$code_), + !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther> { + let BaseOpcode = opstr; +} + +class TLBINVMM<string opstr, InstrItinClass Itin> : + InstSE<(outs), (ins), opstr, [], Itin, FrmOther> { + let BaseOpcode = opstr; +} + +class MfCop0MM<string opstr, RegisterOperand DstRC, + RegisterOperand SrcRC, InstrItinClass Itin> : + InstSE<(outs DstRC:$rt), (ins SrcRC:$rs, uimm3:$sel), + !strconcat(opstr, "\t$rt, $rs, $sel"), [], Itin, FrmR> { + let BaseOpcode = opstr; +} + +class MtCop0MM<string opstr, RegisterOperand DstRC, + RegisterOperand SrcRC, InstrItinClass Itin> : + InstSE<(outs DstRC:$rs), (ins SrcRC:$rt, uimm3:$sel), + !strconcat(opstr, "\t$rt, $rs, $sel"), [], Itin, FrmR> { + let BaseOpcode = opstr; +} + def ADDU16_MM : ArithRMM16<"addu16", GPRMM16Opnd, 1, II_ADDU, add>, ARITH_FM_MM16<0>, ISA_MICROMIPS_NOT_32R6; def AND16_MM : LogicRMM16<"and16", GPRMM16Opnd, II_AND, and>, @@ -1072,6 +1097,35 @@ let DecoderNamespace = "MicroMips" in { ISA_MICROMIPS32_NOT_MIPS32R6; } +let DecoderNamespace = "MicroMips" in { + def MFGC0_MM : MMRel, MfCop0MM<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>, + POOL32A_MFTC0_FM_MM<0b10011, 0b111100>, + ISA_MICROMIPS32R5, ASE_VIRT; + def MFHGC0_MM : MMRel, MfCop0MM<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>, + POOL32A_MFTC0_FM_MM<0b10011, 0b110100>, + ISA_MICROMIPS32R5, ASE_VIRT; + def MTGC0_MM : MMRel, MtCop0MM<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>, + POOL32A_MFTC0_FM_MM<0b11011, 0b111100>, + ISA_MICROMIPS32R5, ASE_VIRT; + def MTHGC0_MM : MMRel, MtCop0MM<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>, + POOL32A_MFTC0_FM_MM<0b11011, 0b110100>, + ISA_MICROMIPS32R5, ASE_VIRT; + def HYPCALL_MM : MMRel, HypcallMM<"hypcall">, POOL32A_HYPCALL_FM_MM, + ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGINV_MM : MMRel, TLBINVMM<"tlbginv", II_TLBGINV>, + POOL32A_TLBINV_FM_MM<0x105>, ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGINVF_MM : MMRel, TLBINVMM<"tlbginvf", II_TLBGINVF>, + POOL32A_TLBINV_FM_MM<0x145>, ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGP_MM : MMRel, TLBINVMM<"tlbgp", II_TLBGP>, + POOL32A_TLBINV_FM_MM<0x5>, ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGR_MM : MMRel, TLBINVMM<"tlbgr", II_TLBGR>, + POOL32A_TLBINV_FM_MM<0x45>, ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGWI_MM : MMRel, TLBINVMM<"tlbgwi", II_TLBGWI>, + POOL32A_TLBINV_FM_MM<0x85>, ISA_MICROMIPS32R5, ASE_VIRT; + def TLBGWR_MM : MMRel, TLBINVMM<"tlbgwr", II_TLBGWR>, + POOL32A_TLBINV_FM_MM<0xc5>, ISA_MICROMIPS32R5, ASE_VIRT; +} + //===----------------------------------------------------------------------===// // MicroMips arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// @@ -1262,3 +1316,17 @@ let Predicates = [InMicroMips] in { def : MipsInstAlias<"break $imm", (BREAK_MM uimm10:$imm, 0), 1>, ISA_MICROMIPS; } +def : MipsInstAlias<"hypcall", (HYPCALL_MM 0), 1>, + ISA_MICROMIPS32R5, ASE_VIRT; +def : MipsInstAlias<"mfgc0 $rt, $rs", + (MFGC0_MM GPR32Opnd:$rt, COP0Opnd:$rs, 0), 0>, + ISA_MICROMIPS32R5, ASE_VIRT; +def : MipsInstAlias<"mfhgc0 $rt, $rs", + (MFHGC0_MM GPR32Opnd:$rt, COP0Opnd:$rs, 0), 0>, + ISA_MICROMIPS32R5, ASE_VIRT; +def : MipsInstAlias<"mtgc0 $rt, $rs", + (MTGC0_MM COP0Opnd:$rs, GPR32Opnd:$rt, 0), 0>, + ISA_MICROMIPS32R5, ASE_VIRT; +def : MipsInstAlias<"mthgc0 $rt, $rs", + (MTHGC0_MM COP0Opnd:$rs, GPR32Opnd:$rt, 0), 0>, + ISA_MICROMIPS32R5, ASE_VIRT; diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td index 75bf9154542..38559a9b2ad 100644 --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -179,6 +179,9 @@ def FeatureEVA : SubtargetFeature<"eva", "HasEVA", "true", "Mips EVA ASE">; def FeatureCRC : SubtargetFeature<"crc", "HasCRC", "true", "Mips R6 CRC ASE">; +def FeatureVirt : SubtargetFeature<"virt", "HasVirt", "true", + "Mips Virtualization ASE">; + def FeatureMicroMips : SubtargetFeature<"micromips", "InMicroMipsMode", "true", "microMips mode">; diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 93f8e09ca2b..8da35bb594c 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -545,16 +545,23 @@ def DMTC2_OCTEON : MFC2OP<"dmtc2", GPR64Opnd, II_DMTC2>, MFC2OP_FM<0x12, 5>, /// Move between CPU and coprocessor registers let DecoderNamespace = "Mips64", Predicates = [HasMips64] in { -def DMFC0 : MFC3OP<"dmfc0", GPR64Opnd, COP0Opnd, II_DMFC0>, MFC3OP_FM<0x10, 1>, - ISA_MIPS3; -def DMTC0 : MTC3OP<"dmtc0", COP0Opnd, GPR64Opnd, II_DMTC0>, MFC3OP_FM<0x10, 5>, - ISA_MIPS3; -def DMFC2 : MFC3OP<"dmfc2", GPR64Opnd, COP2Opnd, II_DMFC2>, MFC3OP_FM<0x12, 1>, - ISA_MIPS3; -def DMTC2 : MTC3OP<"dmtc2", COP2Opnd, GPR64Opnd, II_DMTC2>, MFC3OP_FM<0x12, 5>, - ISA_MIPS3; +def DMFC0 : MFC3OP<"dmfc0", GPR64Opnd, COP0Opnd, II_DMFC0>, + MFC3OP_FM<0x10, 1, 0>, ISA_MIPS3; +def DMTC0 : MTC3OP<"dmtc0", COP0Opnd, GPR64Opnd, II_DMTC0>, + MFC3OP_FM<0x10, 5, 0>, ISA_MIPS3; +def DMFC2 : MFC3OP<"dmfc2", GPR64Opnd, COP2Opnd, II_DMFC2>, + MFC3OP_FM<0x12, 1, 0>, ISA_MIPS3; +def DMTC2 : MTC3OP<"dmtc2", COP2Opnd, GPR64Opnd, II_DMTC2>, + MFC3OP_FM<0x12, 5, 0>, ISA_MIPS3; } +/// Move between CPU and guest coprocessor registers (Virtualization ASE) +let DecoderNamespace = "Mips64" in { + def DMFGC0 : MFC3OP<"dmfgc0", GPR64Opnd, COP0Opnd, II_DMFGC0>, + MFC3OP_FM<0x10, 3, 1>, ISA_MIPS64R5, ASE_VIRT; + def DMTGC0 : MTC3OP<"dmtgc0", COP0Opnd, GPR64Opnd, II_DMTGC0>, + MFC3OP_FM<0x10, 3, 3>, ISA_MIPS64R5, ASE_VIRT; +} let AdditionalPredicates = [UseIndirectJumpsHazard] in def JALRHB64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR_HB64, RA_64>; @@ -873,6 +880,12 @@ let AdditionalPredicates = [NotInMicroMips] in { (DMTC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>; def : MipsInstAlias<"dmfc0 $rt, $rd", (DMFC0 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>; + def : MipsInstAlias<"dmfgc0 $rt, $rd", + (DMFGC0 GPR64Opnd:$rt, COP0Opnd:$rd, 0), 0>, + ISA_MIPS64R5, ASE_VIRT; + def : MipsInstAlias<"dmtgc0 $rt, $rd", + (DMTGC0 COP0Opnd:$rd, GPR64Opnd:$rt, 0), 0>, + ISA_MIPS64R5, ASE_VIRT; } def : MipsInstAlias<"dmfc2 $rt, $rd", (DMFC2 GPR64Opnd:$rt, COP2Opnd:$rd, 0), 0>; def : MipsInstAlias<"dmtc2 $rt, $rd", (DMTC2 COP2Opnd:$rd, GPR64Opnd:$rt, 0), 0>; diff --git a/llvm/lib/Target/Mips/MipsInstrFormats.td b/llvm/lib/Target/Mips/MipsInstrFormats.td index 516edef0556..1c3ecdadf0a 100644 --- a/llvm/lib/Target/Mips/MipsInstrFormats.td +++ b/llvm/lib/Target/Mips/MipsInstrFormats.td @@ -220,10 +220,9 @@ class FJ<bits<6> op> : StdArch } //===----------------------------------------------------------------------===// -// MFC instruction class in Mips : <|op|mf|rt|rd|0000000|sel|> +// MFC instruction class in Mips : <|op|mf|rt|rd|gst|0000|sel|> //===----------------------------------------------------------------------===// -class MFC3OP_FM<bits<6> op, bits<5> mfmt> -{ +class MFC3OP_FM<bits<6> op, bits<5> mfmt, bits<3> guest> : StdArch { bits<5> rt; bits<5> rd; bits<3> sel; @@ -234,7 +233,8 @@ class MFC3OP_FM<bits<6> op, bits<5> mfmt> let Inst{25-21} = mfmt; let Inst{20-16} = rt; let Inst{15-11} = rd; - let Inst{10-3} = 0; + let Inst{10-8} = guest; + let Inst{7-3} = 0; let Inst{2-0} = sel; } @@ -970,3 +970,14 @@ class CACHEOP_FM<bits<6> op> : StdArch { let Inst{20-16} = hint; let Inst{15-0} = offset; } + +class HYPCALL_FM<bits<6> op> : StdArch { + bits<10> code_; + + bits<32> Inst; + + let Inst{31-26} = 0b010000; + let Inst{25} = 1; + let Inst{20-11} = code_; + let Inst{5-0} = op; +} diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index 31e568da741..b71068dd98e 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -202,6 +202,8 @@ def NotMips64 : Predicate<"!Subtarget->hasMips64()">, AssemblerPredicate<"!FeatureMips64">; def HasMips64r2 : Predicate<"Subtarget->hasMips64r2()">, AssemblerPredicate<"FeatureMips64r2">; +def HasMips64r5 : Predicate<"Subtarget->hasMips64r5()">, + AssemblerPredicate<"FeatureMips64r5">; def HasMips64r6 : Predicate<"Subtarget->hasMips64r6()">, AssemblerPredicate<"FeatureMips64r6">; def NotMips64r6 : Predicate<"!Subtarget->hasMips64r6()">, @@ -248,6 +250,8 @@ def NoIndirectJumpGuards : Predicate<"!Subtarget->useIndirectJumpsHazard()">, AssemblerPredicate<"!FeatureUseIndirectJumpsHazard">; def HasCRC : Predicate<"Subtarget->hasCRC()">, AssemblerPredicate<"FeatureCRC">; +def HasVirt : Predicate<"Subtarget->hasVirt()">, + AssemblerPredicate<"FeatureVirt">; //===----------------------------------------------------------------------===// // Mips GPR size adjectives. // They are mutually exclusive. @@ -340,6 +344,10 @@ class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; list<Predicate> EncodingPredicates = [HasStdEnc]; } +class ISA_MIPS64R5 { + list<Predicate> InsnPredicates = [HasMips64r5]; + list<Predicate> EncodingPredicates = [HasStdEnc]; +} class ISA_MIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; list<Predicate> EncodingPredicates = [HasStdEnc]; @@ -351,6 +359,10 @@ class ISA_MIPS64R6 { class ISA_MICROMIPS { list<Predicate> EncodingPredicates = [InMicroMips]; } +class ISA_MICROMIPS32R5 { + list<Predicate> InsnPredicates = [HasMips32r5]; + list<Predicate> EncodingPredicates = [InMicroMips]; +} class ISA_MICROMIPS32R6 { list<Predicate> InsnPredicates = [HasMips32r6]; list<Predicate> EncodingPredicates = [InMicroMips]; @@ -449,6 +461,10 @@ class ASE_CRC { list <Predicate> ASEPredicate = [HasCRC]; } +class ASE_VIRT { + list <Predicate> ASEPredicate = [HasVirt]; +} + // 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 { @@ -1844,12 +1860,16 @@ class SCBase<string opstr, RegisterOperand RO> : class MFC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD, InstrItinClass itin> : InstSE<(outs RO:$rt), (ins RD:$rd, uimm3:$sel), - !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>; + !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> { + let BaseOpcode = asmstr; +} class MTC3OP<string asmstr, RegisterOperand RO, RegisterOperand RD, InstrItinClass itin> : InstSE<(outs RO:$rd), (ins RD:$rt, uimm3:$sel), - !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR>; + !strconcat(asmstr, "\t$rt, $rd, $sel"), [], itin, FrmFR> { + let BaseOpcode = asmstr; +} class TrapBase<Instruction RealInst> : PseudoSE<(outs), (ins), [(trap)], II_TRAP>, @@ -2329,14 +2349,14 @@ let AdditionalPredicates = [NotInMicroMips] in { } /// Move Control Registers From/To CPU Registers let AdditionalPredicates = [NotInMicroMips] in { - def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, MFC3OP_FM<0x10, 4>, - ISA_MIPS1; - def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, MFC3OP_FM<0x10, 0>, - ISA_MIPS1; - def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, MFC3OP_FM<0x12, 0>, - ISA_MIPS1; - def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, MFC3OP_FM<0x12, 4>, - ISA_MIPS1; + def MTC0 : MTC3OP<"mtc0", COP0Opnd, GPR32Opnd, II_MTC0>, + MFC3OP_FM<0x10, 4, 0>, ISA_MIPS1; + def MFC0 : MFC3OP<"mfc0", GPR32Opnd, COP0Opnd, II_MFC0>, + MFC3OP_FM<0x10, 0, 0>, ISA_MIPS1; + def MFC2 : MFC3OP<"mfc2", GPR32Opnd, COP2Opnd, II_MFC2>, + MFC3OP_FM<0x12, 0, 0>, ISA_MIPS1; + def MTC2 : MTC3OP<"mtc2", COP2Opnd, GPR32Opnd, II_MTC2>, + MFC3OP_FM<0x12, 4, 0>, ISA_MIPS1; } class Barrier<string asmstr, InstrItinClass itin = NoItinerary> : @@ -2502,6 +2522,38 @@ def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs, "mulou\t$rd, $rs, $rt">, ISA_MIPS1_NOT_32R6_64R6; +// Virtualization ASE +class HYPCALL_FT<string opstr> : + InstSE<(outs), (ins uimm10:$code_), + !strconcat(opstr, "\t$code_"), [], II_HYPCALL, FrmOther, opstr> { + let BaseOpcode = opstr; +} + +let AdditionalPredicates = [NotInMicroMips] in { + def MFGC0 : MMRel, MFC3OP<"mfgc0", GPR32Opnd, COP0Opnd, II_MFGC0>, + MFC3OP_FM<0x10, 3, 0>, ISA_MIPS32R5, ASE_VIRT; + def MTGC0 : MMRel, MTC3OP<"mtgc0", COP0Opnd, GPR32Opnd, II_MTGC0>, + MFC3OP_FM<0x10, 3, 2>, ISA_MIPS32R5, ASE_VIRT; + def MFHGC0 : MMRel, MFC3OP<"mfhgc0", GPR32Opnd, COP0Opnd, II_MFHGC0>, + MFC3OP_FM<0x10, 3, 4>, ISA_MIPS32R5, ASE_VIRT; + def MTHGC0 : MMRel, MTC3OP<"mthgc0", COP0Opnd, GPR32Opnd, II_MTHGC0>, + MFC3OP_FM<0x10, 3, 6>, ISA_MIPS32R5, ASE_VIRT; + def TLBGINV : MMRel, TLB<"tlbginv", II_TLBGINV>, COP0_TLB_FM<0b001011>, + ISA_MIPS32R5, ASE_VIRT; + def TLBGINVF : MMRel, TLB<"tlbginvf", II_TLBGINVF>, COP0_TLB_FM<0b001100>, + ISA_MIPS32R5, ASE_VIRT; + def TLBGP : MMRel, TLB<"tlbgp", II_TLBGP>, COP0_TLB_FM<0b010000>, + ISA_MIPS32R5, ASE_VIRT; + def TLBGR : MMRel, TLB<"tlbgr", II_TLBGR>, COP0_TLB_FM<0b001001>, + ISA_MIPS32R5, ASE_VIRT; + def TLBGWI : MMRel, TLB<"tlbgwi", II_TLBGWI>, COP0_TLB_FM<0b001010>, + ISA_MIPS32R5, ASE_VIRT; + def TLBGWR : MMRel, TLB<"tlbgwr", II_TLBGWR>, COP0_TLB_FM<0b001110>, + ISA_MIPS32R5, ASE_VIRT; + def HYPCALL : MMRel, HYPCALL_FT<"hypcall">, + HYPCALL_FM<0b101000>, ISA_MIPS32R5, ASE_VIRT; +} + //===----------------------------------------------------------------------===// // Instruction aliases //===----------------------------------------------------------------------===// @@ -2584,6 +2636,20 @@ let AdditionalPredicates = [NotInMicroMips] in { } def : MipsInstAlias<"mfc0 $rt, $rd", (MFC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>; def : MipsInstAlias<"mtc0 $rt, $rd", (MTC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>; +let AdditionalPredicates = [NotInMicroMips] in { + def : MipsInstAlias<"mfgc0 $rt, $rd", + (MFGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>, + ISA_MIPS32R5, ASE_VIRT; + def : MipsInstAlias<"mtgc0 $rt, $rd", + (MTGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>, + ISA_MIPS32R5, ASE_VIRT; + def : MipsInstAlias<"mfhgc0 $rt, $rd", + (MFHGC0 GPR32Opnd:$rt, COP0Opnd:$rd, 0), 0>, + ISA_MIPS32R5, ASE_VIRT; + def : MipsInstAlias<"mthgc0 $rt, $rd", + (MTHGC0 COP0Opnd:$rd, GPR32Opnd:$rt, 0), 0>, + ISA_MIPS32R5, ASE_VIRT; +} def : MipsInstAlias<"mfc2 $rt, $rd", (MFC2 GPR32Opnd:$rt, COP2Opnd:$rd, 0), 0>; def : MipsInstAlias<"mtc2 $rt, $rd", (MTC2 COP2Opnd:$rd, GPR32Opnd:$rt, 0), 0>; let AdditionalPredicates = [NotInMicroMips] in { @@ -2658,6 +2724,9 @@ def : MipsInstAlias<"mulou $rs, $rt", (MULOUMacro GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt), 0>, ISA_MIPS1_NOT_32R6_64R6; +let AdditionalPredicates = [NotInMicroMips] in + def : MipsInstAlias<"hypcall", (HYPCALL 0), 1>, ISA_MIPS32R5, ASE_VIRT; + //===----------------------------------------------------------------------===// // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Mips/MipsSchedule.td b/llvm/lib/Target/Mips/MipsSchedule.td index aedbed34192..e9f1cb7601c 100644 --- a/llvm/lib/Target/Mips/MipsSchedule.td +++ b/llvm/lib/Target/Mips/MipsSchedule.td @@ -92,8 +92,10 @@ def II_DIVU : InstrItinClass; def II_DIV_D : InstrItinClass; def II_DIV_S : InstrItinClass; def II_DMFC0 : InstrItinClass; +def II_DMFGC0 : InstrItinClass; def II_DMT : InstrItinClass; def II_DMTC0 : InstrItinClass; +def II_DMTGC0 : InstrItinClass; def II_DMFC1 : InstrItinClass; def II_DMTC1 : InstrItinClass; def II_DMOD : InstrItinClass; @@ -128,6 +130,7 @@ def II_EVPE : InstrItinClass; def II_EXT : InstrItinClass; // Any EXT instruction def II_FLOOR : InstrItinClass; def II_FORK : InstrItinClass; +def II_HYPCALL : InstrItinClass; def II_INS : InstrItinClass; // Any INS instruction def II_IndirectBranchPseudo : InstrItinClass; // Indirect branch pseudo. def II_J : InstrItinClass; @@ -233,6 +236,8 @@ def II_MFHC0 : InstrItinClass; def II_MFC1 : InstrItinClass; def II_MFHC1 : InstrItinClass; def II_MFC2 : InstrItinClass; +def II_MFGC0 : InstrItinClass; +def II_MFHGC0 : InstrItinClass; def II_MFHI_MFLO : InstrItinClass; // mfhi and mflo def II_MFTR : InstrItinClass; def II_MOD : InstrItinClass; @@ -263,6 +268,8 @@ def II_MTHC0 : InstrItinClass; def II_MTC1 : InstrItinClass; def II_MTHC1 : InstrItinClass; def II_MTC2 : InstrItinClass; +def II_MTGC0 : InstrItinClass; +def II_MTHGC0 : InstrItinClass; def II_MTHI_MTLO : InstrItinClass; // mthi and mtlo def II_MTTR : InstrItinClass; def II_MUL : InstrItinClass; @@ -354,6 +361,12 @@ def II_CACHEE : InstrItinClass; def II_PREFE : InstrItinClass; def II_LLE : InstrItinClass; def II_SCE : InstrItinClass; +def II_TLBGINV : InstrItinClass; +def II_TLBGINVF : InstrItinClass; +def II_TLBGP : InstrItinClass; +def II_TLBGR : InstrItinClass; +def II_TLBGWI : InstrItinClass; +def II_TLBGWR : InstrItinClass; def II_TLBINV : InstrItinClass; def II_TLBINVF : InstrItinClass; def II_WRPGPR : InstrItinClass; @@ -702,5 +715,18 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [ InstrItinData<II_CRC32CB , [InstrStage<1, [ALU]>]>, InstrItinData<II_CRC32CH , [InstrStage<1, [ALU]>]>, InstrItinData<II_CRC32CW , [InstrStage<1, [ALU]>]>, - InstrItinData<II_CRC32CD , [InstrStage<1, [ALU]>]> + InstrItinData<II_CRC32CD , [InstrStage<1, [ALU]>]>, + InstrItinData<II_MFGC0 , [InstrStage<2, [ALU]>]>, + InstrItinData<II_MTGC0 , [InstrStage<2, [ALU]>]>, + InstrItinData<II_MFHGC0 , [InstrStage<2, [ALU]>]>, + InstrItinData<II_MTHGC0 , [InstrStage<2, [ALU]>]>, + InstrItinData<II_HYPCALL , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBGINV , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBGINVF , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBGP , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBGR , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBWI , [InstrStage<2, [ALU]>]>, + InstrItinData<II_TLBWR , [InstrStage<2, [ALU]>]>, + InstrItinData<II_DMFGC0 , [InstrStage<2, [ALU]>]>, + InstrItinData<II_DMTGC0 , [InstrStage<2, [ALU]>]> ]>; diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index fd22b02c4fe..1cbffbf8b34 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -79,7 +79,8 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS, 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), HasCRC(false), - UseIndirectJumpsHazard(false), StackAlignOverride(StackAlignOverride), + HasVirt(false), UseIndirectJumpsHazard(false), + StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT), TSInfo(), InstrInfo( MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))), diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 5a8efcc4161..7aebfe1e74c 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -165,6 +165,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo { // HasCRC -- supports R6 CRC ASE bool HasCRC; + // HasVirt -- supports Virtualization ASE + bool HasVirt; + // Use hazard variants of the jump register instructions for indirect // function calls and jump tables. bool UseIndirectJumpsHazard; @@ -290,6 +293,7 @@ public: bool hasEVA() const { return HasEVA; } bool hasMT() const { return HasMT; } bool hasCRC() const { return HasCRC; } + bool hasVirt() const { return HasVirt; } bool useIndirectJumpsHazard() const { return UseIndirectJumpsHazard && hasMips32r2(); } diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index 0447436f499..f9714d2b439 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -44,6 +44,8 @@ public: virtual void emitDirectiveSetNoMt(); virtual void emitDirectiveSetCRC(); virtual void emitDirectiveSetNoCRC(); + virtual void emitDirectiveSetVirt(); + virtual void emitDirectiveSetNoVirt(); virtual void emitDirectiveSetAt(); virtual void emitDirectiveSetAtWithArg(unsigned RegNo); virtual void emitDirectiveSetNoAt(); @@ -107,6 +109,8 @@ public: virtual void emitDirectiveSetNoOddSPReg(); virtual void emitDirectiveModuleCRC(); virtual void emitDirectiveModuleNoCRC(); + virtual void emitDirectiveModuleVirt(); + virtual void emitDirectiveModuleNoVirt(); void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc, const MCSubtargetInfo *STI); @@ -219,6 +223,8 @@ public: void emitDirectiveSetNoMt() override; void emitDirectiveSetCRC() override; void emitDirectiveSetNoCRC() override; + void emitDirectiveSetVirt() override; + void emitDirectiveSetNoVirt() override; void emitDirectiveSetAt() override; void emitDirectiveSetAtWithArg(unsigned RegNo) override; void emitDirectiveSetNoAt() override; @@ -286,6 +292,8 @@ public: void emitDirectiveModuleMT() override; void emitDirectiveModuleCRC() override; void emitDirectiveModuleNoCRC() override; + void emitDirectiveModuleVirt() override; + void emitDirectiveModuleNoVirt() override; void emitDirectiveSetFp(MipsABIFlagsSection::FpABIKind Value) override; void emitDirectiveSetOddSPReg() override; void emitDirectiveSetNoOddSPReg() override; |

