diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td | 351 |
1 files changed, 232 insertions, 119 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td index 82c51a6..285bb14 100644 --- a/contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td +++ b/contrib/llvm/lib/Target/Mips/MipsMSAInstrInfo.td @@ -27,6 +27,9 @@ def SDT_SHF : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, SDTCisVT<1, i32>, SDTCisSameAs<0, 2>]>; def SDT_ILV : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>; +def SDT_INSVE : SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCisSameAs<0, 1>, + SDTCisVT<2, i32>, SDTCisSameAs<0, 3>, + SDTCisVT<4, i32>]>; def MipsVAllNonZero : SDNode<"MipsISD::VALL_NONZERO", SDT_MipsVecCond>; def MipsVAnyNonZero : SDNode<"MipsISD::VANY_NONZERO", SDT_MipsVecCond>; @@ -50,6 +53,7 @@ def MipsILVL : SDNode<"MipsISD::ILVL", SDT_ILV>; def MipsILVR : SDNode<"MipsISD::ILVR", SDT_ILV>; def MipsPCKEV : SDNode<"MipsISD::PCKEV", SDT_ILV>; def MipsPCKOD : SDNode<"MipsISD::PCKOD", SDT_ILV>; +def MipsINSVE : SDNode<"MipsISD::INSVE", SDT_INSVE>; def vsetcc : SDNode<"ISD::SETCC", SDT_VSetCC>; def vfsetcc : SDNode<"ISD::SETCC", SDT_VFSetCC>; @@ -61,15 +65,11 @@ def MipsVExtractZExt : SDNode<"MipsISD::VEXTRACT_ZEXT_ELT", // Operands -def uimm2 : Operand<i32> { - let PrintMethod = "printUnsignedImm"; -} - // The immediate of an LSA instruction needs special handling // as the encoded value should be subtracted by one. def uimm2LSAAsmOperand : AsmOperandClass { let Name = "LSAImm"; - let ParserMethod = "parseLSAImm"; + let ParserMethod = "ParseLSAImm"; let RenderMethod = "addImmOperands"; } @@ -80,10 +80,6 @@ def LSAImm : Operand<i32> { let ParserMatchClass = uimm2LSAAsmOperand; } -def uimm3 : Operand<i32> { - let PrintMethod = "printUnsignedImm8"; -} - def uimm4 : Operand<i32> { let PrintMethod = "printUnsignedImm8"; } @@ -94,8 +90,6 @@ def uimm8 : Operand<i32> { def simm5 : Operand<i32>; -def simm10 : Operand<i32>; - def vsplat_uimm1 : Operand<vAny> { let PrintMethod = "printUnsignedImm8"; } @@ -137,6 +131,8 @@ def vextract_sext_i16 : PatFrag<(ops node:$vec, node:$idx), (MipsVExtractSExt node:$vec, node:$idx, i16)>; def vextract_sext_i32 : PatFrag<(ops node:$vec, node:$idx), (MipsVExtractSExt node:$vec, node:$idx, i32)>; +def vextract_sext_i64 : PatFrag<(ops node:$vec, node:$idx), + (MipsVExtractSExt node:$vec, node:$idx, i64)>; def vextract_zext_i8 : PatFrag<(ops node:$vec, node:$idx), (MipsVExtractZExt node:$vec, node:$idx, i8)>; @@ -144,6 +140,8 @@ def vextract_zext_i16 : PatFrag<(ops node:$vec, node:$idx), (MipsVExtractZExt node:$vec, node:$idx, i16)>; def vextract_zext_i32 : PatFrag<(ops node:$vec, node:$idx), (MipsVExtractZExt node:$vec, node:$idx, i32)>; +def vextract_zext_i64 : PatFrag<(ops node:$vec, node:$idx), + (MipsVExtractZExt node:$vec, node:$idx, i64)>; def vinsert_v16i8 : PatFrag<(ops node:$vec, node:$val, node:$idx), (v16i8 (vector_insert node:$vec, node:$val, node:$idx))>; @@ -151,6 +149,17 @@ def vinsert_v8i16 : PatFrag<(ops node:$vec, node:$val, node:$idx), (v8i16 (vector_insert node:$vec, node:$val, node:$idx))>; def vinsert_v4i32 : PatFrag<(ops node:$vec, node:$val, node:$idx), (v4i32 (vector_insert node:$vec, node:$val, node:$idx))>; +def vinsert_v2i64 : PatFrag<(ops node:$vec, node:$val, node:$idx), + (v2i64 (vector_insert node:$vec, node:$val, node:$idx))>; + +def insve_v16i8 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), + (v16i8 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; +def insve_v8i16 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), + (v8i16 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; +def insve_v4i32 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), + (v4i32 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; +def insve_v2i64 : PatFrag<(ops node:$v1, node:$i1, node:$v2, node:$i2), + (v2i64 (MipsINSVE node:$v1, node:$i1, node:$v2, node:$i2))>; class vfsetcc_type<ValueType ResTy, ValueType OpTy, CondCode CC> : PatFrag<(ops node:$lhs, node:$rhs), @@ -232,7 +241,7 @@ def vsplati32 : PatFrag<(ops node:$e0), (v4i32 (build_vector node:$e0, node:$e0, node:$e0, node:$e0))>; def vsplati64 : PatFrag<(ops node:$e0), - (v2i64 (build_vector:$v0 node:$e0, node:$e0))>; + (v2i64 (build_vector node:$e0, node:$e0))>; def vsplatf32 : PatFrag<(ops node:$e0), (v4f32 (build_vector node:$e0, node:$e0, node:$e0, node:$e0))>; @@ -614,10 +623,12 @@ class CLTI_U_D_ENC : MSA_I5_FMT<0b011, 0b11, 0b000111>; class COPY_S_B_ENC : MSA_ELM_COPY_B_FMT<0b0010, 0b011001>; class COPY_S_H_ENC : MSA_ELM_COPY_H_FMT<0b0010, 0b011001>; class COPY_S_W_ENC : MSA_ELM_COPY_W_FMT<0b0010, 0b011001>; +class COPY_S_D_ENC : MSA_ELM_COPY_D_FMT<0b0010, 0b011001>; class COPY_U_B_ENC : MSA_ELM_COPY_B_FMT<0b0011, 0b011001>; class COPY_U_H_ENC : MSA_ELM_COPY_H_FMT<0b0011, 0b011001>; class COPY_U_W_ENC : MSA_ELM_COPY_W_FMT<0b0011, 0b011001>; +class COPY_U_D_ENC : MSA_ELM_COPY_D_FMT<0b0011, 0b011001>; class CTCMSA_ENC : MSA_ELM_CTCMSA_FMT<0b0000111110, 0b011001>; @@ -724,6 +735,7 @@ class FFQR_D_ENC : MSA_2RF_FMT<0b110011011, 0b1, 0b011110>; class FILL_B_ENC : MSA_2R_FILL_FMT<0b11000000, 0b00, 0b011110>; class FILL_H_ENC : MSA_2R_FILL_FMT<0b11000000, 0b01, 0b011110>; class FILL_W_ENC : MSA_2R_FILL_FMT<0b11000000, 0b10, 0b011110>; +class FILL_D_ENC : MSA_2R_FILL_D_FMT<0b11000000, 0b11, 0b011110>; class FLOG2_W_ENC : MSA_2RF_FMT<0b110010111, 0b0, 0b011110>; class FLOG2_D_ENC : MSA_2RF_FMT<0b110010111, 0b1, 0b011110>; @@ -851,6 +863,7 @@ class ILVR_D_ENC : MSA_3R_FMT<0b101, 0b11, 0b010100>; class INSERT_B_ENC : MSA_ELM_INSERT_B_FMT<0b0100, 0b011001>; class INSERT_H_ENC : MSA_ELM_INSERT_H_FMT<0b0100, 0b011001>; class INSERT_W_ENC : MSA_ELM_INSERT_W_FMT<0b0100, 0b011001>; +class INSERT_D_ENC : MSA_ELM_INSERT_D_FMT<0b0100, 0b011001>; class INSVE_B_ENC : MSA_ELM_B_FMT<0b0101, 0b011001>; class INSVE_H_ENC : MSA_ELM_H_FMT<0b0101, 0b011001>; @@ -868,6 +881,7 @@ class LDI_W_ENC : MSA_I10_FMT<0b110, 0b10, 0b000111>; class LDI_D_ENC : MSA_I10_FMT<0b110, 0b11, 0b000111>; class LSA_ENC : SPECIAL_LSA_FMT<0b000101>; +class DLSA_ENC : SPECIAL_DLSA_FMT<0b010101>; class MADD_Q_H_ENC : MSA_3RF_FMT<0b0101, 0b0, 0b011100>; class MADD_Q_W_ENC : MSA_3RF_FMT<0b0101, 0b1, 0b011100>; @@ -1221,8 +1235,12 @@ class MSA_BIT_BINSXI_DESC_BASE<string instr_asm, ValueType Ty, dag OutOperandList = (outs ROWD:$wd); dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, vsplat_uimm8:$m); string AsmString = !strconcat(instr_asm, "\t$wd, $ws, $m"); - list<dag> Pattern = [(set ROWD:$wd, (vselect (Ty Mask:$m), (Ty ROWD:$wd_in), - ROWS:$ws))]; + // Note that binsxi and vselect treat the condition operand the opposite + // way to each other. + // (vselect cond, if_set, if_clear) + // (BSEL_V cond, if_clear, if_set) + list<dag> Pattern = [(set ROWD:$wd, (vselect (Ty Mask:$m), (Ty ROWD:$ws), + ROWS:$wd_in))]; InstrItinClass Itinerary = itin; string Constraints = "$wd = $wd_in"; } @@ -1261,20 +1279,22 @@ class MSA_COPY_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass Itinerary = itin; } -class MSA_ELM_DESC_BASE<string instr_asm, SDPatternOperator OpNode, - RegisterOperand ROWD, RegisterOperand ROWS = ROWD, - InstrItinClass itin = NoItinerary> { +class MSA_ELM_SLD_DESC_BASE<string instr_asm, SDPatternOperator OpNode, + RegisterOperand ROWD, RegisterOperand ROWS = ROWD, + InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWS:$ws, uimm4:$n); + dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, uimm4:$n); string AsmString = !strconcat(instr_asm, "\t$wd, $ws[$n]"); - list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, immZExt4:$n))]; + list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, ROWS:$ws, + immZExt4:$n))]; + string Constraints = "$wd = $wd_in"; InstrItinClass Itinerary = itin; } class MSA_COPY_PSEUDO_BASE<SDPatternOperator OpNode, ValueType VecTy, RegisterClass RCD, RegisterClass RCWS> : - MipsPseudo<(outs RCD:$wd), (ins RCWS:$ws, uimm4:$n), - [(set RCD:$wd, (OpNode (VecTy RCWS:$ws), immZExt4:$n))]> { + MSAPseudo<(outs RCD:$wd), (ins RCWS:$ws, uimm4:$n), + [(set RCD:$wd, (OpNode (VecTy RCWS:$ws), immZExt4:$n))]> { bit usesCustomInserter = 1; } @@ -1300,17 +1320,6 @@ class MSA_I8_DESC_BASE<string instr_asm, SDPatternOperator OpNode, InstrItinClass Itinerary = itin; } -// This class is deprecated and will be removed in the next few patches -class MSA_I8_X_DESC_BASE<string instr_asm, SDPatternOperator OpNode, - RegisterOperand ROWD, RegisterOperand ROWS = ROWD, - InstrItinClass itin = NoItinerary> { - dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWS:$ws, uimm8:$u8); - string AsmString = !strconcat(instr_asm, "\t$wd, $ws, $u8"); - list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, immZExt8:$u8))]; - InstrItinClass Itinerary = itin; -} - class MSA_I8_SHF_DESC_BASE<string instr_asm, RegisterOperand ROWD, RegisterOperand ROWS = ROWD, InstrItinClass itin = NoItinerary> { @@ -1355,8 +1364,8 @@ class MSA_2R_FILL_DESC_BASE<string instr_asm, ValueType VT, class MSA_2R_FILL_PSEUDO_BASE<ValueType VT, SDPatternOperator OpNode, RegisterClass RCWD, RegisterClass RCWS = RCWD> : - MipsPseudo<(outs RCWD:$wd), (ins RCWS:$fs), - [(set RCWD:$wd, (OpNode RCWS:$fs))]> { + MSAPseudo<(outs RCWD:$wd), (ins RCWS:$fs), + [(set RCWD:$wd, (OpNode RCWS:$fs))]> { let usesCustomInserter = 1; } @@ -1398,9 +1407,9 @@ class MSA_3R_SPLAT_DESC_BASE<string instr_asm, SDPatternOperator OpNode, RegisterOperand ROWD, RegisterOperand ROWS = ROWD, InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWS:$ws, GPR32:$rt); + dag InOperandList = (ins ROWS:$ws, GPR32Opnd:$rt); string AsmString = !strconcat(instr_asm, "\t$wd, $ws[$rt]"); - list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32:$rt))]; + list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32Opnd:$rt))]; InstrItinClass Itinerary = itin; } @@ -1421,10 +1430,12 @@ class MSA_3R_SLD_DESC_BASE<string instr_asm, SDPatternOperator OpNode, RegisterOperand ROWD, RegisterOperand ROWS = ROWD, InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWS:$ws, GPR32:$rt); + dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, GPR32Opnd:$rt); string AsmString = !strconcat(instr_asm, "\t$wd, $ws[$rt]"); - list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWS:$ws, GPR32:$rt))]; + list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, ROWS:$ws, + GPR32Opnd:$rt))]; InstrItinClass Itinerary = itin; + string Constraints = "$wd = $wd_in"; } class MSA_3R_4R_DESC_BASE<string instr_asm, SDPatternOperator OpNode, @@ -1434,8 +1445,8 @@ class MSA_3R_4R_DESC_BASE<string instr_asm, SDPatternOperator OpNode, dag OutOperandList = (outs ROWD:$wd); dag InOperandList = (ins ROWD:$wd_in, ROWS:$ws, ROWT:$wt); string AsmString = !strconcat(instr_asm, "\t$wd, $ws, $wt"); - list<dag> Pattern = [(set ROWD:$wd, - (OpNode ROWD:$wd_in, ROWS:$ws, ROWT:$wt))]; + list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, ROWS:$ws, + ROWT:$wt))]; InstrItinClass Itinerary = itin; string Constraints = "$wd = $wd_in"; } @@ -1479,22 +1490,32 @@ class MSA_INSERT_DESC_BASE<string instr_asm, SDPatternOperator OpNode, class MSA_INSERT_PSEUDO_BASE<SDPatternOperator OpNode, ValueType Ty, RegisterOperand ROWD, RegisterOperand ROFS> : - MipsPseudo<(outs ROWD:$wd), (ins ROWD:$wd_in, uimm6:$n, ROFS:$fs), - [(set ROWD:$wd, (OpNode (Ty ROWD:$wd_in), ROFS:$fs, + MSAPseudo<(outs ROWD:$wd), (ins ROWD:$wd_in, uimm6:$n, ROFS:$fs), + [(set ROWD:$wd, (OpNode (Ty ROWD:$wd_in), ROFS:$fs, immZExt6:$n))]> { bit usesCustomInserter = 1; string Constraints = "$wd = $wd_in"; } +class MSA_INSERT_VIDX_PSEUDO_BASE<SDPatternOperator OpNode, ValueType Ty, + RegisterOperand ROWD, RegisterOperand ROFS> : + MSAPseudo<(outs ROWD:$wd), (ins ROWD:$wd_in, GPR32Opnd:$n, ROFS:$fs), + [(set ROWD:$wd, (OpNode (Ty ROWD:$wd_in), ROFS:$fs, + GPR32Opnd:$n))]> { + bit usesCustomInserter = 1; + string Constraints = "$wd = $wd_in"; +} + class MSA_INSVE_DESC_BASE<string instr_asm, SDPatternOperator OpNode, RegisterOperand ROWD, RegisterOperand ROWS = ROWD, InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs ROWD:$wd); - dag InOperandList = (ins ROWD:$wd_in, uimm6:$n, ROWS:$ws); - string AsmString = !strconcat(instr_asm, "\t$wd[$n], $ws[0]"); + dag InOperandList = (ins ROWD:$wd_in, uimm6:$n, ROWS:$ws, uimmz:$n2); + string AsmString = !strconcat(instr_asm, "\t$wd[$n], $ws[$n2]"); list<dag> Pattern = [(set ROWD:$wd, (OpNode ROWD:$wd_in, immZExt6:$n, - ROWS:$ws))]; + ROWS:$ws, + immz:$n2))]; InstrItinClass Itinerary = itin; string Constraints = "$wd = $wd_in"; } @@ -1525,8 +1546,8 @@ class MSA_ELM_SPLAT_DESC_BASE<string instr_asm, SplatComplexPattern SplatImm, class MSA_VEC_PSEUDO_BASE<SDPatternOperator OpNode, RegisterOperand ROWD, RegisterOperand ROWS = ROWD, RegisterOperand ROWT = ROWD> : - MipsPseudo<(outs ROWD:$wd), (ins ROWS:$ws, ROWT:$wt), - [(set ROWD:$wd, (OpNode ROWS:$ws, ROWT:$wt))]>; + MSAPseudo<(outs ROWD:$wd), (ins ROWS:$ws, ROWT:$wt), + [(set ROWD:$wd, (OpNode ROWS:$ws, ROWT:$wt))]>; class ADD_A_B_DESC : MSA_3R_DESC_BASE<"add_a.b", int_mips_add_a_b, MSA128BOpnd>, IsCommutable; @@ -1735,10 +1756,14 @@ class BNEG_H_DESC : MSA_3R_DESC_BASE<"bneg.h", vbneg_h, MSA128HOpnd>; class BNEG_W_DESC : MSA_3R_DESC_BASE<"bneg.w", vbneg_w, MSA128WOpnd>; class BNEG_D_DESC : MSA_3R_DESC_BASE<"bneg.d", vbneg_d, MSA128DOpnd>; -class BNEGI_B_DESC : MSA_BIT_B_DESC_BASE<"bnegi.b", xor, vsplat_uimm_pow2, MSA128BOpnd>; -class BNEGI_H_DESC : MSA_BIT_H_DESC_BASE<"bnegi.h", xor, vsplat_uimm_pow2, MSA128HOpnd>; -class BNEGI_W_DESC : MSA_BIT_W_DESC_BASE<"bnegi.w", xor, vsplat_uimm_pow2, MSA128WOpnd>; -class BNEGI_D_DESC : MSA_BIT_D_DESC_BASE<"bnegi.d", xor, vsplat_uimm_pow2, MSA128DOpnd>; +class BNEGI_B_DESC : MSA_BIT_B_DESC_BASE<"bnegi.b", xor, vsplat_uimm_pow2, + MSA128BOpnd>; +class BNEGI_H_DESC : MSA_BIT_H_DESC_BASE<"bnegi.h", xor, vsplat_uimm_pow2, + MSA128HOpnd>; +class BNEGI_W_DESC : MSA_BIT_W_DESC_BASE<"bnegi.w", xor, vsplat_uimm_pow2, + MSA128WOpnd>; +class BNEGI_D_DESC : MSA_BIT_D_DESC_BASE<"bnegi.d", xor, vsplat_uimm_pow2, + MSA128DOpnd>; class BNZ_B_DESC : MSA_CBRANCH_DESC_BASE<"bnz.b", MSA128BOpnd>; class BNZ_H_DESC : MSA_CBRANCH_DESC_BASE<"bnz.h", MSA128HOpnd>; @@ -1752,9 +1777,13 @@ class BSEL_V_DESC { dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, MSA128BOpnd:$wt); string AsmString = "bsel.v\t$wd, $ws, $wt"; + // Note that vselect and BSEL_V treat the condition operand the opposite way + // from each other. + // (vselect cond, if_set, if_clear) + // (BSEL_V cond, if_clear, if_set) list<dag> Pattern = [(set MSA128BOpnd:$wd, - (vselect MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, - MSA128BOpnd:$wt))]; + (vselect MSA128BOpnd:$wd_in, MSA128BOpnd:$wt, + MSA128BOpnd:$ws))]; InstrItinClass Itinerary = NoItinerary; string Constraints = "$wd = $wd_in"; } @@ -1764,9 +1793,13 @@ class BSELI_B_DESC { dag InOperandList = (ins MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, vsplat_uimm8:$u8); string AsmString = "bseli.b\t$wd, $ws, $u8"; + // Note that vselect and BSEL_V treat the condition operand the opposite way + // from each other. + // (vselect cond, if_set, if_clear) + // (BSEL_V cond, if_clear, if_set) list<dag> Pattern = [(set MSA128BOpnd:$wd, (vselect MSA128BOpnd:$wd_in, - MSA128BOpnd:$ws, - vsplati8_uimm8:$u8))]; + vsplati8_uimm8:$u8, + MSA128BOpnd:$ws))]; InstrItinClass Itinerary = NoItinerary; string Constraints = "$wd = $wd_in"; } @@ -1880,6 +1913,8 @@ class COPY_S_H_DESC : MSA_COPY_DESC_BASE<"copy_s.h", vextract_sext_i16, v8i16, GPR32Opnd, MSA128HOpnd>; class COPY_S_W_DESC : MSA_COPY_DESC_BASE<"copy_s.w", vextract_sext_i32, v4i32, GPR32Opnd, MSA128WOpnd>; +class COPY_S_D_DESC : MSA_COPY_DESC_BASE<"copy_s.d", vextract_sext_i64, v2i64, + GPR64Opnd, MSA128DOpnd>; class COPY_U_B_DESC : MSA_COPY_DESC_BASE<"copy_u.b", vextract_zext_i8, v16i8, GPR32Opnd, MSA128BOpnd>; @@ -1887,6 +1922,8 @@ class COPY_U_H_DESC : MSA_COPY_DESC_BASE<"copy_u.h", vextract_zext_i16, v8i16, GPR32Opnd, MSA128HOpnd>; class COPY_U_W_DESC : MSA_COPY_DESC_BASE<"copy_u.w", vextract_zext_i32, v4i32, GPR32Opnd, MSA128WOpnd>; +class COPY_U_D_DESC : MSA_COPY_DESC_BASE<"copy_u.d", vextract_zext_i64, v2i64, + GPR64Opnd, MSA128DOpnd>; class COPY_FW_PSEUDO_DESC : MSA_COPY_PSEUDO_BASE<vector_extract, v4f32, FGR32, MSA128W>; @@ -2047,11 +2084,11 @@ class FEXP2_W_DESC : MSA_3RF_DESC_BASE<"fexp2.w", mul_fexp2, MSA128WOpnd>; class FEXP2_D_DESC : MSA_3RF_DESC_BASE<"fexp2.d", mul_fexp2, MSA128DOpnd>; let usesCustomInserter = 1 in { class FEXP2_W_1_PSEUDO_DESC : - MipsPseudo<(outs MSA128W:$wd), (ins MSA128W:$ws), - [(set MSA128W:$wd, (fexp2 MSA128W:$ws))]>; + MSAPseudo<(outs MSA128W:$wd), (ins MSA128W:$ws), + [(set MSA128W:$wd, (fexp2 MSA128W:$ws))]>; class FEXP2_D_1_PSEUDO_DESC : - MipsPseudo<(outs MSA128D:$wd), (ins MSA128D:$ws), - [(set MSA128D:$wd, (fexp2 MSA128D:$ws))]>; + MSAPseudo<(outs MSA128D:$wd), (ins MSA128D:$ws), + [(set MSA128D:$wd, (fexp2 MSA128D:$ws))]>; } class FEXUPL_W_DESC : MSA_2RF_DESC_BASE<"fexupl.w", int_mips_fexupl_w, @@ -2086,6 +2123,8 @@ class FILL_H_DESC : MSA_2R_FILL_DESC_BASE<"fill.h", v8i16, vsplati16, MSA128HOpnd, GPR32Opnd>; class FILL_W_DESC : MSA_2R_FILL_DESC_BASE<"fill.w", v4i32, vsplati32, MSA128WOpnd, GPR32Opnd>; +class FILL_D_DESC : MSA_2R_FILL_DESC_BASE<"fill.d", v2i64, vsplati64, + MSA128DOpnd, GPR64Opnd>; class FILL_FW_PSEUDO_DESC : MSA_2R_FILL_PSEUDO_BASE<v4f32, vsplatf32, MSA128W, FGR32>; @@ -2259,24 +2298,40 @@ class INSERT_H_DESC : MSA_INSERT_DESC_BASE<"insert.h", vinsert_v8i16, MSA128HOpnd, GPR32Opnd>; class INSERT_W_DESC : MSA_INSERT_DESC_BASE<"insert.w", vinsert_v4i32, MSA128WOpnd, GPR32Opnd>; +class INSERT_D_DESC : MSA_INSERT_DESC_BASE<"insert.d", vinsert_v2i64, + MSA128DOpnd, GPR64Opnd>; + +class INSERT_B_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v16i8, MSA128BOpnd, GPR32Opnd>; +class INSERT_H_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v8i16, MSA128HOpnd, GPR32Opnd>; +class INSERT_W_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v4i32, MSA128WOpnd, GPR32Opnd>; +class INSERT_D_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v2i64, MSA128DOpnd, GPR64Opnd>; class INSERT_FW_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE<vector_insert, v4f32, MSA128WOpnd, FGR32Opnd>; class INSERT_FD_PSEUDO_DESC : MSA_INSERT_PSEUDO_BASE<vector_insert, v2f64, MSA128DOpnd, FGR64Opnd>; -class INSVE_B_DESC : MSA_INSVE_DESC_BASE<"insve.b", int_mips_insve_b, +class INSERT_FW_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v4f32, MSA128WOpnd, FGR32Opnd>; +class INSERT_FD_VIDX_PSEUDO_DESC : + MSA_INSERT_VIDX_PSEUDO_BASE<vector_insert, v2f64, MSA128DOpnd, FGR64Opnd>; + +class INSVE_B_DESC : MSA_INSVE_DESC_BASE<"insve.b", insve_v16i8, MSA128BOpnd>; -class INSVE_H_DESC : MSA_INSVE_DESC_BASE<"insve.h", int_mips_insve_h, +class INSVE_H_DESC : MSA_INSVE_DESC_BASE<"insve.h", insve_v8i16, MSA128HOpnd>; -class INSVE_W_DESC : MSA_INSVE_DESC_BASE<"insve.w", int_mips_insve_w, +class INSVE_W_DESC : MSA_INSVE_DESC_BASE<"insve.w", insve_v4i32, MSA128WOpnd>; -class INSVE_D_DESC : MSA_INSVE_DESC_BASE<"insve.d", int_mips_insve_d, +class INSVE_D_DESC : MSA_INSVE_DESC_BASE<"insve.d", insve_v2i64, MSA128DOpnd>; class LD_DESC_BASE<string instr_asm, SDPatternOperator OpNode, ValueType TyNode, RegisterOperand ROWD, - Operand MemOpnd = mem, ComplexPattern Addr = addrRegImm, + Operand MemOpnd = mem_msa, ComplexPattern Addr = addrimm10, InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs ROWD:$wd); dag InOperandList = (ins MemOpnd:$addr); @@ -2296,16 +2351,21 @@ class LDI_H_DESC : MSA_I10_LDI_DESC_BASE<"ldi.h", MSA128HOpnd>; class LDI_W_DESC : MSA_I10_LDI_DESC_BASE<"ldi.w", MSA128WOpnd>; class LDI_D_DESC : MSA_I10_LDI_DESC_BASE<"ldi.d", MSA128DOpnd>; -class LSA_DESC { - dag OutOperandList = (outs GPR32Opnd:$rd); - dag InOperandList = (ins GPR32Opnd:$rs, GPR32Opnd:$rt, LSAImm:$sa); - string AsmString = "lsa\t$rd, $rs, $rt, $sa"; - list<dag> Pattern = [(set GPR32Opnd:$rd, (add GPR32Opnd:$rs, - (shl GPR32Opnd:$rt, +class LSA_DESC_BASE<string instr_asm, RegisterOperand RORD, + RegisterOperand RORS = RORD, RegisterOperand RORT = RORD, + InstrItinClass itin = NoItinerary > { + dag OutOperandList = (outs RORD:$rd); + dag InOperandList = (ins RORS:$rs, RORT:$rt, LSAImm:$sa); + string AsmString = !strconcat(instr_asm, "\t$rd, $rs, $rt, $sa"); + list<dag> Pattern = [(set RORD:$rd, (add RORT:$rt, + (shl RORS:$rs, immZExt2Lsa:$sa)))]; - InstrItinClass Itinerary = NoItinerary; + InstrItinClass Itinerary = itin; } +class LSA_DESC : LSA_DESC_BASE<"lsa", GPR32Opnd>; +class DLSA_DESC : LSA_DESC_BASE<"dlsa", GPR64Opnd>; + class MADD_Q_H_DESC : MSA_3RF_4RF_DESC_BASE<"madd_q.h", int_mips_madd_q_h, MSA128HOpnd>; class MADD_Q_W_DESC : MSA_3RF_4RF_DESC_BASE<"madd_q.w", int_mips_madd_q_w, @@ -2502,10 +2562,14 @@ class SLD_H_DESC : MSA_3R_SLD_DESC_BASE<"sld.h", int_mips_sld_h, MSA128HOpnd>; class SLD_W_DESC : MSA_3R_SLD_DESC_BASE<"sld.w", int_mips_sld_w, MSA128WOpnd>; class SLD_D_DESC : MSA_3R_SLD_DESC_BASE<"sld.d", int_mips_sld_d, MSA128DOpnd>; -class SLDI_B_DESC : MSA_ELM_DESC_BASE<"sldi.b", int_mips_sldi_b, MSA128BOpnd>; -class SLDI_H_DESC : MSA_ELM_DESC_BASE<"sldi.h", int_mips_sldi_h, MSA128HOpnd>; -class SLDI_W_DESC : MSA_ELM_DESC_BASE<"sldi.w", int_mips_sldi_w, MSA128WOpnd>; -class SLDI_D_DESC : MSA_ELM_DESC_BASE<"sldi.d", int_mips_sldi_d, MSA128DOpnd>; +class SLDI_B_DESC : MSA_ELM_SLD_DESC_BASE<"sldi.b", int_mips_sldi_b, + MSA128BOpnd>; +class SLDI_H_DESC : MSA_ELM_SLD_DESC_BASE<"sldi.h", int_mips_sldi_h, + MSA128HOpnd>; +class SLDI_W_DESC : MSA_ELM_SLD_DESC_BASE<"sldi.w", int_mips_sldi_w, + MSA128WOpnd>; +class SLDI_D_DESC : MSA_ELM_SLD_DESC_BASE<"sldi.d", int_mips_sldi_d, + MSA128DOpnd>; class SLL_B_DESC : MSA_3R_DESC_BASE<"sll.b", shl, MSA128BOpnd>; class SLL_H_DESC : MSA_3R_DESC_BASE<"sll.h", shl, MSA128HOpnd>; @@ -2597,7 +2661,7 @@ class SRLRI_D_DESC : MSA_BIT_D_X_DESC_BASE<"srlri.d", int_mips_srlri_d, class ST_DESC_BASE<string instr_asm, SDPatternOperator OpNode, ValueType TyNode, RegisterOperand ROWD, - Operand MemOpnd = mem, ComplexPattern Addr = addrRegImm, + Operand MemOpnd = mem_msa, ComplexPattern Addr = addrimm10, InstrItinClass itin = NoItinerary> { dag OutOperandList = (outs); dag InOperandList = (ins ROWD:$wd, MemOpnd:$addr); @@ -2810,8 +2874,12 @@ def BNZ_V : BNZ_V_ENC, BNZ_V_DESC; def BSEL_V : BSEL_V_ENC, BSEL_V_DESC; class MSA_BSEL_PSEUDO_BASE<RegisterOperand RO, ValueType Ty> : - MipsPseudo<(outs RO:$wd), (ins RO:$wd_in, RO:$ws, RO:$wt), - [(set RO:$wd, (Ty (vselect RO:$wd_in, RO:$ws, RO:$wt)))]>, + MSAPseudo<(outs RO:$wd), (ins RO:$wd_in, RO:$ws, RO:$wt), + [(set RO:$wd, (Ty (vselect RO:$wd_in, RO:$wt, RO:$ws)))]>, + // Note that vselect and BSEL_V treat the condition operand the opposite way + // from each other. + // (vselect cond, if_set, if_clear) + // (BSEL_V cond, if_clear, if_set) PseudoInstExpansion<(BSEL_V MSA128BOpnd:$wd, MSA128BOpnd:$wd_in, MSA128BOpnd:$ws, MSA128BOpnd:$wt)> { let Constraints = "$wd_in = $wd"; @@ -2897,10 +2965,12 @@ def CLTI_U_D : CLTI_U_D_ENC, CLTI_U_D_DESC; def COPY_S_B : COPY_S_B_ENC, COPY_S_B_DESC; def COPY_S_H : COPY_S_H_ENC, COPY_S_H_DESC; def COPY_S_W : COPY_S_W_ENC, COPY_S_W_DESC; +def COPY_S_D : COPY_S_D_ENC, COPY_S_D_DESC; def COPY_U_B : COPY_U_B_ENC, COPY_U_B_DESC; def COPY_U_H : COPY_U_H_ENC, COPY_U_H_DESC; def COPY_U_W : COPY_U_W_ENC, COPY_U_W_DESC; +def COPY_U_D : COPY_U_D_ENC, COPY_U_D_DESC; def COPY_FW_PSEUDO : COPY_FW_PSEUDO_DESC; def COPY_FD_PSEUDO : COPY_FD_PSEUDO_DESC; @@ -3012,6 +3082,7 @@ def FFQR_D : FFQR_D_ENC, FFQR_D_DESC; def FILL_B : FILL_B_ENC, FILL_B_DESC; def FILL_H : FILL_H_ENC, FILL_H_DESC; def FILL_W : FILL_W_ENC, FILL_W_DESC; +def FILL_D : FILL_D_ENC, FILL_D_DESC; def FILL_FW_PSEUDO : FILL_FW_PSEUDO_DESC; def FILL_FD_PSEUDO : FILL_FD_PSEUDO_DESC; @@ -3141,18 +3212,30 @@ def ILVR_D : ILVR_D_ENC, ILVR_D_DESC; def INSERT_B : INSERT_B_ENC, INSERT_B_DESC; def INSERT_H : INSERT_H_ENC, INSERT_H_DESC; def INSERT_W : INSERT_W_ENC, INSERT_W_DESC; +def INSERT_D : INSERT_D_ENC, INSERT_D_DESC; // INSERT_FW_PSEUDO defined after INSVE_W // INSERT_FD_PSEUDO defined after INSVE_D -def INSVE_B : INSVE_B_ENC, INSVE_B_DESC; -def INSVE_H : INSVE_H_ENC, INSVE_H_DESC; -def INSVE_W : INSVE_W_ENC, INSVE_W_DESC; -def INSVE_D : INSVE_D_ENC, INSVE_D_DESC; +// There is a fourth operand that is not present in the encoding. Use a +// custom decoder to get a chance to add it. +let DecoderMethod = "DecodeINSVE_DF" in { + def INSVE_B : INSVE_B_ENC, INSVE_B_DESC; + def INSVE_H : INSVE_H_ENC, INSVE_H_DESC; + def INSVE_W : INSVE_W_ENC, INSVE_W_DESC; + def INSVE_D : INSVE_D_ENC, INSVE_D_DESC; +} def INSERT_FW_PSEUDO : INSERT_FW_PSEUDO_DESC; def INSERT_FD_PSEUDO : INSERT_FD_PSEUDO_DESC; +def INSERT_B_VIDX_PSEUDO : INSERT_B_VIDX_PSEUDO_DESC; +def INSERT_H_VIDX_PSEUDO : INSERT_H_VIDX_PSEUDO_DESC; +def INSERT_W_VIDX_PSEUDO : INSERT_W_VIDX_PSEUDO_DESC; +def INSERT_D_VIDX_PSEUDO : INSERT_D_VIDX_PSEUDO_DESC; +def INSERT_FW_VIDX_PSEUDO : INSERT_FW_VIDX_PSEUDO_DESC; +def INSERT_FD_VIDX_PSEUDO : INSERT_FD_VIDX_PSEUDO_DESC; + def LD_B: LD_B_ENC, LD_B_DESC; def LD_H: LD_H_ENC, LD_H_DESC; def LD_W: LD_W_ENC, LD_W_DESC; @@ -3164,6 +3247,7 @@ def LDI_W : LDI_W_ENC, LDI_W_DESC; def LDI_D : LDI_D_ENC, LDI_D_DESC; def LSA : LSA_ENC, LSA_DESC; +def DLSA : DLSA_ENC, DLSA_DESC; def MADD_Q_H : MADD_Q_H_ENC, MADD_Q_H_DESC; def MADD_Q_W : MADD_Q_W_ENC, MADD_Q_W_DESC; @@ -3464,46 +3548,23 @@ class MSAPat<dag pattern, dag result, list<Predicate> pred = [HasMSA]> : def : MSAPat<(extractelt (v4i32 MSA128W:$ws), immZExt4:$idx), (COPY_S_W MSA128W:$ws, immZExt4:$idx)>; -def : MSAPat<(v16i8 (load addr:$addr)), (LD_B addr:$addr)>; -def : MSAPat<(v8i16 (load addr:$addr)), (LD_H addr:$addr)>; -def : MSAPat<(v4i32 (load addr:$addr)), (LD_W addr:$addr)>; -def : MSAPat<(v2i64 (load addr:$addr)), (LD_D addr:$addr)>; -def : MSAPat<(v8f16 (load addr:$addr)), (LD_H addr:$addr)>; -def : MSAPat<(v4f32 (load addr:$addr)), (LD_W addr:$addr)>; -def : MSAPat<(v2f64 (load addr:$addr)), (LD_D addr:$addr)>; - -def : MSAPat<(v8f16 (load addrRegImm:$addr)), (LD_H addrRegImm:$addr)>; -def : MSAPat<(v4f32 (load addrRegImm:$addr)), (LD_W addrRegImm:$addr)>; -def : MSAPat<(v2f64 (load addrRegImm:$addr)), (LD_D addrRegImm:$addr)>; - -def : MSAPat<(store (v16i8 MSA128B:$ws), addr:$addr), - (ST_B MSA128B:$ws, addr:$addr)>; -def : MSAPat<(store (v8i16 MSA128H:$ws), addr:$addr), - (ST_H MSA128H:$ws, addr:$addr)>; -def : MSAPat<(store (v4i32 MSA128W:$ws), addr:$addr), - (ST_W MSA128W:$ws, addr:$addr)>; -def : MSAPat<(store (v2i64 MSA128D:$ws), addr:$addr), - (ST_D MSA128D:$ws, addr:$addr)>; -def : MSAPat<(store (v8f16 MSA128H:$ws), addr:$addr), - (ST_H MSA128H:$ws, addr:$addr)>; -def : MSAPat<(store (v4f32 MSA128W:$ws), addr:$addr), - (ST_W MSA128W:$ws, addr:$addr)>; -def : MSAPat<(store (v2f64 MSA128D:$ws), addr:$addr), - (ST_D MSA128D:$ws, addr:$addr)>; - -def ST_FH : MSAPat<(store (v8f16 MSA128H:$ws), addrRegImm:$addr), - (ST_H MSA128H:$ws, addrRegImm:$addr)>; -def ST_FW : MSAPat<(store (v4f32 MSA128W:$ws), addrRegImm:$addr), - (ST_W MSA128W:$ws, addrRegImm:$addr)>; -def ST_FD : MSAPat<(store (v2f64 MSA128D:$ws), addrRegImm:$addr), - (ST_D MSA128D:$ws, addrRegImm:$addr)>; +def : MSAPat<(v8f16 (load addrimm10:$addr)), (LD_H addrimm10:$addr)>; +def : MSAPat<(v4f32 (load addrimm10:$addr)), (LD_W addrimm10:$addr)>; +def : MSAPat<(v2f64 (load addrimm10:$addr)), (LD_D addrimm10:$addr)>; + +def ST_FH : MSAPat<(store (v8f16 MSA128H:$ws), addrimm10:$addr), + (ST_H MSA128H:$ws, addrimm10:$addr)>; +def ST_FW : MSAPat<(store (v4f32 MSA128W:$ws), addrimm10:$addr), + (ST_W MSA128W:$ws, addrimm10:$addr)>; +def ST_FD : MSAPat<(store (v2f64 MSA128D:$ws), addrimm10:$addr), + (ST_D MSA128D:$ws, addrimm10:$addr)>; class MSA_FABS_PSEUDO_DESC_BASE<RegisterOperand ROWD, RegisterOperand ROWS = ROWD, InstrItinClass itin = NoItinerary> : - MipsPseudo<(outs ROWD:$wd), - (ins ROWS:$ws), - [(set ROWD:$wd, (fabs ROWS:$ws))]> { + MSAPseudo<(outs ROWD:$wd), + (ins ROWS:$ws), + [(set ROWD:$wd, (fabs ROWS:$ws))]> { InstrItinClass Itinerary = itin; } def FABS_W : MSA_FABS_PSEUDO_DESC_BASE<MSA128WOpnd>, @@ -3518,7 +3579,7 @@ class MSABitconvertPat<ValueType DstVT, ValueType SrcVT, MSAPat<(DstVT (bitconvert SrcVT:$src)), (COPY_TO_REGCLASS SrcVT:$src, DstRC), preds>; -// These are endian-independant because the element size doesnt change +// These are endian-independent because the element size doesnt change def : MSABitconvertPat<v8i16, v8f16, MSA128H>; def : MSABitconvertPat<v4i32, v4f32, MSA128W>; def : MSABitconvertPat<v2i64, v2f64, MSA128D>; @@ -3692,3 +3753,55 @@ def SZ_D_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE<MipsVAllZero, v2i64, MSA128D, NoItinerary>; def SZ_V_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE<MipsVAnyZero, v16i8, MSA128B, NoItinerary>; + +// Vector extraction with variable index +def : MSAPat<(i32 (vextract_sext_i8 v16i8:$ws, i32:$idx)), + (SRA (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_B v16i8:$ws, + i32:$idx), + sub_lo)), + GPR32), (i32 24))>; +def : MSAPat<(i32 (vextract_sext_i16 v8i16:$ws, i32:$idx)), + (SRA (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_H v8i16:$ws, + i32:$idx), + sub_lo)), + GPR32), (i32 16))>; +def : MSAPat<(i32 (vextract_sext_i32 v4i32:$ws, i32:$idx)), + (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_W v4i32:$ws, + i32:$idx), + sub_lo)), + GPR32)>; +def : MSAPat<(i64 (vextract_sext_i64 v2i64:$ws, i32:$idx)), + (COPY_TO_REGCLASS (i64 (EXTRACT_SUBREG (SPLAT_D v2i64:$ws, + i32:$idx), + sub_64)), + GPR64), [HasMSA, IsGP64bit]>; + +def : MSAPat<(i32 (vextract_zext_i8 v16i8:$ws, i32:$idx)), + (SRL (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_B v16i8:$ws, + i32:$idx), + sub_lo)), + GPR32), (i32 24))>; +def : MSAPat<(i32 (vextract_zext_i16 v8i16:$ws, i32:$idx)), + (SRL (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_H v8i16:$ws, + i32:$idx), + sub_lo)), + GPR32), (i32 16))>; +def : MSAPat<(i32 (vextract_zext_i32 v4i32:$ws, i32:$idx)), + (COPY_TO_REGCLASS (i32 (EXTRACT_SUBREG (SPLAT_W v4i32:$ws, + i32:$idx), + sub_lo)), + GPR32)>; +def : MSAPat<(i64 (vextract_zext_i64 v2i64:$ws, i32:$idx)), + (COPY_TO_REGCLASS (i64 (EXTRACT_SUBREG (SPLAT_D v2i64:$ws, + i32:$idx), + sub_64)), + GPR64), [HasMSA, IsGP64bit]>; + +def : MSAPat<(f32 (vector_extract v4f32:$ws, i32:$idx)), + (f32 (EXTRACT_SUBREG (SPLAT_W v4f32:$ws, + i32:$idx), + sub_lo))>; +def : MSAPat<(f64 (vector_extract v2f64:$ws, i32:$idx)), + (f64 (EXTRACT_SUBREG (SPLAT_D v2f64:$ws, + i32:$idx), + sub_64))>; |