From: Michael Collison <Michael.Collison@arm.com>
To: GCC Patches <gcc-patches@gcc.gnu.org>
Cc: nd <nd@arm.com>
Subject: [PATCH][Aarch64] v2: Arithmetic overflow common functions [Patch 1/4]
Date: Wed, 15 Nov 2017 07:28:00 -0000 [thread overview]
Message-ID: <HE1PR0802MB2377EDFEC442E4763897AE6995290@HE1PR0802MB2377.eurprd08.prod.outlook.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]
This is a respin of a AArch64 patch that adds support for builtin arithmetic overflow operations. This update separates the patch into multiple pieces and addresses comments made by Richard Earnshaw here:
https://gcc.gnu.org/ml/gcc-patches/2017-07/msg00249.html
Original patch and motivation for patch here:
https://gcc.gnu.org/ml/gcc-patches/2017-05/msg01512.html
This patch primarily contains common functions in aarch64.c for generating TImode scratch registers,
and common rtl functions utilized by the overflow patterns in aarch64.md. In addition a new mode representing overflow, CC_Vmode is introduced.
Bootstrapped and tested on aarch64-linux-gnu. Okay for trunk?
2017-10-26 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_add_128bit_scratch_regs): Declare
(aarch64_subv_128bit_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_add_128bit_scratch_regs): New function.
(aarch64_subv_128bit_scratch_regs): New function.
(aarch64_expand_subvti): New function.
[-- Attachment #2: gnutools-6308-common-v2.patch.patch --]
[-- Type: application/octet-stream, Size: 7576 bytes --]
diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def
index 195976c..3b9a151 100644
--- a/gcc/config/aarch64/aarch64-modes.def
+++ b/gcc/config/aarch64/aarch64-modes.def
@@ -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);
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 5d7c5df..28618c3 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -415,6 +415,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_add_128bit_scratch_regs (rtx, rtx, rtx *,
+ rtx *, rtx *,
+ rtx *, rtx *,
+ rtx *);
+void aarch64_subv_128bit_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);
@@ -439,6 +449,8 @@ 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, RTX_CODE, bool);
machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d1aaf19..061d139 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5013,6 +5013,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;
}
@@ -5119,6 +5126,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;
}
@@ -14150,6 +14166,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_add_128bit_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_add_128bit_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_subv_128bit_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
next reply other threads:[~2017-11-15 7:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-15 7:28 Michael Collison [this message]
2018-06-06 17:14 Michael Collison
2018-06-08 0:19 ` James Greenhalgh
2018-06-08 21:45 ` Michael Collison
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=HE1PR0802MB2377EDFEC442E4763897AE6995290@HE1PR0802MB2377.eurprd08.prod.outlook.com \
--to=michael.collison@arm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=nd@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).