diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2010-11-13 23:04:26 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@arm.com> | 2010-11-13 23:04:26 +0000 |
commit | a11284af032c6940ad3628a5544184d9c62f2dc6 (patch) | |
tree | 4d5e92ee2775c360fc918228cb97e2a2af9270e3 /gcc/stmt.c | |
parent | c5e5be9d7f91ce95348a8b875db5d6671447856c (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.c | 80 |
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) |