LGTM,

Cheers,
Claudiu

On Tue, Mar 18, 2025 at 6:23 PM Luis Silva <luis.sil...@synopsys.com> wrote:
>
> This patch handles both signed and unsigned
> builtin multiplication overflow.
>
> Uses the "mpy.f" instruction to set the condition
> codes based on the result.  In the event of an
> overflow, the V flag is set, triggering a
> conditional move depending on the V flag status.
>
> For example, set "1" to "r0" in case of overflow:
>
>         mov_s   r0,1
>         mpy.f   r0,r0,r1
>         j_s.d   [blink]
>         mov.nv  r0,0
>
> gcc/ChangeLog:
>
>         * config/arc/arc.md (<su_optab>mulvsi4): New define_expand.
>         (<su_optab>mulsi3_Vcmp): New define_insn.
>
> Signed-off-by: Luis Silva <lu...@synopsys.com>
> ---
>  gcc/config/arc/arc.md | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index bc2e8fadd91..dd245d1813c 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -842,6 +842,9 @@ archs4x, archs4xd"
>  ; Optab prefix for sign/zero-extending operations
>  (define_code_attr su_optab [(sign_extend "") (zero_extend "u")])
>
> +;; Code iterator for sign/zero extension
> +(define_code_iterator ANY_EXTEND [sign_extend zero_extend])
> +
>  (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout"
>    [(set (match_operand 0 "cc_set_register" "")
>         (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
> @@ -1068,6 +1071,36 @@ archs4x, archs4xd"
>     (set_attr "cond" "set_zn")
>     (set_attr "length" "*,4,4,4,8")])
>
> +(define_expand "<su_optab>mulvsi4"
> +  [(ANY_EXTEND:DI (match_operand:SI 0 "register_operand"))
> +   (ANY_EXTEND:DI (match_operand:SI 1 "register_operand"))
> +   (ANY_EXTEND:DI (match_operand:SI 2 "register_operand"))
> +   (label_ref (match_operand 3 "" ""))]
> +  "TARGET_MPY"
> +  {
> +    emit_insn (gen_<su_optab>mulsi3_Vcmp (operands[0], operands[1],
> +                                         operands[2]));
> +    arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
> +    DONE;
> +  })
> +
> +(define_insn "<su_optab>mulsi3_Vcmp"
> +  [(parallel
> +    [(set
> +      (reg:CC_V CC_REG)
> +      (compare:CC_V
> +       (mult:DI
> +       (ANY_EXTEND:DI (match_operand:SI 1 "register_operand"  "%0,r,r,r"))
> +       (ANY_EXTEND:DI (match_operand:SI 2 "nonmemory_operand"  "I,L,r,C32")))
> +       (ANY_EXTEND:DI (mult:SI (match_dup 1) (match_dup 2)))))
> +     (set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
> +         (mult:SI (match_dup 1) (match_dup 2)))])]
> +  "register_operand (operands[1], SImode)
> +   || register_operand (operands[2], SImode)"
> +  "mpy<su_optab>.f\\t%0,%1,%2"
> +  [(set_attr "length" "4,4,4,8")
> +   (set_attr "type"   "mpy")])
> +
>  (define_insn "*mulsi3_cmp0"
>    [(set (reg:CC_Z CC_REG)
>         (compare:CC_Z
> --
> 2.37.1
>

Reply via email to