491 lines
21 KiB
Diff
491 lines
21 KiB
Diff
From 8684458c3faf358e5a15dfb73b4ef632341ddf0a Mon Sep 17 00:00:00 2001
|
||
From: Richard Sandiford <richard.sandiford@arm.com>
|
||
Date: Tue, 5 Dec 2023 09:52:41 +0000
|
||
Subject: [PATCH 052/157] [Backport][SME] Allow targets to add USEs to asms
|
||
|
||
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=414d795d8a365b6e72a84257caa36cb3bed7e0ba
|
||
|
||
Arm's SME has an array called ZA that for inline asm purposes
|
||
is effectively a form of special-purpose memory. It doesn't
|
||
have an associated storage type and so can't be passed and
|
||
returned in normal C/C++ objects.
|
||
|
||
We'd therefore like "za" in a clobber list to mean that an inline
|
||
asm can read from and write to ZA. (Just reading or writing
|
||
individually is unlikely to be useful, but we could add syntax
|
||
for that too if necessary.)
|
||
|
||
There is currently a TARGET_MD_ASM_ADJUST target hook that allows
|
||
targets to add clobbers to an asm instruction. This patch
|
||
extends that to allow targets to add USEs as well.
|
||
|
||
gcc/
|
||
* target.def (md_asm_adjust): Add a uses parameter.
|
||
* doc/tm.texi: Regenerate.
|
||
* cfgexpand.cc (expand_asm_loc): Update call to md_asm_adjust.
|
||
Handle any USEs created by the target.
|
||
(expand_asm_stmt): Likewise.
|
||
* recog.cc (asm_noperands): Handle asms with USEs.
|
||
(decode_asm_operands): Likewise.
|
||
* config/arm/aarch-common-protos.h (arm_md_asm_adjust): Add uses
|
||
parameter.
|
||
* config/arm/aarch-common.cc (arm_md_asm_adjust): Likewise.
|
||
* config/arm/arm.cc (thumb1_md_asm_adjust): Likewise.
|
||
* config/avr/avr.cc (avr_md_asm_adjust): Likewise.
|
||
* config/cris/cris.cc (cris_md_asm_adjust): Likewise.
|
||
* config/i386/i386.cc (ix86_md_asm_adjust): Likewise.
|
||
* config/mn10300/mn10300.cc (mn10300_md_asm_adjust): Likewise.
|
||
* config/nds32/nds32.cc (nds32_md_asm_adjust): Likewise.
|
||
* config/pdp11/pdp11.cc (pdp11_md_asm_adjust): Likewise.
|
||
* config/rs6000/rs6000.cc (rs6000_md_asm_adjust): Likewise.
|
||
* config/s390/s390.cc (s390_md_asm_adjust): Likewise.
|
||
* config/vax/vax.cc (vax_md_asm_adjust): Likewise.
|
||
* config/visium/visium.cc (visium_md_asm_adjust): Likewise.
|
||
---
|
||
gcc/cfgexpand.cc | 37 +++++++++++++++++++---------
|
||
gcc/config/arm/aarch-common-protos.h | 2 +-
|
||
gcc/config/arm/aarch-common.cc | 3 ++-
|
||
gcc/config/arm/arm.cc | 5 ++--
|
||
gcc/config/avr/avr.cc | 1 +
|
||
gcc/config/cris/cris.cc | 6 +++--
|
||
gcc/config/i386/i386.cc | 5 ++--
|
||
gcc/config/mn10300/mn10300.cc | 3 ++-
|
||
gcc/config/nds32/nds32.cc | 4 +--
|
||
gcc/config/pdp11/pdp11.cc | 6 +++--
|
||
gcc/config/rs6000/rs6000.cc | 3 ++-
|
||
gcc/config/s390/s390.cc | 3 ++-
|
||
gcc/config/vax/vax.cc | 4 ++-
|
||
gcc/config/visium/visium.cc | 5 ++--
|
||
gcc/doc/tm.texi | 5 ++--
|
||
gcc/recog.cc | 20 ++++++++++-----
|
||
gcc/target.def | 5 ++--
|
||
17 files changed, 77 insertions(+), 40 deletions(-)
|
||
|
||
diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
|
||
index 4691355aa..5401a4ebd 100644
|
||
--- a/gcc/cfgexpand.cc
|
||
+++ b/gcc/cfgexpand.cc
|
||
@@ -2873,6 +2873,7 @@ expand_asm_loc (tree string, int vol, location_t locus)
|
||
auto_vec<rtx> input_rvec, output_rvec;
|
||
auto_vec<machine_mode> input_mode;
|
||
auto_vec<const char *> constraints;
|
||
+ auto_vec<rtx> use_rvec;
|
||
auto_vec<rtx> clobber_rvec;
|
||
HARD_REG_SET clobbered_regs;
|
||
CLEAR_HARD_REG_SET (clobbered_regs);
|
||
@@ -2882,16 +2883,20 @@ expand_asm_loc (tree string, int vol, location_t locus)
|
||
|
||
if (targetm.md_asm_adjust)
|
||
targetm.md_asm_adjust (output_rvec, input_rvec, input_mode,
|
||
- constraints, clobber_rvec, clobbered_regs,
|
||
- locus);
|
||
+ constraints, use_rvec, clobber_rvec,
|
||
+ clobbered_regs, locus);
|
||
|
||
asm_op = body;
|
||
nclobbers = clobber_rvec.length ();
|
||
- body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nclobbers));
|
||
+ auto nuses = use_rvec.length ();
|
||
+ body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nuses + nclobbers));
|
||
|
||
- XVECEXP (body, 0, 0) = asm_op;
|
||
- for (i = 0; i < nclobbers; i++)
|
||
- XVECEXP (body, 0, i + 1) = gen_rtx_CLOBBER (VOIDmode, clobber_rvec[i]);
|
||
+ i = 0;
|
||
+ XVECEXP (body, 0, i++) = asm_op;
|
||
+ for (rtx use : use_rvec)
|
||
+ XVECEXP (body, 0, i++) = gen_rtx_USE (VOIDmode, use);
|
||
+ for (rtx clobber : clobber_rvec)
|
||
+ XVECEXP (body, 0, i++) = gen_rtx_CLOBBER (VOIDmode, clobber);
|
||
}
|
||
|
||
emit_insn (body);
|
||
@@ -3443,11 +3448,12 @@ expand_asm_stmt (gasm *stmt)
|
||
maintaining source-level compatibility means automatically clobbering
|
||
the flags register. */
|
||
rtx_insn *after_md_seq = NULL;
|
||
+ auto_vec<rtx> use_rvec;
|
||
if (targetm.md_asm_adjust)
|
||
after_md_seq
|
||
= targetm.md_asm_adjust (output_rvec, input_rvec, input_mode,
|
||
- constraints, clobber_rvec, clobbered_regs,
|
||
- locus);
|
||
+ constraints, use_rvec, clobber_rvec,
|
||
+ clobbered_regs, locus);
|
||
|
||
/* Do not allow the hook to change the output and input count,
|
||
lest it mess up the operand numbering. */
|
||
@@ -3455,7 +3461,8 @@ expand_asm_stmt (gasm *stmt)
|
||
gcc_assert (input_rvec.length() == ninputs);
|
||
gcc_assert (constraints.length() == noutputs + ninputs);
|
||
|
||
- /* But it certainly can adjust the clobbers. */
|
||
+ /* But it certainly can adjust the uses and clobbers. */
|
||
+ unsigned nuses = use_rvec.length ();
|
||
unsigned nclobbers = clobber_rvec.length ();
|
||
|
||
/* Third pass checks for easy conflicts. */
|
||
@@ -3527,7 +3534,7 @@ expand_asm_stmt (gasm *stmt)
|
||
ARGVEC CONSTRAINTS OPNAMES))
|
||
If there is more than one, put them inside a PARALLEL. */
|
||
|
||
- if (noutputs == 0 && nclobbers == 0)
|
||
+ if (noutputs == 0 && nuses == 0 && nclobbers == 0)
|
||
{
|
||
/* No output operands: put in a raw ASM_OPERANDS rtx. */
|
||
if (nlabels > 0)
|
||
@@ -3535,7 +3542,7 @@ expand_asm_stmt (gasm *stmt)
|
||
else
|
||
emit_insn (body);
|
||
}
|
||
- else if (noutputs == 1 && nclobbers == 0)
|
||
+ else if (noutputs == 1 && nuses == 0 && nclobbers == 0)
|
||
{
|
||
ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = constraints[0];
|
||
if (nlabels > 0)
|
||
@@ -3551,7 +3558,8 @@ expand_asm_stmt (gasm *stmt)
|
||
if (num == 0)
|
||
num = 1;
|
||
|
||
- body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num + nclobbers));
|
||
+ body = gen_rtx_PARALLEL (VOIDmode,
|
||
+ rtvec_alloc (num + nuses + nclobbers));
|
||
|
||
/* For each output operand, store a SET. */
|
||
for (i = 0; i < noutputs; ++i)
|
||
@@ -3578,6 +3586,11 @@ expand_asm_stmt (gasm *stmt)
|
||
if (i == 0)
|
||
XVECEXP (body, 0, i++) = obody;
|
||
|
||
+ /* Add the uses specified by the target hook. No checking should
|
||
+ be needed since this doesn't come directly from user code. */
|
||
+ for (rtx use : use_rvec)
|
||
+ XVECEXP (body, 0, i++) = gen_rtx_USE (VOIDmode, use);
|
||
+
|
||
/* Store (clobber REG) for each clobbered register specified. */
|
||
for (unsigned j = 0; j < nclobbers; ++j)
|
||
{
|
||
diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h
|
||
index ae0465159..3b525c174 100644
|
||
--- a/gcc/config/arm/aarch-common-protos.h
|
||
+++ b/gcc/config/arm/aarch-common-protos.h
|
||
@@ -149,7 +149,7 @@ struct cpu_cost_table
|
||
|
||
rtx_insn *arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> &constraints,
|
||
+ vec<const char *> &constraints, vec<rtx> &,
|
||
vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
|
||
location_t loc);
|
||
|
||
diff --git a/gcc/config/arm/aarch-common.cc b/gcc/config/arm/aarch-common.cc
|
||
index 04a53d750..365cfc140 100644
|
||
--- a/gcc/config/arm/aarch-common.cc
|
||
+++ b/gcc/config/arm/aarch-common.cc
|
||
@@ -533,7 +533,8 @@ arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer)
|
||
rtx_insn *
|
||
arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> &constraints, vec<rtx> & /*clobbers*/,
|
||
+ vec<const char *> &constraints,
|
||
+ vec<rtx> & /*uses*/, vec<rtx> & /*clobbers*/,
|
||
HARD_REG_SET & /*clobbered_regs*/, location_t loc)
|
||
{
|
||
bool saw_asm_flag = false;
|
||
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
|
||
index b700c23b8..c72e9c0b0 100644
|
||
--- a/gcc/config/arm/arm.cc
|
||
+++ b/gcc/config/arm/arm.cc
|
||
@@ -325,7 +325,7 @@ static HOST_WIDE_INT arm_constant_alignment (const_tree, HOST_WIDE_INT);
|
||
static rtx_insn *thumb1_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||
vec<machine_mode> &,
|
||
vec<const char *> &, vec<rtx> &,
|
||
- HARD_REG_SET &, location_t);
|
||
+ vec<rtx> &, HARD_REG_SET &, location_t);
|
||
static const char *arm_identify_fpu_from_isa (sbitmap);
|
||
|
||
/* Table of machine attributes. */
|
||
@@ -34209,7 +34209,8 @@ arm_stack_protect_guard (void)
|
||
rtx_insn *
|
||
thumb1_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> &constraints, vec<rtx> & /*clobbers*/,
|
||
+ vec<const char *> &constraints,
|
||
+ vec<rtx> &, vec<rtx> & /*clobbers*/,
|
||
HARD_REG_SET & /*clobbered_regs*/, location_t /*loc*/)
|
||
{
|
||
for (unsigned i = 0, n = outputs.length (); i < n; ++i)
|
||
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
|
||
index 4ed390e4c..1b5a95410 100644
|
||
--- a/gcc/config/avr/avr.cc
|
||
+++ b/gcc/config/avr/avr.cc
|
||
@@ -14497,6 +14497,7 @@ static rtx_insn *
|
||
avr_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
vec<const char *> &/*constraints*/,
|
||
+ vec<rtx> &/*uses*/,
|
||
vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
|
||
location_t /*loc*/)
|
||
{
|
||
diff --git a/gcc/config/cris/cris.cc b/gcc/config/cris/cris.cc
|
||
index f0017d630..3a1c85481 100644
|
||
--- a/gcc/config/cris/cris.cc
|
||
+++ b/gcc/config/cris/cris.cc
|
||
@@ -151,7 +151,8 @@ static void cris_function_arg_advance (cumulative_args_t,
|
||
const function_arg_info &);
|
||
static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||
vec<machine_mode> &, vec<const char *> &,
|
||
- vec<rtx> &, HARD_REG_SET &, location_t);
|
||
+ vec<rtx> &, vec<rtx> &,
|
||
+ HARD_REG_SET &, location_t);
|
||
|
||
static void cris_option_override (void);
|
||
|
||
@@ -3506,7 +3507,8 @@ cris_function_arg_advance (cumulative_args_t ca_v,
|
||
static rtx_insn *
|
||
cris_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> &constraints, vec<rtx> &clobbers,
|
||
+ vec<const char *> &constraints,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
/* For the time being, all asms clobber condition codes.
|
||
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
|
||
index 593185fa6..83a0d8abb 100644
|
||
--- a/gcc/config/i386/i386.cc
|
||
+++ b/gcc/config/i386/i386.cc
|
||
@@ -22252,8 +22252,9 @@ ix86_c_mode_for_suffix (char suffix)
|
||
static rtx_insn *
|
||
ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> &constraints, vec<rtx> &clobbers,
|
||
- HARD_REG_SET &clobbered_regs, location_t loc)
|
||
+ vec<const char *> &constraints, vec<rtx> &/*uses*/,
|
||
+ vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
|
||
+ location_t loc)
|
||
{
|
||
bool saw_asm_flag = false;
|
||
|
||
diff --git a/gcc/config/mn10300/mn10300.cc b/gcc/config/mn10300/mn10300.cc
|
||
index 2a58dd925..2ca2c769c 100644
|
||
--- a/gcc/config/mn10300/mn10300.cc
|
||
+++ b/gcc/config/mn10300/mn10300.cc
|
||
@@ -2849,7 +2849,8 @@ mn10300_conditional_register_usage (void)
|
||
static rtx_insn *
|
||
mn10300_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
|
||
+ vec<const char *> & /*constraints*/,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
clobbers.safe_push (gen_rtx_REG (CCmode, CC_REG));
|
||
diff --git a/gcc/config/nds32/nds32.cc b/gcc/config/nds32/nds32.cc
|
||
index 71fe9e8bc..27530495f 100644
|
||
--- a/gcc/config/nds32/nds32.cc
|
||
+++ b/gcc/config/nds32/nds32.cc
|
||
@@ -4199,8 +4199,8 @@ nds32_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
|
||
vec<rtx> &inputs ATTRIBUTE_UNUSED,
|
||
vec<machine_mode> &input_modes ATTRIBUTE_UNUSED,
|
||
vec<const char *> &constraints ATTRIBUTE_UNUSED,
|
||
- vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
|
||
- location_t /*loc*/)
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
+ HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
if (!flag_inline_asm_r15)
|
||
{
|
||
diff --git a/gcc/config/pdp11/pdp11.cc b/gcc/config/pdp11/pdp11.cc
|
||
index 380223439..25cf62cbc 100644
|
||
--- a/gcc/config/pdp11/pdp11.cc
|
||
+++ b/gcc/config/pdp11/pdp11.cc
|
||
@@ -155,7 +155,8 @@ static int pdp11_addr_cost (rtx, machine_mode, addr_space_t, bool);
|
||
static int pdp11_insn_cost (rtx_insn *insn, bool speed);
|
||
static rtx_insn *pdp11_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||
vec<machine_mode> &, vec<const char *> &,
|
||
- vec<rtx> &, HARD_REG_SET &, location_t);
|
||
+ vec<rtx> &, vec<rtx> &,
|
||
+ HARD_REG_SET &, location_t);
|
||
static bool pdp11_return_in_memory (const_tree, const_tree);
|
||
static rtx pdp11_function_value (const_tree, const_tree, bool);
|
||
static rtx pdp11_libcall_value (machine_mode, const_rtx);
|
||
@@ -2137,7 +2138,8 @@ pdp11_cmp_length (rtx *operands, int words)
|
||
static rtx_insn *
|
||
pdp11_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
|
||
+ vec<const char *> & /*constraints*/,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
clobbers.safe_push (gen_rtx_REG (CCmode, CC_REGNUM));
|
||
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
|
||
index 0b75861bb..55d4ce751 100644
|
||
--- a/gcc/config/rs6000/rs6000.cc
|
||
+++ b/gcc/config/rs6000/rs6000.cc
|
||
@@ -3443,7 +3443,8 @@ rs6000_builtin_mask_calculate (void)
|
||
static rtx_insn *
|
||
rs6000_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
|
||
+ vec<const char *> & /*constraints*/,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
clobbers.safe_push (gen_rtx_REG (SImode, CA_REGNO));
|
||
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
|
||
index ae0cf9ef5..f1599a5c5 100644
|
||
--- a/gcc/config/s390/s390.cc
|
||
+++ b/gcc/config/s390/s390.cc
|
||
@@ -16994,7 +16994,8 @@ s390_hard_fp_reg_p (rtx x)
|
||
static rtx_insn *
|
||
s390_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs,
|
||
vec<machine_mode> &input_modes,
|
||
- vec<const char *> &constraints, vec<rtx> & /*clobbers*/,
|
||
+ vec<const char *> &constraints,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &/*clobbers*/,
|
||
HARD_REG_SET & /*clobbered_regs*/, location_t /*loc*/)
|
||
{
|
||
if (!TARGET_VXE)
|
||
diff --git a/gcc/config/vax/vax.cc b/gcc/config/vax/vax.cc
|
||
index 28c1af59a..7673a1428 100644
|
||
--- a/gcc/config/vax/vax.cc
|
||
+++ b/gcc/config/vax/vax.cc
|
||
@@ -57,7 +57,8 @@ static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
|
||
static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode);
|
||
static rtx_insn *vax_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||
vec<machine_mode> &, vec<const char *> &,
|
||
- vec<rtx> &, HARD_REG_SET &, location_t);
|
||
+ vec<rtx> &, vec<rtx> &, HARD_REG_SET &,
|
||
+ location_t);
|
||
static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
|
||
static void vax_function_arg_advance (cumulative_args_t,
|
||
const function_arg_info &);
|
||
@@ -1179,6 +1180,7 @@ vax_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
|
||
vec<rtx> &inputs ATTRIBUTE_UNUSED,
|
||
vec<machine_mode> &input_modes ATTRIBUTE_UNUSED,
|
||
vec<const char *> &constraints ATTRIBUTE_UNUSED,
|
||
+ vec<rtx> &/*uses*/,
|
||
vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
|
||
location_t /*loc*/)
|
||
{
|
||
diff --git a/gcc/config/visium/visium.cc b/gcc/config/visium/visium.cc
|
||
index 03c1a33e1..35b46ced9 100644
|
||
--- a/gcc/config/visium/visium.cc
|
||
+++ b/gcc/config/visium/visium.cc
|
||
@@ -190,7 +190,7 @@ static tree visium_build_builtin_va_list (void);
|
||
static rtx_insn *visium_md_asm_adjust (vec<rtx> &, vec<rtx> &,
|
||
vec<machine_mode> &,
|
||
vec<const char *> &, vec<rtx> &,
|
||
- HARD_REG_SET &, location_t);
|
||
+ vec<rtx> &, HARD_REG_SET &, location_t);
|
||
|
||
static bool visium_legitimate_constant_p (machine_mode, rtx);
|
||
|
||
@@ -794,7 +794,8 @@ visium_conditional_register_usage (void)
|
||
static rtx_insn *
|
||
visium_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
|
||
vec<machine_mode> & /*input_modes*/,
|
||
- vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
|
||
+ vec<const char *> & /*constraints*/,
|
||
+ vec<rtx> &/*uses*/, vec<rtx> &clobbers,
|
||
HARD_REG_SET &clobbered_regs, location_t /*loc*/)
|
||
{
|
||
clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REGNUM));
|
||
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
|
||
index 357c29a4d..4f93facf7 100644
|
||
--- a/gcc/doc/tm.texi
|
||
+++ b/gcc/doc/tm.texi
|
||
@@ -11626,10 +11626,11 @@ from shared libraries (DLLs).
|
||
You need not define this macro if it would always evaluate to zero.
|
||
@end defmac
|
||
|
||
-@deftypefn {Target Hook} {rtx_insn *} TARGET_MD_ASM_ADJUST (vec<rtx>& @var{outputs}, vec<rtx>& @var{inputs}, vec<machine_mode>& @var{input_modes}, vec<const char *>& @var{constraints}, vec<rtx>& @var{clobbers}, HARD_REG_SET& @var{clobbered_regs}, location_t @var{loc})
|
||
+@deftypefn {Target Hook} {rtx_insn *} TARGET_MD_ASM_ADJUST (vec<rtx>& @var{outputs}, vec<rtx>& @var{inputs}, vec<machine_mode>& @var{input_modes}, vec<const char *>& @var{constraints}, vec<rtx>& @var{usess}, vec<rtx>& @var{clobbers}, HARD_REG_SET& @var{clobbered_regs}, location_t @var{loc})
|
||
This target hook may add @dfn{clobbers} to @var{clobbers} and
|
||
@var{clobbered_regs} for any hard regs the port wishes to automatically
|
||
-clobber for an asm. The @var{outputs} and @var{inputs} may be inspected
|
||
+clobber for an asm. It can also add hard registers that are used by the
|
||
+asm to @var{uses}. The @var{outputs} and @var{inputs} may be inspected
|
||
to avoid clobbering a register that is already used by the asm. @var{loc}
|
||
is the source location of the asm.
|
||
|
||
diff --git a/gcc/recog.cc b/gcc/recog.cc
|
||
index cd2410ab2..5b81d5e21 100644
|
||
--- a/gcc/recog.cc
|
||
+++ b/gcc/recog.cc
|
||
@@ -1977,13 +1977,17 @@ asm_noperands (const_rtx body)
|
||
{
|
||
/* Multiple output operands, or 1 output plus some clobbers:
|
||
body is
|
||
- [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...]. */
|
||
- /* Count backwards through CLOBBERs to determine number of SETs. */
|
||
+ [(set OUTPUT (asm_operands ...))...
|
||
+ (use (reg ...))...
|
||
+ (clobber (reg ...))...]. */
|
||
+ /* Count backwards through USEs and CLOBBERs to determine
|
||
+ number of SETs. */
|
||
for (i = XVECLEN (body, 0); i > 0; i--)
|
||
{
|
||
if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
|
||
break;
|
||
- if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
|
||
+ if (GET_CODE (XVECEXP (body, 0, i - 1)) != USE
|
||
+ && GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
|
||
return -1;
|
||
}
|
||
|
||
@@ -2010,10 +2014,13 @@ asm_noperands (const_rtx body)
|
||
else
|
||
{
|
||
/* 0 outputs, but some clobbers:
|
||
- body is [(asm_operands ...) (clobber (reg ...))...]. */
|
||
+ body is [(asm_operands ...)
|
||
+ (use (reg ...))...
|
||
+ (clobber (reg ...))...]. */
|
||
/* Make sure all the other parallel things really are clobbers. */
|
||
for (i = XVECLEN (body, 0) - 1; i > 0; i--)
|
||
- if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
|
||
+ if (GET_CODE (XVECEXP (body, 0, i)) != USE
|
||
+ && GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
|
||
return -1;
|
||
}
|
||
}
|
||
@@ -2080,7 +2087,8 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
|
||
the SETs. Their constraints are in the ASM_OPERANDS itself. */
|
||
for (i = 0; i < nparallel; i++)
|
||
{
|
||
- if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
|
||
+ if (GET_CODE (XVECEXP (body, 0, i)) == USE
|
||
+ || GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
|
||
break; /* Past last SET */
|
||
gcc_assert (GET_CODE (XVECEXP (body, 0, i)) == SET);
|
||
if (operands)
|
||
diff --git a/gcc/target.def b/gcc/target.def
|
||
index a57e51b0d..60096c60c 100644
|
||
--- a/gcc/target.def
|
||
+++ b/gcc/target.def
|
||
@@ -4309,7 +4309,8 @@ DEFHOOK
|
||
(md_asm_adjust,
|
||
"This target hook may add @dfn{clobbers} to @var{clobbers} and\n\
|
||
@var{clobbered_regs} for any hard regs the port wishes to automatically\n\
|
||
-clobber for an asm. The @var{outputs} and @var{inputs} may be inspected\n\
|
||
+clobber for an asm. It can also add hard registers that are used by the\n\
|
||
+asm to @var{uses}. The @var{outputs} and @var{inputs} may be inspected\n\
|
||
to avoid clobbering a register that is already used by the asm. @var{loc}\n\
|
||
is the source location of the asm.\n\
|
||
\n\
|
||
@@ -4320,7 +4321,7 @@ changes to @var{inputs} must be accompanied by the corresponding changes\n\
|
||
to @var{input_modes}.",
|
||
rtx_insn *,
|
||
(vec<rtx>& outputs, vec<rtx>& inputs, vec<machine_mode>& input_modes,
|
||
- vec<const char *>& constraints, vec<rtx>& clobbers,
|
||
+ vec<const char *>& constraints, vec<rtx>& usess, vec<rtx>& clobbers,
|
||
HARD_REG_SET& clobbered_regs, location_t loc),
|
||
NULL)
|
||
|
||
--
|
||
2.33.0
|
||
|