diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -368,6 +368,7 @@ bool parseSetMsaDirective(); bool parseSetNoMsaDirective(); bool parseSetNoDspDirective(); + bool parseSetNoMips3DDirective(); bool parseSetReorderDirective(); bool parseSetNoReorderDirective(); bool parseSetMips16Directive(); @@ -6985,6 +6986,21 @@ return false; } +bool MipsAsmParser::parseSetNoMips3DDirective() { + MCAsmParser &Parser = getParser(); + Parser.Lex(); // Eat "nomips3d". + + // 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::FeatureMips3D, "mips3d"); + getTargetStreamer().emitDirectiveSetNoMips3D(); + return false; +} + bool MipsAsmParser::parseSetMips16Directive() { MCAsmParser &Parser = getParser(); Parser.Lex(); // Eat "mips16". @@ -7317,6 +7333,10 @@ switch (Feature) { default: llvm_unreachable("Unimplemented feature"); + case Mips::FeatureMips3D: + setFeatureBits(Mips::FeatureMips3D, "mips3d"); + getTargetStreamer().emitDirectiveSetMips3D(); + break; case Mips::FeatureDSP: setFeatureBits(Mips::FeatureDSP, "dsp"); getTargetStreamer().emitDirectiveSetDsp(); @@ -7732,6 +7752,10 @@ return parseSetFeature(Mips::FeatureDSPR2); if (IdVal == "nodsp") return parseSetNoDspDirective(); + if (IdVal == "mips3d") + return parseSetFeature(Mips::FeatureMips3D); + if (IdVal == "nomips3d") + return parseSetNoMips3DDirective(); if (IdVal == "msa") return parseSetMsaDirective(); if (IdVal == "nomsa") diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -109,6 +109,8 @@ void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetDspr2() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } +void MipsTargetStreamer::emitDirectiveSetMips3D() { forbidModuleDirective(); } +void MipsTargetStreamer::emitDirectiveSetNoMips3D() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} void MipsTargetStreamer::emitDirectiveCpLocal(unsigned RegNo) { // .cplocal $reg @@ -609,6 +611,16 @@ MipsTargetStreamer::emitDirectiveSetNoDsp(); } +void MipsTargetAsmStreamer::emitDirectiveSetMips3D() { + OS << "\t.set\tmips3d\n"; + MipsTargetStreamer::emitDirectiveSetMips3D(); +} + +void MipsTargetAsmStreamer::emitDirectiveSetNoMips3D() { + OS << "\t.set\tnomips3d\n"; + MipsTargetStreamer::emitDirectiveSetNoMips3D(); +} + void MipsTargetAsmStreamer::emitDirectiveSetPop() { OS << "\t.set\tpop\n"; MipsTargetStreamer::emitDirectiveSetPop(); diff --git a/llvm/lib/Target/Mips/Mips.td b/llvm/lib/Target/Mips/Mips.td --- a/llvm/lib/Target/Mips/Mips.td +++ b/llvm/lib/Target/Mips/Mips.td @@ -161,6 +161,8 @@ : SubtargetFeature<"dspr3", "HasDSPR3", "true", "Mips DSP-R3 ASE", [ FeatureDSP, FeatureDSPR2 ]>; +def FeatureMips3D : SubtargetFeature<"mips3d", "Has3D", "true", "Mips 3D ASE">; + def FeatureMSA : SubtargetFeature<"msa", "HasMSA", "true", "Mips MSA ASE">; def FeatureEVA : SubtargetFeature<"eva", "HasEVA", "true", "Mips EVA ASE">; diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td --- a/llvm/lib/Target/Mips/MipsInstrFPU.td +++ b/llvm/lib/Target/Mips/MipsInstrFPU.td @@ -72,6 +72,8 @@ AssemblerPredicate<(all_of (not FeatureSingleFloat))>; def IsNotSoftFloat : Predicate<"!Subtarget->useSoftFloat()">, AssemblerPredicate<(all_of (not FeatureSoftFloat))>; +def Mips3D : Predicate<"Subtarget->has3D()">, + AssemblerPredicate<(all_of FeatureMips3D)>; //===----------------------------------------------------------------------===// // Mips FGR size adjectives. @@ -477,6 +479,21 @@ } let DecoderNamespace = "MipsFP64" in { + let AdditionalPredicates = [Mips3D] in { + def ADDR_PS64 : ADDS_FT<"addr.ps", FGR64Opnd, II_ADDR_PS, 0>, + ADDS_FM<0x18, 22>, ISA_MIPS32R2_NOT_32R6_64R6, FGR_64; + def MULR_PS64 : ADDS_FT<"mulr.ps", FGR64Opnd, II_MULR_PS, 0>, + ADDS_FM<0x1a, 22>, ISA_MIPS32R2_NOT_32R6_64R6, FGR_64; + def CVT_PS_PW64 : ABSS_FT<"cvt.ps.pw", FGR64Opnd, FGR64Opnd, II_CVT>, + ABSS_FM<0x26, 20>, + ISA_MIPS32R2_NOT_32R6_64R6, FGR_64; + def CVT_PW_PS64 : ABSS_FT<"cvt.pw.ps", FGR64Opnd, FGR64Opnd, II_CVT>, + ABSS_FM<0x24, 22>, + ISA_MIPS32R2_NOT_32R6_64R6, FGR_64; + } +} + +let DecoderNamespace = "MipsFP64" in { let AdditionalPredicates = [NotInMicroMips] in { def CVT_S_L : ABSS_FT<"cvt.s.l", FGR32Opnd, FGR64Opnd, II_CVT>, ABSS_FM<0x20, 21>, INSN_MIPS3_32R2, FGR_64; diff --git a/llvm/lib/Target/Mips/MipsSchedule.td b/llvm/lib/Target/Mips/MipsSchedule.td --- a/llvm/lib/Target/Mips/MipsSchedule.td +++ b/llvm/lib/Target/Mips/MipsSchedule.td @@ -27,6 +27,7 @@ def II_ADDU : InstrItinClass; def II_ADD_D : InstrItinClass; def II_ADD_S : InstrItinClass; +def II_ADDR_PS : InstrItinClass; def II_ALIGN : InstrItinClass; def II_AND : InstrItinClass; def II_ANDI : InstrItinClass; @@ -278,6 +279,7 @@ def II_MUH : InstrItinClass; def II_MUHU : InstrItinClass; def II_MULU : InstrItinClass; +def II_MULR_PS : InstrItinClass; def II_MULT : InstrItinClass; def II_MULTU : InstrItinClass; def II_MUL_D : InstrItinClass; diff --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td --- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td +++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td @@ -822,15 +822,17 @@ // madd.d, msub.dm mul.d, mul.ps, nmadd.d, nmsub.d, ceil.[wl].[sd], cvt.d.[sw], // cvt.s.[dw], cvt.w.[sd], cvt.[sw].ps, round.[lw].[ds], floor.[lw].ds, // trunc.w.[ds], trunc.w.ps, -def : InstRW<[GenericWriteFPUL], (instrs CEIL_L_D64, CEIL_L_S, CEIL_W_D32, +def : InstRW<[GenericWriteFPUL], (instrs ADDR_PS64, + CEIL_L_D64, CEIL_L_S, CEIL_W_D32, CEIL_W_D64, CEIL_W_S, CVT_D32_S, CVT_D32_W, CVT_D64_L, CVT_D64_S, CVT_D64_W, CVT_L_D64, CVT_L_S, CVT_S_D32, CVT_S_D64, CVT_S_L, CVT_S_W, CVT_W_D32, CVT_W_D64, CVT_W_S, CVT_PS_S64, CVT_S_PL64, CVT_S_PU64, + CVT_PS_PW64, CVT_PW_PS64, FLOOR_L_D64, FLOOR_L_S, FLOOR_W_D32, FLOOR_W_D64, FLOOR_W_S, FMUL_D32, FMUL_D64, - MADD_D32, MADD_D64, MSUB_D32, MSUB_D64, + MADD_D32, MADD_D64, MSUB_D32, MSUB_D64, MULR_PS64, NMADD_D32, NMADD_D64, NMSUB_D32, NMSUB_D64, PLL_PS64, PLU_PS64, PUL_PS64, PUU_PS64, ROUND_L_D64, ROUND_L_S, ROUND_W_D32, diff --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td --- a/llvm/lib/Target/Mips/MipsScheduleP5600.td +++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td @@ -458,6 +458,8 @@ def : InstRW<[P5600WriteFPUL], (instregex "^FCMP_(S32|D32|D64)$")>; def : InstRW<[P5600WriteFPUL], (instregex "^PseudoCVT_(S|D32|D64)_(L|W)$")>; def : InstRW<[P5600WriteFPUL], (instrs PLL_PS64, PLU_PS64, PUL_PS64, PUU_PS64)>; +def : InstRW<[P5600WriteFPUL], (instrs ADDR_PS64, MULR_PS64)>; +def : InstRW<[P5600WriteFPUL], (instrs CVT_PS_PW64, CVT_PW_PS64)>; // div.[ds], div.ps def : InstRW<[P5600WriteFPUDivS], (instrs FDIV_S)>; diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -149,6 +149,9 @@ // HasDSP, HasDSPR2, HasDSPR3 -- supports DSP ASE. bool HasDSP, HasDSPR2, HasDSPR3; + // Has3D -- Supports Mips3D ASE. + bool Has3D; + // Allow mixed Mips16 and Mips32 in one source file bool AllowMixed16_32; diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -84,6 +84,8 @@ virtual void emitDirectiveSetDsp(); virtual void emitDirectiveSetDspr2(); virtual void emitDirectiveSetNoDsp(); + virtual void emitDirectiveSetMips3D(); + virtual void emitDirectiveSetNoMips3D(); virtual void emitDirectiveSetPop(); virtual void emitDirectiveSetPush(); virtual void emitDirectiveSetSoftFloat(); @@ -263,6 +265,8 @@ void emitDirectiveSetDsp() override; void emitDirectiveSetDspr2() override; void emitDirectiveSetNoDsp() override; + void emitDirectiveSetMips3D() override; + void emitDirectiveSetNoMips3D() override; void emitDirectiveSetPop() override; void emitDirectiveSetPush() override; void emitDirectiveSetSoftFloat() override; diff --git a/llvm/test/MC/Mips/mips3d/valid.s b/llvm/test/MC/Mips/mips3d/valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/Mips/mips3d/valid.s @@ -0,0 +1,7 @@ +# RUN: llvm-mc -show-encoding -triple=mips-unknown-unknown -mcpu=mips64r2 -mattr=mips3d %s | FileCheck %s +# + .set noat + addr.ps $f7, $f11, $f3 # CHECK: addr.ps $f7, $f11, $f3 # encoding: [0x46,0xc3,0x59,0xd8] + cvt.ps.pw $f3, $f18 # CHECK: cvt.ps.pw $f3, $f18 # encoding: [0x46,0x80,0x90,0xe6] + cvt.pw.ps $f5, $f20 # CHECK: cvt.pw.ps $f5, $f20 # encoding: [0x46,0xc0,0xa1,0x64] + mulr.ps $f23, $f5, $f1 # CHECK: mulr.ps $f23, $f5, $f1 # encoding: [0x46,0xc1,0x2d,0xda] diff --git a/llvm/test/MC/Mips/mips64r6/invalid-mips5-wrong-error.s b/llvm/test/MC/Mips/mips64r6/invalid-mips5-wrong-error.s --- a/llvm/test/MC/Mips/mips64r6/invalid-mips5-wrong-error.s +++ b/llvm/test/MC/Mips/mips64r6/invalid-mips5-wrong-error.s @@ -28,7 +28,6 @@ c.ule.ps $fcc6,$f17,$f3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction c.ult.ps $fcc7,$f14,$f0 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction c.un.ps $fcc4,$f2,$f26 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction - cvt.ps.pw $f3,$f18 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction madd.ps $f22,$f3,$f14,$f3 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction mov.ps $f22,$f17 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction movf.ps $f10,$f28,$fcc6 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: unknown instruction diff --git a/llvm/test/MC/Mips/mips64r6/invalid-mips5.s b/llvm/test/MC/Mips/mips64r6/invalid-mips5.s --- a/llvm/test/MC/Mips/mips64r6/invalid-mips5.s +++ b/llvm/test/MC/Mips/mips64r6/invalid-mips5.s @@ -8,6 +8,8 @@ bgezal $0, 21100 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled bgezal $6, 21100 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled bltzal $6, 21100 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + cvt.ps.pw $f3,$f18 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + cvt.pw.ps $f1, $f2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled luxc1 $f19,$s6($s5) # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled pll.ps $f25,$f9,$f30 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled plu.ps $f1,$f26,$f29 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled