diff options
author | Michael Collison <michael.collison@linaro.org> | 2016-08-24 19:31:20 +0000 |
---|---|---|
committer | Michael Collison <collison@gcc.gnu.org> | 2016-08-24 19:31:20 +0000 |
commit | c8cd4696473a9c803b9454adeee57c90565c2fad (patch) | |
tree | 8a1b828540680a9271b18e9c65d461ce0fb4fb3e /gcc | |
parent | d5b5d21260d1036b078cad42ec2fe88754cd8ca3 (diff) | |
download | gcc-c8cd4696473a9c803b9454adeee57c90565c2fad.zip gcc-c8cd4696473a9c803b9454adeee57c90565c2fad.tar.gz gcc-c8cd4696473a9c803b9454adeee57c90565c2fad.tar.bz2 |
arm-modes.def: Add new condition code mode CC_V to represent the overflow bit.
2016-08-24 Michael Collison <michael.collison@linaro.org>
Michael Collison <michael.collison@arm.com>
* config/arm/arm-modes.def: Add new condition code mode CC_V
to represent the overflow bit.
* config/arm/arm.c (maybe_get_arm_condition_code):
Add support for CC_Vmode.
(arm_gen_unlikely_cbranch): New function to generate common
rtl conditional branches for overflow patterns.
* config/arm/arm-protos.h: Add prototype for
arm_gen_unlikely_cbranch.
* config/arm/arm.md (addv<mode>4, add<mode>3_compareV,
addsi3_compareV_upper): New patterns to support signed
builtin overflow add operations.
(uaddv<mode>4, add<mode>3_compareC, addsi3_compareV_upper):
New patterns to support unsigned builtin add overflow operations.
(subv<mode>4, sub<mode>3_compare1): New patterns to support signed
builtin overflow subtract operations,
(usubv<mode>4): New patterns to support unsigned builtin subtract
overflow operations.
(negvsi3, negvdi3, negdi2_compare, negsi2_carryin_compare): New patterns
to support builtin overflow negate operations.
* gcc.target/arm/builtin_saddl.c: New testcase.
* gcc.target/arm/builtin_saddll.c: New testcase.
* gcc.target/arm/builtin_uaddl.c: New testcase.
* gcc.target/arm/builtin_uaddll.c: New testcase.
* gcc.target/arm/builtin_ssubl.c: New testcase.
* gcc.target/arm/builtin_ssubll.c: New testcase.
* gcc.target/arm/builtin_usubl.c: New testcase.
* gcc.target/arm/builtin_usubll.c: New testcase.
Co-Authored-By: Michael Collison <michael.collison@arm.com>
From-SVN: r239739
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/config/arm/arm-modes.def | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 29 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 325 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_saddl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_saddll.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_ssubl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_ssubll.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_uaddl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_uaddll.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_usubl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/builtin_usubll.c | 18 |
14 files changed, 532 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 66ec428..ef08c0a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2016-08-24 Michael Collison <michael.collison@linaro.org> + Michael Collison <michael.collison@arm.com> + + * config/arm/arm-modes.def: Add new condition code mode CC_V + to represent the overflow bit. + * config/arm/arm.c (maybe_get_arm_condition_code): + Add support for CC_Vmode. + (arm_gen_unlikely_cbranch): New function to generate common + rtl conditional branches for overflow patterns. + * config/arm/arm-protos.h: Add prototype for + arm_gen_unlikely_cbranch. + * config/arm/arm.md (addv<mode>4, add<mode>3_compareV, + addsi3_compareV_upper): New patterns to support signed + builtin overflow add operations. + (uaddv<mode>4, add<mode>3_compareC, addsi3_compareV_upper): + New patterns to support unsigned builtin add overflow operations. + (subv<mode>4, sub<mode>3_compare1): New patterns to support signed + builtin overflow subtract operations, + (usubv<mode>4): New patterns to support unsigned builtin subtract + overflow operations. + (negvsi3, negvdi3, negdi2_compare, negsi2_carryin_compare): New patterns + to support builtin overflow negate operations. + 2016-08-24 Andreas Krebbel <krebbel@linux.vnet.ibm.com> Revert diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index 1819553..69231f2 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -59,6 +59,7 @@ CC_MODE (CC_DGEU); CC_MODE (CC_DGTU); CC_MODE (CC_C); CC_MODE (CC_N); +CC_MODE (CC_V); /* Vector modes. */ VECTOR_MODES (INT, 4); /* V4QI V2HI */ diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 3975612..374836c 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -54,6 +54,8 @@ extern rtx arm_simd_vect_par_cnst_half (machine_mode mode, bool high); extern bool arm_simd_check_vect_par_cnst_half_p (rtx op, machine_mode mode, bool high); #ifdef RTX_CODE +extern void arm_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode, + rtx label_ref); extern bool arm_vector_mode_supported_p (machine_mode); extern bool arm_small_register_classes_for_mode_p (machine_mode); extern int arm_hard_regno_mode_ok (unsigned int, machine_mode); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c1d010c..c775807 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -22992,6 +22992,8 @@ maybe_get_arm_condition_code (rtx comparison) { case LTU: return ARM_CS; case GEU: return ARM_CC; + case NE: return ARM_CS; + case EQ: return ARM_CC; default: return ARM_NV; } @@ -23017,6 +23019,14 @@ maybe_get_arm_condition_code (rtx comparison) default: return ARM_NV; } + case CC_Vmode: + switch (comp_code) + { + case NE: return ARM_VS; + case EQ: return ARM_VC; + default: return ARM_NV; + } + case CCmode: switch (comp_code) { @@ -30575,4 +30585,23 @@ arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset, return true; } +/* Generate RTL for a conditional branch with rtx comparison CODE in + mode CC_MODE. The destination of the unlikely conditional branch + is LABEL_REF. */ + +void +arm_gen_unlikely_cbranch (enum rtx_code code, machine_mode cc_mode, + rtx label_ref) +{ + rtx x; + x = gen_rtx_fmt_ee (code, VOIDmode, + gen_rtx_REG (cc_mode, CC_REGNUM), + const0_rtx); + + x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, + gen_rtx_LABEL_REF (VOIDmode, label_ref), + pc_rtx); + emit_unlikely_jump (gen_rtx_SET (pc_rtx, x)); +} + #include "gt-arm.h" diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ec1a9ad..318db75 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -547,6 +547,32 @@ (set_attr "type" "multiple")] ) +(define_expand "addv<mode>4" + [(match_operand:SIDI 0 "register_operand") + (match_operand:SIDI 1 "register_operand") + (match_operand:SIDI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + + DONE; +}) + +(define_expand "uaddv<mode>4" + [(match_operand:SIDI 0 "register_operand") + (match_operand:SIDI 1 "register_operand") + (match_operand:SIDI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]); + + DONE; +}) + (define_expand "addsi3" [(set (match_operand:SI 0 "s_register_operand" "") (plus:SI (match_operand:SI 1 "s_register_operand" "") @@ -624,6 +650,165 @@ ] ) +(define_insn_and_split "adddi3_compareV" + [(set (reg:CC_V CC_REGNUM) + (ne:CC_V + (plus:TI + (sign_extend:TI (match_operand:DI 1 "register_operand" "r")) + (sign_extend:TI (match_operand:DI 2 "register_operand" "r"))) + (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) + (set (match_operand:DI 0 "register_operand" "=&r") + (plus:DI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "#" + "&& reload_completed" + [(parallel [(set (reg:CC_C CC_REGNUM) + (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) + (match_dup 1))) + (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) + (parallel [(set (reg:CC_V CC_REGNUM) + (ne:CC_V + (plus:DI (plus:DI + (sign_extend:DI (match_dup 4)) + (sign_extend:DI (match_dup 5))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) + (plus:DI (sign_extend:DI + (plus:SI (match_dup 4) (match_dup 5))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) + (set (match_dup 3) (plus:SI (plus:SI + (match_dup 4) (match_dup 5)) + (ltu:SI (reg:CC_C CC_REGNUM) + (const_int 0))))])] + " + { + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[2] = gen_lowpart (SImode, operands[2]); + }" + [(set_attr "conds" "set") + (set_attr "length" "8") + (set_attr "type" "multiple")] +) + +(define_insn "addsi3_compareV" + [(set (reg:CC_V CC_REGNUM) + (ne:CC_V + (plus:DI + (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "adds%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "type" "alus_sreg")] +) + +(define_insn "*addsi3_compareV_upper" + [(set (reg:CC_V CC_REGNUM) + (ne:CC_V + (plus:DI + (plus:DI + (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) + (plus:DI (sign_extend:DI + (plus:SI (match_dup 1) (match_dup 2))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) + (set (match_operand:SI 0 "register_operand" "=r") + (plus:SI + (plus:SI (match_dup 1) (match_dup 2)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] + "TARGET_32BIT" + "adcs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "type" "adcs_reg")] +) + +(define_insn_and_split "adddi3_compareC" + [(set (reg:CC_C CC_REGNUM) + (ne:CC_C + (plus:TI + (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) + (zero_extend:TI (match_operand:DI 2 "register_operand" "r"))) + (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) + (set (match_operand:DI 0 "register_operand" "=&r") + (plus:DI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "#" + "&& reload_completed" + [(parallel [(set (reg:CC_C CC_REGNUM) + (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) + (match_dup 1))) + (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) + (parallel [(set (reg:CC_C CC_REGNUM) + (ne:CC_C + (plus:DI (plus:DI + (zero_extend:DI (match_dup 4)) + (zero_extend:DI (match_dup 5))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) + (plus:DI (zero_extend:DI + (plus:SI (match_dup 4) (match_dup 5))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) + (set (match_dup 3) (plus:SI + (plus:SI (match_dup 4) (match_dup 5)) + (ltu:SI (reg:CC_C CC_REGNUM) + (const_int 0))))])] + " + { + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[2] = gen_lowpart (SImode, operands[2]); + }" + [(set_attr "conds" "set") + (set_attr "length" "8") + (set_attr "type" "multiple")] +) + +(define_insn "*addsi3_compareC_upper" + [(set (reg:CC_C CC_REGNUM) + (ne:CC_C + (plus:DI + (plus:DI + (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) + (plus:DI (zero_extend:DI + (plus:SI (match_dup 1) (match_dup 2))) + (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) + (set (match_operand:SI 0 "register_operand" "=r") + (plus:SI + (plus:SI (match_dup 1) (match_dup 2)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] + "TARGET_32BIT" + "adcs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "type" "adcs_reg")] +) + +(define_insn "addsi3_compareC" + [(set (reg:CC_C CC_REGNUM) + (ne:CC_C + (plus:DI + (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) + (zero_extend:DI + (plus:SI (match_dup 1) (match_dup 2))))) + (set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "adds%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "type" "alus_sreg")] +) + (define_insn "addsi3_compare0" [(set (reg:CC_NOOV CC_REGNUM) (compare:CC_NOOV @@ -873,6 +1058,75 @@ (set_attr "type" "adcs_reg")] ) +(define_expand "subv<mode>4" + [(match_operand:SIDI 0 "register_operand") + (match_operand:SIDI 1 "register_operand") + (match_operand:SIDI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); + + DONE; +}) + +(define_expand "usubv<mode>4" + [(match_operand:SIDI 0 "register_operand") + (match_operand:SIDI 1 "register_operand") + (match_operand:SIDI 2 "register_operand") + (match_operand 3 "")] + "TARGET_32BIT" +{ + emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); + arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]); + + DONE; +}) + +(define_insn_and_split "subdi3_compare1" + [(set (reg:CC CC_REGNUM) + (compare:CC + (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r"))) + (set (match_operand:DI 0 "register_operand" "=&r") + (minus:DI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "#" + "&& reload_completed" + [(parallel [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 1) (match_dup 2))) + (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) + (parallel [(set (reg:CC CC_REGNUM) + (compare:CC (match_dup 4) (match_dup 5))) + (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] + { + operands[3] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[2] = gen_lowpart (SImode, operands[2]); + } + [(set_attr "conds" "set") + (set_attr "length" "8") + (set_attr "type" "multiple")] +) + +(define_insn "subsi3_compare1" + [(set (reg:CC CC_REGNUM) + (compare:CC + (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r"))) + (set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (match_dup 1) (match_dup 2)))] + "TARGET_32BIT" + "subs%?\\t%0, %1, %2" + [(set_attr "conds" "set") + (set_attr "type" "alus_sreg")] +) + (define_insn "*subsi3_carryin" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I") @@ -4360,6 +4614,63 @@ ;; Unary arithmetic insns +(define_expand "negvsi3" + [(match_operand:SI 0 "register_operand") + (match_operand:SI 1 "register_operand") + (match_operand 2 "")] + "TARGET_32BIT" +{ + emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); + + DONE; +}) + +(define_expand "negvdi3" + [(match_operand:DI 0 "register_operand") + (match_operand:DI 1 "register_operand") + (match_operand 2 "")] + "TARGET_ARM" +{ + emit_insn (gen_negdi2_compare (operands[0], operands[1])); + arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); + + DONE; +}) + + +(define_insn_and_split "negdi2_compare" + [(set (reg:CC CC_REGNUM) + (compare:CC + (const_int 0) + (match_operand:DI 1 "register_operand" "0,r"))) + (set (match_operand:DI 0 "register_operand" "=r,&r") + (minus:DI (const_int 0) (match_dup 1)))] + "TARGET_ARM" + "#" + "&& reload_completed" + [(parallel [(set (reg:CC CC_REGNUM) + (compare:CC (const_int 0) (match_dup 1))) + (set (match_dup 0) (minus:SI (const_int 0) + (match_dup 1)))]) + (parallel [(set (reg:CC CC_REGNUM) + (compare:CC (const_int 0) (match_dup 3))) + (set (match_dup 2) + (minus:SI + (minus:SI (const_int 0) (match_dup 3)) + (ltu:SI (reg:CC_C CC_REGNUM) + (const_int 0))))])] + { + operands[2] = gen_highpart (SImode, operands[0]); + operands[0] = gen_lowpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); + operands[1] = gen_lowpart (SImode, operands[1]); + } + [(set_attr "conds" "set") + (set_attr "length" "8") + (set_attr "type" "multiple")] +) + (define_expand "negdi2" [(parallel [(set (match_operand:DI 0 "s_register_operand" "") @@ -4400,6 +4711,20 @@ (set_attr "type" "multiple")] ) +(define_insn "*negsi2_carryin_compare" + [(set (reg:CC CC_REGNUM) + (compare:CC (const_int 0) + (match_operand:SI 1 "s_register_operand" "r"))) + (set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI (minus:SI (const_int 0) + (match_dup 1)) + (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] + "TARGET_ARM" + "rscs\\t%0, %1, #0" + [(set_attr "conds" "set") + (set_attr "type" "alus_imm")] +) + (define_expand "negsi2" [(set (match_operand:SI 0 "s_register_operand" "") (neg:SI (match_operand:SI 1 "s_register_operand" "")))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 354e485..2393eb5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2016-08-24 Michael Collison <michael.collison@linaro.org> + Michael Collison <michael.collison@arm.com> + + * gcc.target/arm/builtin_saddl.c: New testcase. + * gcc.target/arm/builtin_saddll.c: New testcase. + * gcc.target/arm/builtin_uaddl.c: New testcase. + * gcc.target/arm/builtin_uaddll.c: New testcase. + * gcc.target/arm/builtin_ssubl.c: New testcase. + * gcc.target/arm/builtin_ssubll.c: New testcase. + * gcc.target/arm/builtin_usubl.c: New testcase. + * gcc.target/arm/builtin_usubll.c: New testcase. + 2016-08-24 Uros Bizjak <ubizjak@gmail.com> PR target/77270 diff --git a/gcc/testsuite/gcc.target/arm/builtin_saddl.c b/gcc/testsuite/gcc.target/arm/builtin_saddl.c new file mode 100644 index 0000000..af85594 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_saddl.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +long overflow_add (long x, long y) +{ + long r; + + int ovr = __builtin_saddl_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "adds" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_saddll.c b/gcc/testsuite/gcc.target/arm/builtin_saddll.c new file mode 100644 index 0000000..62fe6ef --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_saddll.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +long long overflow_add (long long x, long long y) +{ + long long r; + + int ovr = __builtin_saddll_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "adds" } } */ +/* { dg-final { scan-assembler "adcs" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_ssubl.c b/gcc/testsuite/gcc.target/arm/builtin_ssubl.c new file mode 100644 index 0000000..8c5a4c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_ssubl.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +long overflow_sub (long x, long y) +{ + long r; + + int ovr = __builtin_ssubl_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "subs" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_ssubll.c b/gcc/testsuite/gcc.target/arm/builtin_ssubll.c new file mode 100644 index 0000000..2048d79 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_ssubll.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +long long overflow_sub (long long x, long long y) +{ + long long r; + + int ovr = __builtin_ssubll_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "subs" } } */ +/* { dg-final { scan-assembler "sbcs" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_uaddl.c b/gcc/testsuite/gcc.target/arm/builtin_uaddl.c new file mode 100644 index 0000000..ac25766 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_uaddl.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +unsigned long overflow_add (unsigned long x, unsigned long y) +{ + unsigned long r; + + int ovr = __builtin_uaddl_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "adds" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_uaddll.c b/gcc/testsuite/gcc.target/arm/builtin_uaddll.c new file mode 100644 index 0000000..ec3188e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_uaddll.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +unsigned long long overflow_add (unsigned long long x, unsigned long long y) +{ + unsigned long long r; + + int ovr = __builtin_uaddll_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "adds" } } */ +/* { dg-final { scan-assembler "adcs" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_usubl.c b/gcc/testsuite/gcc.target/arm/builtin_usubl.c new file mode 100644 index 0000000..9978208 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_usubl.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +unsigned long overflow_sub (unsigned long x, unsigned long y) +{ + unsigned long r; + + int ovr = __builtin_usubl_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "subs" } } */ diff --git a/gcc/testsuite/gcc.target/arm/builtin_usubll.c b/gcc/testsuite/gcc.target/arm/builtin_usubll.c new file mode 100644 index 0000000..8d64660 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/builtin_usubll.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm32 } */ +extern void overflow_handler (); + +unsigned long long overflow_sub (unsigned long long x, unsigned long long y) +{ + unsigned long long r; + + int ovr = __builtin_usubll_overflow (x, y, &r); + if (ovr) + overflow_handler (); + + return r; +} + +/* { dg-final { scan-assembler "subs" } } */ +/* { dg-final { scan-assembler "sbcs" } } */ |