mirror of git://gcc.gnu.org/git/gcc.git
aarch64.md (subv<GPI>4, [...]): New patterns.
2018-07-19 Michael Collison <michael.collison@arm.com> Richard Henderson <rth@redhat.com> * config/aarch64/aarch64.md (subv<GPI>4, usubv<GPI>4): New patterns. (subti): Handle op1 zero. (subvti4, usub4ti4): New. (*sub<GPI>3_compare1_imm): New. (sub<GPI>3_carryinCV): New. (*sub<GPI>3_carryinCV_z1_z2, *sub<GPI>3_carryinCV_z1): New. (*sub<GPI>3_carryinCV_z2, *sub<GPI>3_carryinCV): New. 2018-07-19 Michael Collison <michael.collison@arm.com> Richard Henderson <rth@redhat.com> * config/aarch64/aarch64.md: (addv<GPI>4, uaddv<GPI>4): New. (addti3): Create simpler code if low part is already known to be 0. (addvti4, uaddvti4): New. (*add<GPI>3_compareC_cconly_imm): New. (*add<GPI>3_compareC_cconly): New. (*add<GPI>3_compareC_imm): New. (*add<GPI>3_compareC): Rename from add<GPI>3_compare1; do not handle constants within this pattern.. (*add<GPI>3_compareV_cconly_imm): New. (*add<GPI>3_compareV_cconly): New. (*add<GPI>3_compareV_imm): New. (add<GPI>3_compareV): New. (add<GPI>3_carryinC, add<GPI>3_carryinV): New. (*add<GPI>3_carryinC_zero, *add<GPI>3_carryinV_zero): New. (*add<GPI>3_carryinC, *add<GPI>3_carryinV): New. ((*add<GPI>3_compareC_cconly_imm): Replace 'ne' operator with 'comparison' operator. (*add<GPI>3_compareV_cconly_imm): Ditto. (*add<GPI>3_compareV_cconly): Ditto. (*add<GPI>3_compareV_imm): Ditto. (add<GPI>3_compareV): Ditto. (add<mode>3_carryinC): Ditto. (*add<mode>3_carryinC_zero): Ditto. (*add<mode>3_carryinC): Ditto. (add<mode>3_carryinV): Ditto. (*add<mode>3_carryinV_zero): Ditto. (*add<mode>3_carryinV): Ditto. 2018-07-19 Michael Collison <michael.collison@arm.com> Richard Henderson <rth@redhat.com> * config/aarch64/aarch64-modes.def (CC_V): New. * config/aarch64/aarch64-protos.h (aarch64_addti_scratch_regs): Declare (aarch64_subvti_scratch_regs): Declare. (aarch64_expand_subvti): Declare. (aarch64_gen_unlikely_cbranch): Declare * config/aarch64/aarch64.c (aarch64_select_cc_mode): Test for signed overflow using CC_Vmode. (aarch64_get_condition_code_1): Handle CC_Vmode. (aarch64_gen_unlikely_cbranch): New function. (aarch64_addti_scratch_regs): New function. (aarch64_subvti_scratch_regs): New function. (aarch64_expand_subvti): New function. 2018-07-19 Michael Collison <michael.collison@arm.com> Richard Henderson <rth@redhat.com> * gcc.target/aarch64/builtin_sadd_128.c: New testcase. * gcc.target/aarch64/builtin_saddl.c: New testcase. * gcc.target/aarch64/builtin_saddll.c: New testcase. * gcc.target/aarch64/builtin_uadd_128.c: New testcase. * gcc.target/aarch64/builtin_uaddl.c: New testcase. * gcc.target/aarch64/builtin_uaddll.c: New testcase. * gcc.target/aarch64/builtin_ssub_128.c: New testcase. * gcc.target/aarch64/builtin_ssubl.c: New testcase. * gcc.target/aarch64/builtin_ssubll.c: New testcase. * gcc.target/aarch64/builtin_usub_128.c: New testcase. * gcc.target/aarch64/builtin_usubl.c: New testcase. * gcc.target/aarch64/builtin_usubll.c: New testcase. Co-Authored-By: Richard Henderson <rth@redhat.com> From-SVN: r262890
This commit is contained in:
parent
c01f9216b7
commit
30c4605355
|
|
@ -1,3 +1,62 @@
|
|||
2018-07-19 Michael Collison <michael.collison@arm.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/aarch64/aarch64.md (subv<GPI>4, usubv<GPI>4): New patterns.
|
||||
(subti): Handle op1 zero.
|
||||
(subvti4, usub4ti4): New.
|
||||
(*sub<GPI>3_compare1_imm): New.
|
||||
(sub<GPI>3_carryinCV): New.
|
||||
(*sub<GPI>3_carryinCV_z1_z2, *sub<GPI>3_carryinCV_z1): New.
|
||||
(*sub<GPI>3_carryinCV_z2, *sub<GPI>3_carryinCV): New.
|
||||
|
||||
2018-07-19 Michael Collison <michael.collison@arm.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/aarch64/aarch64.md: (addv<GPI>4, uaddv<GPI>4): New.
|
||||
(addti3): Create simpler code if low part is already known to be 0.
|
||||
(addvti4, uaddvti4): New.
|
||||
(*add<GPI>3_compareC_cconly_imm): New.
|
||||
(*add<GPI>3_compareC_cconly): New.
|
||||
(*add<GPI>3_compareC_imm): New.
|
||||
(*add<GPI>3_compareC): Rename from add<GPI>3_compare1; do not
|
||||
handle constants within this pattern..
|
||||
(*add<GPI>3_compareV_cconly_imm): New.
|
||||
(*add<GPI>3_compareV_cconly): New.
|
||||
(*add<GPI>3_compareV_imm): New.
|
||||
(add<GPI>3_compareV): New.
|
||||
(add<GPI>3_carryinC, add<GPI>3_carryinV): New.
|
||||
(*add<GPI>3_carryinC_zero, *add<GPI>3_carryinV_zero): New.
|
||||
(*add<GPI>3_carryinC, *add<GPI>3_carryinV): New.
|
||||
((*add<GPI>3_compareC_cconly_imm): Replace 'ne' operator
|
||||
with 'comparison' operator.
|
||||
(*add<GPI>3_compareV_cconly_imm): Ditto.
|
||||
(*add<GPI>3_compareV_cconly): Ditto.
|
||||
(*add<GPI>3_compareV_imm): Ditto.
|
||||
(add<GPI>3_compareV): Ditto.
|
||||
(add<mode>3_carryinC): Ditto.
|
||||
(*add<mode>3_carryinC_zero): Ditto.
|
||||
(*add<mode>3_carryinC): Ditto.
|
||||
(add<mode>3_carryinV): Ditto.
|
||||
(*add<mode>3_carryinV_zero): Ditto.
|
||||
(*add<mode>3_carryinV): Ditto.
|
||||
|
||||
2018-07-19 Michael Collison <michael.collison@arm.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/aarch64/aarch64-modes.def (CC_V): New.
|
||||
* config/aarch64/aarch64-protos.h
|
||||
(aarch64_addti_scratch_regs): Declare
|
||||
(aarch64_subvti_scratch_regs): Declare.
|
||||
(aarch64_expand_subvti): Declare.
|
||||
(aarch64_gen_unlikely_cbranch): Declare
|
||||
* config/aarch64/aarch64.c (aarch64_select_cc_mode): Test
|
||||
for signed overflow using CC_Vmode.
|
||||
(aarch64_get_condition_code_1): Handle CC_Vmode.
|
||||
(aarch64_gen_unlikely_cbranch): New function.
|
||||
(aarch64_addti_scratch_regs): New function.
|
||||
(aarch64_subvti_scratch_regs): New function.
|
||||
(aarch64_expand_subvti): New function.
|
||||
|
||||
2018-07-19 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-option-extensions.def: New entry for profile
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ CC_MODE (CC_SWP);
|
|||
CC_MODE (CC_NZ); /* Only N and Z bits of condition flags are valid. */
|
||||
CC_MODE (CC_Z); /* Only Z bit of condition flags is valid. */
|
||||
CC_MODE (CC_C); /* Only C bit of condition flags is valid. */
|
||||
CC_MODE (CC_V); /* Only V bit of condition flags is valid. */
|
||||
|
||||
/* Half-precision floating point for __fp16. */
|
||||
FLOAT_MODE (HF, 2, 0);
|
||||
|
|
|
|||
|
|
@ -472,6 +472,16 @@ void aarch64_relayout_simd_types (void);
|
|||
void aarch64_reset_previous_fndecl (void);
|
||||
bool aarch64_return_address_signing_enabled (void);
|
||||
void aarch64_save_restore_target_globals (tree);
|
||||
void aarch64_addti_scratch_regs (rtx, rtx, rtx *,
|
||||
rtx *, rtx *,
|
||||
rtx *, rtx *,
|
||||
rtx *);
|
||||
void aarch64_subvti_scratch_regs (rtx, rtx, rtx *,
|
||||
rtx *, rtx *,
|
||||
rtx *, rtx *, rtx *);
|
||||
void aarch64_expand_subvti (rtx, rtx, rtx,
|
||||
rtx, rtx, rtx, rtx);
|
||||
|
||||
|
||||
/* Initialize builtins for SIMD intrinsics. */
|
||||
void init_aarch64_simd_builtins (void);
|
||||
|
|
@ -498,7 +508,8 @@ void aarch64_split_simd_move (rtx, rtx);
|
|||
bool aarch64_float_const_representable_p (rtx);
|
||||
|
||||
#if defined (RTX_CODE)
|
||||
|
||||
void aarch64_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode,
|
||||
rtx label_ref);
|
||||
bool aarch64_legitimate_address_p (machine_mode, rtx, bool,
|
||||
aarch64_addr_query_type = ADDR_QUERY_M);
|
||||
machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
|
||||
|
|
|
|||
|
|
@ -6414,6 +6414,13 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
|
|||
&& GET_CODE (y) == ZERO_EXTEND)
|
||||
return CC_Cmode;
|
||||
|
||||
/* A test for signed overflow. */
|
||||
if ((GET_MODE (x) == DImode || GET_MODE (x) == TImode)
|
||||
&& code == NE
|
||||
&& GET_CODE (x) == PLUS
|
||||
&& GET_CODE (y) == SIGN_EXTEND)
|
||||
return CC_Vmode;
|
||||
|
||||
/* For everything else, return CCmode. */
|
||||
return CCmode;
|
||||
}
|
||||
|
|
@ -6520,6 +6527,15 @@ aarch64_get_condition_code_1 (machine_mode mode, enum rtx_code comp_code)
|
|||
}
|
||||
break;
|
||||
|
||||
case E_CC_Vmode:
|
||||
switch (comp_code)
|
||||
{
|
||||
case NE: return AARCH64_VS;
|
||||
case EQ: return AARCH64_VC;
|
||||
default: return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -16274,6 +16290,131 @@ aarch64_split_dimode_const_store (rtx dst, rtx src)
|
|||
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
|
||||
aarch64_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);
|
||||
aarch64_emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
|
||||
}
|
||||
|
||||
/* Generate DImode scratch registers for 128-bit (TImode) addition.
|
||||
|
||||
OP1 represents the TImode destination operand 1
|
||||
OP2 represents the TImode destination operand 2
|
||||
LOW_DEST represents the low half (DImode) of TImode operand 0
|
||||
LOW_IN1 represents the low half (DImode) of TImode operand 1
|
||||
LOW_IN2 represents the low half (DImode) of TImode operand 2
|
||||
HIGH_DEST represents the high half (DImode) of TImode operand 0
|
||||
HIGH_IN1 represents the high half (DImode) of TImode operand 1
|
||||
HIGH_IN2 represents the high half (DImode) of TImode operand 2. */
|
||||
|
||||
void
|
||||
aarch64_addti_scratch_regs (rtx op1, rtx op2, rtx *low_dest,
|
||||
rtx *low_in1, rtx *low_in2,
|
||||
rtx *high_dest, rtx *high_in1,
|
||||
rtx *high_in2)
|
||||
{
|
||||
*low_dest = gen_reg_rtx (DImode);
|
||||
*low_in1 = gen_lowpart (DImode, op1);
|
||||
*low_in2 = simplify_gen_subreg (DImode, op2, TImode,
|
||||
subreg_lowpart_offset (DImode, TImode));
|
||||
*high_dest = gen_reg_rtx (DImode);
|
||||
*high_in1 = gen_highpart (DImode, op1);
|
||||
*high_in2 = simplify_gen_subreg (DImode, op2, TImode,
|
||||
subreg_highpart_offset (DImode, TImode));
|
||||
}
|
||||
|
||||
/* Generate DImode scratch registers for 128-bit (TImode) subtraction.
|
||||
|
||||
This function differs from 'arch64_addti_scratch_regs' in that
|
||||
OP1 can be an immediate constant (zero). We must call
|
||||
subreg_highpart_offset with DImode and TImode arguments, otherwise
|
||||
VOIDmode will be used for the const_int which generates an internal
|
||||
error from subreg_size_highpart_offset which does not expect a size of zero.
|
||||
|
||||
OP1 represents the TImode destination operand 1
|
||||
OP2 represents the TImode destination operand 2
|
||||
LOW_DEST represents the low half (DImode) of TImode operand 0
|
||||
LOW_IN1 represents the low half (DImode) of TImode operand 1
|
||||
LOW_IN2 represents the low half (DImode) of TImode operand 2
|
||||
HIGH_DEST represents the high half (DImode) of TImode operand 0
|
||||
HIGH_IN1 represents the high half (DImode) of TImode operand 1
|
||||
HIGH_IN2 represents the high half (DImode) of TImode operand 2. */
|
||||
|
||||
|
||||
void
|
||||
aarch64_subvti_scratch_regs (rtx op1, rtx op2, rtx *low_dest,
|
||||
rtx *low_in1, rtx *low_in2,
|
||||
rtx *high_dest, rtx *high_in1,
|
||||
rtx *high_in2)
|
||||
{
|
||||
*low_dest = gen_reg_rtx (DImode);
|
||||
*low_in1 = simplify_gen_subreg (DImode, op1, TImode,
|
||||
subreg_lowpart_offset (DImode, TImode));
|
||||
|
||||
*low_in2 = simplify_gen_subreg (DImode, op2, TImode,
|
||||
subreg_lowpart_offset (DImode, TImode));
|
||||
*high_dest = gen_reg_rtx (DImode);
|
||||
|
||||
*high_in1 = simplify_gen_subreg (DImode, op1, TImode,
|
||||
subreg_highpart_offset (DImode, TImode));
|
||||
*high_in2 = simplify_gen_subreg (DImode, op2, TImode,
|
||||
subreg_highpart_offset (DImode, TImode));
|
||||
}
|
||||
|
||||
/* Generate RTL for 128-bit (TImode) subtraction with overflow.
|
||||
|
||||
OP0 represents the TImode destination operand 0
|
||||
LOW_DEST represents the low half (DImode) of TImode operand 0
|
||||
LOW_IN1 represents the low half (DImode) of TImode operand 1
|
||||
LOW_IN2 represents the low half (DImode) of TImode operand 2
|
||||
HIGH_DEST represents the high half (DImode) of TImode operand 0
|
||||
HIGH_IN1 represents the high half (DImode) of TImode operand 1
|
||||
HIGH_IN2 represents the high half (DImode) of TImode operand 2. */
|
||||
|
||||
void
|
||||
aarch64_expand_subvti (rtx op0, rtx low_dest, rtx low_in1,
|
||||
rtx low_in2, rtx high_dest, rtx high_in1,
|
||||
rtx high_in2)
|
||||
{
|
||||
if (low_in2 == const0_rtx)
|
||||
{
|
||||
low_dest = low_in1;
|
||||
emit_insn (gen_subdi3_compare1 (high_dest, high_in1,
|
||||
force_reg (DImode, high_in2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CONST_INT_P (low_in2))
|
||||
{
|
||||
low_in2 = force_reg (DImode, GEN_INT (-UINTVAL (low_in2)));
|
||||
high_in2 = force_reg (DImode, high_in2);
|
||||
emit_insn (gen_adddi3_compareC (low_dest, low_in1, low_in2));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_subdi3_compare1 (low_dest, low_in1, low_in2));
|
||||
emit_insn (gen_subdi3_carryinCV (high_dest,
|
||||
force_reg (DImode, high_in1),
|
||||
high_in2));
|
||||
}
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, op0), low_dest);
|
||||
emit_move_insn (gen_highpart (DImode, op0), high_dest);
|
||||
|
||||
}
|
||||
|
||||
/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
|
||||
|
||||
static unsigned HOST_WIDE_INT
|
||||
|
|
|
|||
|
|
@ -1726,25 +1726,133 @@
|
|||
}
|
||||
)
|
||||
|
||||
(define_expand "addv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "register_operand")
|
||||
(match_operand:GPI 2 "register_operand")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "uaddv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "register_operand")
|
||||
(match_operand:GPI 2 "register_operand")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "addti3"
|
||||
[(set (match_operand:TI 0 "register_operand" "")
|
||||
(plus:TI (match_operand:TI 1 "register_operand" "")
|
||||
(match_operand:TI 2 "register_operand" "")))]
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm" "")))]
|
||||
""
|
||||
{
|
||||
rtx low = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_adddi3_compareC (low, gen_lowpart (DImode, operands[1]),
|
||||
gen_lowpart (DImode, operands[2])));
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
rtx high = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_adddi3_carryin (high, gen_highpart (DImode, operands[1]),
|
||||
gen_highpart (DImode, operands[2])));
|
||||
aarch64_addti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
|
||||
if (op2_low == const0_rtx)
|
||||
{
|
||||
low_dest = op1_low;
|
||||
if (!aarch64_pluslong_operand (op2_high, DImode))
|
||||
op2_high = force_reg (DImode, op2_high);
|
||||
emit_insn (gen_adddi3 (high_dest, op1_high, op2_high));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_adddi3_compareC (low_dest, op1_low,
|
||||
force_reg (DImode, op2_low)));
|
||||
emit_insn (gen_adddi3_carryin (high_dest, op1_high,
|
||||
force_reg (DImode, op2_high)));
|
||||
}
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "addvti4"
|
||||
[(match_operand:TI 0 "register_operand" "")
|
||||
(match_operand:TI 1 "register_operand" "")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm" "")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
aarch64_addti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
|
||||
if (op2_low == const0_rtx)
|
||||
{
|
||||
low_dest = op1_low;
|
||||
emit_insn (gen_adddi3_compareV (high_dest, op1_high,
|
||||
force_reg (DImode, op2_high)));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_adddi3_compareC (low_dest, op1_low,
|
||||
force_reg (DImode, op2_low)));
|
||||
emit_insn (gen_adddi3_carryinV (high_dest, op1_high,
|
||||
force_reg (DImode, op2_high)));
|
||||
}
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "uaddvti4"
|
||||
[(match_operand:TI 0 "register_operand" "")
|
||||
(match_operand:TI 1 "register_operand" "")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm" "")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
aarch64_addti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
|
||||
if (op2_low == const0_rtx)
|
||||
{
|
||||
low_dest = op1_low;
|
||||
emit_insn (gen_adddi3_compareC (high_dest, op1_high,
|
||||
force_reg (DImode, op2_high)));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_adddi3_compareC (low_dest, op1_low,
|
||||
force_reg (DImode, op2_low)));
|
||||
emit_insn (gen_adddi3_carryinC (high_dest, op1_high,
|
||||
force_reg (DImode, op2_high)));
|
||||
}
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "add<mode>3_compare0"
|
||||
[(set (reg:CC_NZ CC_REGNUM)
|
||||
(compare:CC_NZ
|
||||
|
|
@ -1830,7 +1938,7 @@
|
|||
|
||||
(define_insn "add<mode>3_compareC"
|
||||
[(set (reg:CC_C CC_REGNUM)
|
||||
(ne:CC_C
|
||||
(compare:CC_C
|
||||
(plus:<DWI>
|
||||
(zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
|
||||
(zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
|
||||
|
|
@ -1843,10 +1951,71 @@
|
|||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_compareV_cconly_imm"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI> (match_operand:GPI 0 "register_operand" "r,r"))
|
||||
(match_operand:<DWI> 1 "const_scalar_int_operand" ""))
|
||||
(sign_extend:<DWI>
|
||||
(plus:GPI
|
||||
(match_dup 0)
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))))]
|
||||
"INTVAL (operands[1]) == INTVAL (operands[2])"
|
||||
"@
|
||||
cmn\\t%<w>0, %<w>1
|
||||
cmp\\t%<w>0, #%n1"
|
||||
[(set_attr "type" "alus_imm")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_compareV_cconly"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI> (match_operand:GPI 0 "register_operand" "r"))
|
||||
(sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
|
||||
(sign_extend:<DWI> (plus:GPI (match_dup 0) (match_dup 1)))))]
|
||||
""
|
||||
"cmn\\t%<w>0, %<w>1"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_compareV_imm"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r,r"))
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate" "I,J"))
|
||||
(sign_extend:<DWI>
|
||||
(plus:GPI (match_dup 1) (match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r,r")
|
||||
(plus:GPI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"@
|
||||
adds\\t%<w>0, %<w>1, %<w>2
|
||||
subs\\t%<w>0, %<w>1, #%n2"
|
||||
[(set_attr "type" "alus_imm,alus_imm")]
|
||||
)
|
||||
|
||||
(define_insn "add<mode>3_compareV"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r"))
|
||||
(sign_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
|
||||
(sign_extend:<DWI> (plus:GPI (match_dup 1) (match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(plus:GPI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"adds\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*adds_shift_imm_<mode>"
|
||||
[(set (reg:CC_NZ CC_REGNUM)
|
||||
(compare:CC_NZ
|
||||
(plus:GPI (ASHIFT:GPI
|
||||
(plus:GPI (ASHIFT:GPI
|
||||
(match_operand:GPI 1 "register_operand" "r")
|
||||
(match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
|
||||
(match_operand:GPI 3 "register_operand" "r"))
|
||||
|
|
@ -2213,6 +2382,138 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_expand "add<mode>3_carryinC"
|
||||
[(parallel
|
||||
[(set (match_dup 3)
|
||||
(compare:CC_C
|
||||
(plus:<DWI>
|
||||
(plus:<DWI>
|
||||
(match_dup 4)
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "")))
|
||||
(zero_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" "")))
|
||||
(zero_extend:<DWI>
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 5) (match_dup 1))
|
||||
(match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 5) (match_dup 1))
|
||||
(match_dup 2)))])]
|
||||
""
|
||||
{
|
||||
operands[3] = gen_rtx_REG (CC_Cmode, CC_REGNUM);
|
||||
operands[4] = gen_rtx_NE (<DWI>mode, operands[3], const0_rtx);
|
||||
operands[5] = gen_rtx_NE (<MODE>mode, operands[3], const0_rtx);
|
||||
})
|
||||
|
||||
(define_insn "*add<mode>3_carryinC_zero"
|
||||
[(set (reg:CC_C CC_REGNUM)
|
||||
(compare:CC_C
|
||||
(plus:<DWI>
|
||||
(match_operand:<DWI> 2 "aarch64_carry_operation" "")
|
||||
(zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
|
||||
(zero_extend:<DWI>
|
||||
(plus:GPI
|
||||
(match_operand:GPI 3 "aarch64_carry_operation" "")
|
||||
(match_dup 1)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI (match_dup 3) (match_dup 1)))]
|
||||
""
|
||||
"adcs\\t%<w>0, %<w>1, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_carryinC"
|
||||
[(set (reg:CC_C CC_REGNUM)
|
||||
(compare:CC_C
|
||||
(plus:<DWI>
|
||||
(plus:<DWI>
|
||||
(match_operand:<DWI> 3 "aarch64_carry_operation" "")
|
||||
(zero_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
|
||||
(zero_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
|
||||
(zero_extend:<DWI>
|
||||
(plus:GPI
|
||||
(plus:GPI
|
||||
(match_operand:GPI 4 "aarch64_carry_operation" "")
|
||||
(match_dup 1))
|
||||
(match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 4) (match_dup 1))
|
||||
(match_dup 2)))]
|
||||
""
|
||||
"adcs\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_expand "add<mode>3_carryinV"
|
||||
[(parallel
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(plus:<DWI>
|
||||
(match_dup 3)
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "")))
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" "")))
|
||||
(sign_extend:<DWI>
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 4) (match_dup 1))
|
||||
(match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 4) (match_dup 1))
|
||||
(match_dup 2)))])]
|
||||
""
|
||||
{
|
||||
rtx cc = gen_rtx_REG (CC_Cmode, CC_REGNUM);
|
||||
operands[3] = gen_rtx_NE (<DWI>mode, cc, const0_rtx);
|
||||
operands[4] = gen_rtx_NE (<MODE>mode, cc, const0_rtx);
|
||||
})
|
||||
|
||||
(define_insn "*add<mode>3_carryinV_zero"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(match_operand:<DWI> 2 "aarch64_carry_operation" "")
|
||||
(sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
|
||||
(sign_extend:<DWI>
|
||||
(plus:GPI
|
||||
(match_operand:GPI 3 "aarch64_carry_operation" "")
|
||||
(match_dup 1)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI (match_dup 3) (match_dup 1)))]
|
||||
""
|
||||
"adcs\\t%<w>0, %<w>1, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*add<mode>3_carryinV"
|
||||
[(set (reg:CC_V CC_REGNUM)
|
||||
(compare:CC_V
|
||||
(plus:<DWI>
|
||||
(plus:<DWI>
|
||||
(match_operand:<DWI> 3 "aarch64_carry_operation" "")
|
||||
(sign_extend:<DWI> (match_operand:GPI 1 "register_operand" "r")))
|
||||
(sign_extend:<DWI> (match_operand:GPI 2 "register_operand" "r")))
|
||||
(sign_extend:<DWI>
|
||||
(plus:GPI
|
||||
(plus:GPI
|
||||
(match_operand:GPI 4 "aarch64_carry_operation" "")
|
||||
(match_dup 1))
|
||||
(match_dup 2)))))
|
||||
(set (match_operand:GPI 0 "register_operand")
|
||||
(plus:GPI
|
||||
(plus:GPI (match_dup 4) (match_dup 1))
|
||||
(match_dup 2)))]
|
||||
""
|
||||
"adcs\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*add_uxt<mode>_shift2"
|
||||
[(set (match_operand:GPI 0 "register_operand" "=rk")
|
||||
(plus:GPI (and:GPI
|
||||
|
|
@ -2309,22 +2610,87 @@
|
|||
(set_attr "simd" "*,yes")]
|
||||
)
|
||||
|
||||
(define_expand "subv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:GPI 2 "aarch64_reg_or_zero")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "usubv<mode>4"
|
||||
[(match_operand:GPI 0 "register_operand")
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:GPI 2 "aarch64_reg_or_zero")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
|
||||
aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
|
||||
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "subti3"
|
||||
[(set (match_operand:TI 0 "register_operand" "")
|
||||
(minus:TI (match_operand:TI 1 "register_operand" "")
|
||||
(minus:TI (match_operand:TI 1 "aarch64_reg_or_zero" "")
|
||||
(match_operand:TI 2 "register_operand" "")))]
|
||||
""
|
||||
{
|
||||
rtx low = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_subdi3_compare1 (low, gen_lowpart (DImode, operands[1]),
|
||||
gen_lowpart (DImode, operands[2])));
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
rtx high = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_subdi3_carryin (high, gen_highpart (DImode, operands[1]),
|
||||
gen_highpart (DImode, operands[2])));
|
||||
aarch64_subvti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high);
|
||||
emit_insn (gen_subdi3_compare1 (low_dest, op1_low, op2_low));
|
||||
emit_insn (gen_subdi3_carryin (high_dest, op1_high, op2_high));
|
||||
|
||||
emit_move_insn (gen_lowpart (DImode, operands[0]), low_dest);
|
||||
emit_move_insn (gen_highpart (DImode, operands[0]), high_dest);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "subvti4"
|
||||
[(match_operand:TI 0 "register_operand")
|
||||
(match_operand:TI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
aarch64_subvti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
|
||||
high_dest, op1_high, op2_high);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "usubvti4"
|
||||
[(match_operand:TI 0 "register_operand")
|
||||
(match_operand:TI 1 "aarch64_reg_or_zero")
|
||||
(match_operand:TI 2 "aarch64_reg_or_imm")
|
||||
(label_ref (match_operand 3 "" ""))]
|
||||
""
|
||||
{
|
||||
rtx low_dest, op1_low, op2_low, high_dest, op1_high, op2_high;
|
||||
|
||||
aarch64_subvti_scratch_regs (operands[1], operands[2],
|
||||
&low_dest, &op1_low, &op2_low,
|
||||
&high_dest, &op1_high, &op2_high);
|
||||
aarch64_expand_subvti (operands[0], low_dest, op1_low, op2_low,
|
||||
high_dest, op1_high, op2_high);
|
||||
|
||||
aarch64_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
|
@ -2353,6 +2719,22 @@
|
|||
[(set_attr "type" "alus_sreg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_compare1_imm"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ,rZ")
|
||||
(match_operand:GPI 2 "aarch64_plus_immediate" "I,J")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r,r")
|
||||
(plus:GPI
|
||||
(match_dup 1)
|
||||
(match_operand:GPI 3 "aarch64_plus_immediate" "J,I")))]
|
||||
"UINTVAL (operands[2]) == -UINTVAL (operands[3])"
|
||||
"@
|
||||
subs\\t%<w>0, %<w>1, #%n3
|
||||
adds\\t%<w>0, %<w>1, %3"
|
||||
[(set_attr "type" "alus_imm")]
|
||||
)
|
||||
|
||||
(define_insn "sub<mode>3_compare1"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
|
|
@ -2669,6 +3051,85 @@
|
|||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_expand "sub<mode>3_carryinCV"
|
||||
[(parallel
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "aarch64_reg_or_zero" ""))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" ""))
|
||||
(ltu:<DWI> (reg:CC CC_REGNUM) (const_int 0)))))
|
||||
(set (match_operand:GPI 0 "register_operand" "")
|
||||
(minus:GPI
|
||||
(minus:GPI (match_dup 1) (match_dup 2))
|
||||
(ltu:GPI (reg:CC CC_REGNUM) (const_int 0))))])]
|
||||
""
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z1_z2"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(const_int 0)
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(neg:GPI (match_operand:GPI 1 "aarch64_borrow_operation" "")))]
|
||||
""
|
||||
"sbcs\\t%<w>0, <w>zr, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z1"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(const_int 0)
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" ""))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI
|
||||
(neg:GPI (match_dup 1))
|
||||
(match_operand:GPI 3 "aarch64_borrow_operation" "")))]
|
||||
""
|
||||
"sbcs\\t%<w>0, <w>zr, %<w>1"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV_z2"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(match_operand:<DWI> 2 "aarch64_borrow_operation" "")))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI
|
||||
(match_dup 1)
|
||||
(match_operand:GPI 3 "aarch64_borrow_operation" "")))]
|
||||
""
|
||||
"sbcs\\t%<w>0, %<w>1, <w>zr"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub<mode>3_carryinCV"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 1 "register_operand" "r"))
|
||||
(plus:<DWI>
|
||||
(sign_extend:<DWI>
|
||||
(match_operand:GPI 2 "register_operand" "r"))
|
||||
(match_operand:<DWI> 3 "aarch64_borrow_operation" ""))))
|
||||
(set (match_operand:GPI 0 "register_operand" "=r")
|
||||
(minus:GPI
|
||||
(minus:GPI (match_dup 1) (match_dup 2))
|
||||
(match_operand:GPI 4 "aarch64_borrow_operation" "")))]
|
||||
""
|
||||
"sbcs\\t%<w>0, %<w>1, %<w>2"
|
||||
[(set_attr "type" "adc_reg")]
|
||||
)
|
||||
|
||||
(define_insn "*sub_uxt<mode>_shift2"
|
||||
[(set (match_operand:GPI 0 "register_operand" "=rk")
|
||||
(minus:GPI (match_operand:GPI 4 "register_operand" "rk")
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
2018-07-19 Michael Collison <michael.collison@arm.com>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.target/aarch64/builtin_sadd_128.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_saddl.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_saddll.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_uadd_128.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_uaddl.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_uaddll.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_ssub_128.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_ssubl.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_ssubll.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_usub_128.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_usubl.c: New testcase.
|
||||
* gcc.target/aarch64/builtin_usubll.c: New testcase.
|
||||
|
||||
2018-07-19 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
Revert fix for c++/59480 (and testsuite followup)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void overflow_handler ();
|
||||
|
||||
__int128 overflow_add (__int128 x, __int128 y)
|
||||
{
|
||||
__int128 r;
|
||||
|
||||
int ovr = __builtin_add_overflow (x, y, &r);
|
||||
if (ovr)
|
||||
overflow_handler ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "adds" } } */
|
||||
/* { dg-final { scan-assembler "adcs" } } */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void overflow_handler ();
|
||||
|
||||
__int128 overflow_sub (__int128 x, __int128 y)
|
||||
{
|
||||
__int128 r;
|
||||
|
||||
int ovr = __builtin_sub_overflow (x, y, &r);
|
||||
if (ovr)
|
||||
overflow_handler ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "subs" } } */
|
||||
/* { dg-final { scan-assembler "sbcs" } } */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void overflow_handler ();
|
||||
|
||||
unsigned __int128 overflow_add (unsigned __int128 x, unsigned __int128 y)
|
||||
{
|
||||
unsigned __int128 r;
|
||||
|
||||
int ovr = __builtin_add_overflow (x, y, &r);
|
||||
if (ovr)
|
||||
overflow_handler ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "adds" } } */
|
||||
/* { dg-final { scan-assembler "adcs" } } */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void overflow_handler ();
|
||||
|
||||
unsigned __int128 overflow_sub (unsigned __int128 x, unsigned __int128 y)
|
||||
{
|
||||
unsigned __int128 r;
|
||||
|
||||
int ovr = __builtin_sub_overflow (x, y, &r);
|
||||
if (ovr)
|
||||
overflow_handler ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "subs" } } */
|
||||
/* { dg-final { scan-assembler "sbcs" } } */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
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" } } */
|
||||
|
||||
Loading…
Reference in New Issue