From 5fd8f336f17067fa3ae25eb69f50ca45171ceec8 Mon Sep 17 00:00:00 2001 From: Luis Silva Date: Wed, 25 Jun 2025 17:58:35 +0300 Subject: [PATCH] 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 (mulvsi4): New define_expand. (mulsi3_Vcmp): New define_insn. Signed-off-by: Luis Silva --- 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 96921207cc4..d119464176b 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 "*xt_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 "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_mulsi3_Vcmp (operands[0], operands[1], + operands[2])); + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + DONE; + }) + +(define_insn "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.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 -- 2.47.2