diff options
Diffstat (limited to '0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch')
-rw-r--r-- | 0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch | 490 |
1 files changed, 490 insertions, 0 deletions
diff --git a/0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch b/0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch new file mode 100644 index 0000000..cb06751 --- /dev/null +++ b/0151-Backport-SME-Allow-targets-to-add-USEs-to-asms.patch @@ -0,0 +1,490 @@ +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 + |