Hi Eikansh,
This looks good - a few comments:
Please add a comment before this pattern so it's clear what it is for and
shows up if you search for similar saturating patterns.
+(define_expand "usmulsi3"
+ [(set (match_operand:SI 0 "register_operand")
+ (us_mult:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "register_operand")))]
+ ""
+{
+ rtx product = gen_reg_rtx (DImode);
+ emit_insn (gen_umulsidi3 (product, operands[1], operands[2]));
+
+ rtx high = gen_reg_rtx (DImode);
+ emit_insn (gen_lshrdi3 (high, product, GEN_INT (32)));
+
+ rtx cc_reg = aarch64_gen_compare_reg (EQ, high, const0_rtx);
+ rtx cond = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
+ rtx low = gen_lowpart (SImode, product);
+ emit_insn (gen_rtx_SET (operands[0],
+ gen_rtx_IF_THEN_ELSE (SImode, cond, low,
+ constm1_rtx)));
+ DONE;
+})
This generates:
umull x0, w0, w1
cmp xzr, x0, lsr 32
csinv w0, w0, wzr, eq
This is an odd form of CMP, and it uses a shift which means it takes 2 cycles
on most CPUs.
Using TST x0, 0xffffffff00000000 is both easier to understand and faster.
Cheers,
Wilco