aboutsummaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2010-11-13 23:04:26 +0000
committerRichard Earnshaw <rearnsha@arm.com>2010-11-13 23:04:26 +0000
commita11284af032c6940ad3628a5544184d9c62f2dc6 (patch)
tree4d5e92ee2775c360fc918228cb97e2a2af9270e3 /gcc/stmt.c
parentc5e5be9d7f91ce95348a8b875db5d6671447856c (diff)
* tm.texi.in (OVERLAPPING_REGISTER_NAMES): Document new macro.
* tm.texi: Regenerated. * output.h (decode_reg_name_and_count): Declare. * varasm.c (decode_reg_name_and_count): New function. (decode_reg_name): Reimplement using decode_reg_name_and_count. * reginfo.c (fix_register): Use decode_reg_name_and_count and iterate over all regs used. * stmt.c (expand_asm_operands): Likewise. * arm/aout.h (OVERLAPPING_REGISTER_NAMES): Define. (ADDITIONAL_REGISTER_NAMES): Remove aliases that overlap multiple machine registers. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@166722 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c80
1 files changed, 49 insertions, 31 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index c8f56f5470b..e24ed4ebb31 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -687,13 +687,14 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
{
const char *regname;
+ int nregs;
if (TREE_VALUE (tail) == error_mark_node)
return;
regname = TREE_STRING_POINTER (TREE_VALUE (tail));
- i = decode_reg_name (regname);
- if (i >= 0 || i == -4)
+ i = decode_reg_name_and_count (regname, &nregs);
+ if (i == -4)
++nclobbers;
else if (i == -2)
error ("unknown register name %qs in %<asm%>", regname);
@@ -701,14 +702,21 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
/* Mark clobbered registers. */
if (i >= 0)
{
- /* Clobbering the PIC register is an error. */
- if (i == (int) PIC_OFFSET_TABLE_REGNUM)
+ int reg;
+
+ for (reg = i; reg < i + nregs; reg++)
{
- error ("PIC register %qs clobbered in %<asm%>", regname);
- return;
- }
+ ++nclobbers;
+
+ /* Clobbering the PIC register is an error. */
+ if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
+ {
+ error ("PIC register clobbered by %qs in %<asm%>", regname);
+ return;
+ }
- SET_HARD_REG_BIT (clobbered_regs, i);
+ SET_HARD_REG_BIT (clobbered_regs, reg);
+ }
}
}
@@ -1033,7 +1041,8 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
{
const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
- int j = decode_reg_name (regname);
+ int reg, nregs;
+ int j = decode_reg_name_and_count (regname, &nregs);
rtx clobbered_reg;
if (j < 0)
@@ -1055,30 +1064,39 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
continue;
}
- /* Use QImode since that's guaranteed to clobber just one reg. */
- clobbered_reg = gen_rtx_REG (QImode, j);
-
- /* Do sanity check for overlap between clobbers and respectively
- input and outputs that hasn't been handled. Such overlap
- should have been detected and reported above. */
- if (!clobber_conflict_found)
+ for (reg = j; reg < j + nregs; reg++)
{
- int opno;
-
- /* We test the old body (obody) contents to avoid tripping
- over the under-construction body. */
- for (opno = 0; opno < noutputs; opno++)
- if (reg_overlap_mentioned_p (clobbered_reg, output_rtx[opno]))
- internal_error ("asm clobber conflict with output operand");
-
- for (opno = 0; opno < ninputs - ninout; opno++)
- if (reg_overlap_mentioned_p (clobbered_reg,
- ASM_OPERANDS_INPUT (obody, opno)))
- internal_error ("asm clobber conflict with input operand");
- }
+ /* Use QImode since that's guaranteed to clobber just
+ * one reg. */
+ clobbered_reg = gen_rtx_REG (QImode, reg);
+
+ /* Do sanity check for overlap between clobbers and
+ respectively input and outputs that hasn't been
+ handled. Such overlap should have been detected and
+ reported above. */
+ if (!clobber_conflict_found)
+ {
+ int opno;
+
+ /* We test the old body (obody) contents to avoid
+ tripping over the under-construction body. */
+ for (opno = 0; opno < noutputs; opno++)
+ if (reg_overlap_mentioned_p (clobbered_reg,
+ output_rtx[opno]))
+ internal_error
+ ("asm clobber conflict with output operand");
+
+ for (opno = 0; opno < ninputs - ninout; opno++)
+ if (reg_overlap_mentioned_p (clobbered_reg,
+ ASM_OPERANDS_INPUT (obody,
+ opno)))
+ internal_error
+ ("asm clobber conflict with input operand");
+ }
- XVECEXP (body, 0, i++)
- = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+ XVECEXP (body, 0, i++)
+ = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
+ }
}
if (nlabels > 0)