diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsLegalizerInfo.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsLegalizerInfo.cpp | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp index bb4a1d902d75..9645aa24dc05 100644 --- a/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp +++ b/llvm/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -13,6 +13,7 @@ #include "MipsLegalizerInfo.h" #include "MipsTargetMachine.h" #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" +#include "llvm/IR/IntrinsicsMips.h" using namespace llvm; @@ -61,11 +62,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { const LLT v2s64 = LLT::vector(2, 64); const LLT p0 = LLT::pointer(0, 32); - getActionDefinitionsBuilder({G_SUB, G_MUL}) - .legalFor({s32}) - .clampScalar(0, s32, s32); - - getActionDefinitionsBuilder(G_ADD) + getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL}) .legalIf([=, &ST](const LegalityQuery &Query) { if (CheckTyN(0, Query, {s32})) return true; @@ -145,8 +142,14 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { .legalFor({s32}) .clampScalar(0, s32, s32); - getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UREM, G_UDIV}) - .legalFor({s32}) + getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UDIV, G_UREM}) + .legalIf([=, &ST](const LegalityQuery &Query) { + if (CheckTyN(0, Query, {s32})) + return true; + if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64})) + return true; + return false; + }) .minScalar(0, s32) .libcallFor({s64}); @@ -164,7 +167,7 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { .legalFor({s32}) .clampScalar(0, s32, s32); - getActionDefinitionsBuilder({G_GEP, G_INTTOPTR}) + getActionDefinitionsBuilder({G_PTR_ADD, G_INTTOPTR}) .legalFor({{p0, s32}}); getActionDefinitionsBuilder(G_PTRTOINT) @@ -182,12 +185,35 @@ MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) { getActionDefinitionsBuilder(G_VASTART) .legalFor({p0}); + getActionDefinitionsBuilder(G_BSWAP) + .legalIf([=, &ST](const LegalityQuery &Query) { + if (ST.hasMips32r2() && CheckTyN(0, Query, {s32})) + return true; + return false; + }) + .lowerIf([=, &ST](const LegalityQuery &Query) { + if (!ST.hasMips32r2() && CheckTyN(0, Query, {s32})) + return true; + return false; + }) + .maxScalar(0, s32); + + getActionDefinitionsBuilder(G_BITREVERSE) + .lowerFor({s32}) + .maxScalar(0, s32); + // FP instructions getActionDefinitionsBuilder(G_FCONSTANT) .legalFor({s32, s64}); getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT}) - .legalFor({s32, s64}); + .legalIf([=, &ST](const LegalityQuery &Query) { + if (CheckTyN(0, Query, {s32, s64})) + return true; + if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64})) + return true; + return false; + }); getActionDefinitionsBuilder(G_FCMP) .legalFor({{s32, s32}, {s32, s64}}) @@ -315,6 +341,17 @@ static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode, return true; } +static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode, + MachineIRBuilder &MIRBuilder, + const MipsSubtarget &ST) { + assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA."); + MIRBuilder.buildInstr(Opcode) + .add(MI.getOperand(0)) + .add(MI.getOperand(2)); + MI.eraseFromParent(); + return true; +} + bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const { @@ -364,6 +401,64 @@ bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI, return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_W, MIRBuilder, ST); case Intrinsic::mips_addvi_d: return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_D, MIRBuilder, ST); + case Intrinsic::mips_subv_b: + case Intrinsic::mips_subv_h: + case Intrinsic::mips_subv_w: + case Intrinsic::mips_subv_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SUB, MIRBuilder, ST); + case Intrinsic::mips_subvi_b: + return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_B, MIRBuilder, ST); + case Intrinsic::mips_subvi_h: + return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_H, MIRBuilder, ST); + case Intrinsic::mips_subvi_w: + return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_W, MIRBuilder, ST); + case Intrinsic::mips_subvi_d: + return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_D, MIRBuilder, ST); + case Intrinsic::mips_mulv_b: + case Intrinsic::mips_mulv_h: + case Intrinsic::mips_mulv_w: + case Intrinsic::mips_mulv_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_MUL, MIRBuilder, ST); + case Intrinsic::mips_div_s_b: + case Intrinsic::mips_div_s_h: + case Intrinsic::mips_div_s_w: + case Intrinsic::mips_div_s_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SDIV, MIRBuilder, ST); + case Intrinsic::mips_mod_s_b: + case Intrinsic::mips_mod_s_h: + case Intrinsic::mips_mod_s_w: + case Intrinsic::mips_mod_s_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SREM, MIRBuilder, ST); + case Intrinsic::mips_div_u_b: + case Intrinsic::mips_div_u_h: + case Intrinsic::mips_div_u_w: + case Intrinsic::mips_div_u_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UDIV, MIRBuilder, ST); + case Intrinsic::mips_mod_u_b: + case Intrinsic::mips_mod_u_h: + case Intrinsic::mips_mod_u_w: + case Intrinsic::mips_mod_u_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UREM, MIRBuilder, ST); + case Intrinsic::mips_fadd_w: + case Intrinsic::mips_fadd_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FADD, MIRBuilder, ST); + case Intrinsic::mips_fsub_w: + case Intrinsic::mips_fsub_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FSUB, MIRBuilder, ST); + case Intrinsic::mips_fmul_w: + case Intrinsic::mips_fmul_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FMUL, MIRBuilder, ST); + case Intrinsic::mips_fdiv_w: + case Intrinsic::mips_fdiv_d: + return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FDIV, MIRBuilder, ST); + case Intrinsic::mips_fmax_a_w: + return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_W, MIRBuilder, ST); + case Intrinsic::mips_fmax_a_d: + return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_D, MIRBuilder, ST); + case Intrinsic::mips_fsqrt_w: + return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST); + case Intrinsic::mips_fsqrt_d: + return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST); default: break; } |