(match_operand:IMSA 1 "register_operand" "f,f")
(match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_MSA"
- "@
- srl.<msafmt>\t%w0,%w1,%w2
- srli.<msafmt>\t%w0,%w1,%E2"
+{
+ if (which_alternative == 0)
+ return "srl.<msafmt>\t%w0,%w1,%w2";
+
+ return mips_msa_output_shift_immediate("srli.<msafmt>\t%w0,%w1,%E2", operands);
+}
[(set_attr "type" "simd_shift")
(set_attr "mode" "<MODE>")])
(match_operand:IMSA 1 "register_operand" "f,f")
(match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_MSA"
- "@
- sra.<msafmt>\t%w0,%w1,%w2
- srai.<msafmt>\t%w0,%w1,%E2"
+{
+ if (which_alternative == 0)
+ return "sra.<msafmt>\t%w0,%w1,%w2";
+
+ return mips_msa_output_shift_immediate("srai.<msafmt>\t%w0,%w1,%E2", operands);
+}
[(set_attr "type" "simd_shift")
(set_attr "mode" "<MODE>")])
(match_operand:IMSA 1 "register_operand" "f,f")
(match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
"ISA_HAS_MSA"
- "@
- sll.<msafmt>\t%w0,%w1,%w2
- slli.<msafmt>\t%w0,%w1,%E2"
+{
+ if (which_alternative == 0)
+ return "sll.<msafmt>\t%w0,%w1,%w2";
+
+ return mips_msa_output_shift_immediate("slli.<msafmt>\t%w0,%w1,%E2", operands);
+}
[(set_attr "type" "simd_shift")
(set_attr "mode" "<MODE>")])
extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *);
extern const char *mips_output_division (const char *, rtx *);
extern const char *mips_msa_output_division (const char *, rtx *);
+extern const char *mips_msa_output_shift_immediate (const char *, rtx *);
extern const char *mips_output_probe_stack_range (rtx, rtx);
extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int);
extern bool mips_linked_madd_p (rtx_insn *, rtx_insn *);
}
return s;
}
+
+/* Return the assembly code for MSA immediate shift instructions,
+ which has the operands given by OPERANDS. Truncate the shift amount
+ to make GAS happy. */
+
+const char *
+mips_msa_output_shift_immediate (const char *shift, rtx *operands)
+{
+ rtx amount = operands[2];
+ machine_mode mode = amount->mode;
+
+ unsigned val = UINTVAL (CONST_VECTOR_ELT (amount, 0));
+ val &= GET_MODE_UNIT_BITSIZE (mode) - 1;
+ if (!val)
+ return "";
+
+ rtx c = gen_int_mode (val, GET_MODE_INNER (mode));
+ operands[2] = gen_const_vec_duplicate (mode, c);
+
+ return shift;
+}
\f
/* Return true if destination of IN_INSN is used as add source in
OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example: