aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 672fc57..8fa392f 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3010,6 +3010,55 @@ expand_asm_stmt (gasm *stmt)
&allows_mem, &allows_reg, &is_inout))
return;
+ /* If the output is a hard register, verify it doesn't conflict with
+ any other operand's possible hard register use. */
+ if (DECL_P (val)
+ && REG_P (DECL_RTL (val))
+ && HARD_REGISTER_P (DECL_RTL (val)))
+ {
+ unsigned j, output_hregno = REGNO (DECL_RTL (val));
+ bool early_clobber_p = strchr (constraints[i], '&') != NULL;
+ unsigned long match;
+
+ /* Verify the other outputs do not use the same hard register. */
+ for (j = i + 1; j < noutputs; ++j)
+ if (DECL_P (output_tvec[j])
+ && REG_P (DECL_RTL (output_tvec[j]))
+ && HARD_REGISTER_P (DECL_RTL (output_tvec[j]))
+ && output_hregno == REGNO (DECL_RTL (output_tvec[j])))
+ error ("invalid hard register usage between output operands");
+
+ /* Verify matching constraint operands use the same hard register
+ and that the non-matching constraint operands do not use the same
+ hard register if the output is an early clobber operand. */
+ for (j = 0; j < ninputs; ++j)
+ if (DECL_P (input_tvec[j])
+ && REG_P (DECL_RTL (input_tvec[j]))
+ && HARD_REGISTER_P (DECL_RTL (input_tvec[j])))
+ {
+ unsigned input_hregno = REGNO (DECL_RTL (input_tvec[j]));
+ switch (*constraints[j + noutputs])
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ match = strtoul (constraints[j + noutputs], NULL, 10);
+ break;
+ default:
+ match = ULONG_MAX;
+ break;
+ }
+ if (i == match
+ && output_hregno != input_hregno)
+ error ("invalid hard register usage between output operand "
+ "and matching constraint operand");
+ else if (early_clobber_p
+ && i != match
+ && output_hregno == input_hregno)
+ error ("invalid hard register usage between earlyclobber "
+ "operand and input operand");
+ }
+ }
+
if (! allows_reg
&& (allows_mem
|| is_inout