https://gcc.gnu.org/g:5fd8f336f17067fa3ae25eb69f50ca45171ceec8

commit r16-1689-g5fd8f336f17067fa3ae25eb69f50ca45171ceec8
Author: Luis Silva <lu...@synopsys.com>
Date:   Wed Jun 25 17:58:35 2025 +0300

    arc: Use intrinsics for __builtin_mul_overflow ()
    
    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>

Diff:
---
 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 96921207cc41..d119464176b8 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"   "multi")])
+
 (define_insn "*mulsi3_cmp0"
   [(set (reg:CC_Z CC_REG)
        (compare:CC_Z

Reply via email to