OK, Thank you for your contribution, Claudiu
On Wed, Sep 6, 2023 at 3:50 PM Shahab Vahedi <shahab.vah...@synopsys.com> wrote: > > This patch covers signed and unsigned subtractions. The generated code > would be something along these lines: > > signed: > sub.f r0, r1, r2 > b.v @label > > unsigned: > sub.f r0, r1, r2 > b.c @label > > gcc/ChangeLog: > > * config/arc/arc.md (subsi3_v): New insn. > (subvsi4): New expand. > (subsi3_c): New insn. > (usubvsi4): New expand. > > gcc/testsuite/ChangeLog: > > * gcc.target/arc/overflow-2.c: New. > > Signed-off-by: Shahab Vahedi <sha...@synopsys.com> > --- > gcc/config/arc/arc.md | 48 +++++++++++ > gcc/testsuite/gcc.target/arc/overflow-2.c | 97 +++++++++++++++++++++++ > 2 files changed, 145 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/arc/overflow-2.c > > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md > index 9d011f6b4a9..34e9e1a7f1d 100644 > --- a/gcc/config/arc/arc.md > +++ b/gcc/config/arc/arc.md > @@ -2973,6 +2973,54 @@ archs4x, archs4xd" > (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") > ]) > > +(define_insn "subsi3_v" > + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") > + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") > + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) > + (set (reg:CC_V CC_REG) > + (compare:CC_V (sign_extend:DI (minus:SI (match_dup 1) > + (match_dup 2))) > + (minus:DI (sign_extend:DI (match_dup 1)) > + (sign_extend:DI (match_dup 2)))))] > + "" > + "sub.f\\t%0,%1,%2" > + [(set_attr "cond" "set") > + (set_attr "type" "compare") > + (set_attr "length" "4,4,4,8")]) > + > +(define_expand "subvsi4" > + [(match_operand:SI 0 "register_operand") > + (match_operand:SI 1 "register_operand") > + (match_operand:SI 2 "nonmemory_operand") > + (label_ref (match_operand 3 "" ""))] > + "" > + "emit_insn (gen_subsi3_v (operands[0], operands[1], operands[2])); > + arc_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); > + DONE;") > + > +(define_insn "subsi3_c" > + [(set (match_operand:SI 0 "register_operand" "=r,r,r, r") > + (minus:SI (match_operand:SI 1 "register_operand" "r,r,0, r") > + (match_operand:SI 2 "nonmemory_operand" "r,L,I,C32"))) > + (set (reg:CC_C CC_REG) > + (compare:CC_C (match_dup 1) > + (match_dup 2)))] > + "" > + "sub.f\\t%0,%1,%2" > + [(set_attr "cond" "set") > + (set_attr "type" "compare") > + (set_attr "length" "4,4,4,8")]) > + > +(define_expand "usubvsi4" > + [(match_operand:SI 0 "register_operand") > + (match_operand:SI 1 "register_operand") > + (match_operand:SI 2 "nonmemory_operand") > + (label_ref (match_operand 3 "" ""))] > + "" > + "emit_insn (gen_subsi3_c (operands[0], operands[1], operands[2])); > + arc_gen_unlikely_cbranch (LTU, CC_Cmode, operands[3]); > + DONE;") > + > (define_expand "subdi3" > [(set (match_operand:DI 0 "register_operand" "") > (minus:DI (match_operand:DI 1 "register_operand" "") > diff --git a/gcc/testsuite/gcc.target/arc/overflow-2.c > b/gcc/testsuite/gcc.target/arc/overflow-2.c > new file mode 100644 > index 00000000000..b4de8c03b22 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arc/overflow-2.c > @@ -0,0 +1,97 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1" } */ > + > +#include <stdbool.h> > +#include <stdint.h> > + > +/* > + * sub.f r0,r0,r1 > + * st_s r0,[r2] > + * mov_s r0,1 > + * j_s.d [blink] > + * mov.nv r0,0 > + */ > +bool sub_overflow (int32_t a, int32_t b, int32_t *res) > +{ > + return __builtin_sub_overflow (a, b, res); > +} > + > +/* > + * sub.f r0,r0,-1234 > + * st_s r0,[r1] > + * mov_s r0,1 > + * j_s.d [blink] > + * mov.nv r0,0 > + */ > +bool subi_overflow (int32_t a, int32_t *res) > +{ > + return __builtin_sub_overflow (a, -1234, res); > +} > + > +/* > + * sub.f r3,r0,r1 > + * st_s r3,[r2] > + * j_s.d [blink] > + * setlo r0,r0,r1 > + */ > +bool usub_overflow (uint32_t a, uint32_t b, uint32_t *res) > +{ > + return __builtin_sub_overflow (a, b, res); > +} > + > +/* > + * sub.f r2,r0,4321 > + * seths r0,4320,r0 > + * j_s.d [blink] > + * st_s r2,[r1] > + */ > +bool usubi_overflow (uint32_t a, uint32_t *res) > +{ > + return __builtin_sub_overflow (a, 4321, res); > +} > + > +/* > + * sub.f r0,r0,r1 > + * mov_s r0,1 > + * j_s.d [blink] > + * mov.nv r0,0 > + */ > +bool sub_overflow_p (int32_t a, int32_t b, int32_t res) > +{ > + return __builtin_sub_overflow_p (a, b, res); > +} > + > +/* > + * sub.f r0,r0,-1000 > + * mov_s r0,1 > + * j_s.d [blink] > + * mov.nv r0,0 > + */ > +bool subi_overflow_p (int32_t a, int32_t res) > +{ > + return __builtin_sub_overflow_p (a, -1000, res); > +} > + > +/* > + * j_s.d [blink] > + * setlo r0,r0,r1 > + */ > +bool usub_overflow_p (uint32_t a, uint32_t b, uint32_t res) > +{ > + return __builtin_sub_overflow_p (a, b, res); > +} > + > +/* > + * seths r0,1999,r0 > + * j_s.d [blink] > + */ > +bool usubi_overflow_p (uint32_t a, uint32_t res) > +{ > + return __builtin_sub_overflow_p (a, 2000, res); > +} > + > +/* { dg-final { scan-assembler-times "sub.f\\s\+" 6 } } */ > +/* { dg-final { scan-assembler-times "mov\.nv\\s\+" 4 } } */ > +/* { dg-final { scan-assembler-times "setlo\\s\+" 2 } } */ > +/* { dg-final { scan-assembler-times "seths\\s\+" 2 } } */ > +/* { dg-final { scan-assembler-not "cmp" } } */ > -- > 2.42.0 >