aboutsummaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2016-06-06 12:31:59 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2016-06-06 12:31:59 +0000
commit93671519e202e3bc5ab592bb6318aa738e4ae58f (patch)
tree4c408260aa6953423d714fd94976bb8529014f19 /gcc/recog.c
parent690f24b7754826f08fc19119dd3a30a6c07e9919 (diff)
downloadgcc-93671519e202e3bc5ab592bb6318aa738e4ae58f.zip
gcc-93671519e202e3bc5ab592bb6318aa738e4ae58f.tar.gz
gcc-93671519e202e3bc5ab592bb6318aa738e4ae58f.tar.bz2
re PR c/24414 (Old-style asms don't clobber memory)
gcc/ 2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c/24414 * cfgexpand.c (expand_asm_loc): Remove handling for ADDR_EXPR. Implicitly clobber memory for basic asm with non-empty assembler string. Use targetm.md_asm_adjust also here. * compare-elim.c (arithmetic_flags_clobber_p): Use asm_noperands here. * final.c (final_scan_insn): Handle basic asm in PARALLEL block. * gimple.c (gimple_asm_clobbers_memory_p): Handle basic asm with non-empty assembler string. * ira.c (compute_regs_asm_clobbered): Use asm_noperands here. * recog.c (asm_noperands): Handle basic asm in PARALLEL block. (decode_asm_operands): Handle basic asm in PARALLEL block. (extract_insn): Handle basic asm in PARALLEL block. * doc/extend.texi: Mention new behavior of basic asm. * config/ia64/ia64 (rtx_needs_barrier): Handle ASM_INPUT here. * config/pa/pa.c (branch_to_delay_slot_p, branch_needs_nop_p, branch_needs_nop_p): Use asm_noperands. gcc/testsuite/ 2016-06-06 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c/24414 * gcc.target/i386/pr24414.c: New test. From-SVN: r237133
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 92b2aa3..80d1779 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1470,22 +1470,34 @@ extract_asm_operands (rtx body)
/* If BODY is an insn body that uses ASM_OPERANDS,
return the number of operands (both input and output) in the insn.
+ If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
+ return 0.
Otherwise return -1. */
int
asm_noperands (const_rtx body)
{
rtx asm_op = extract_asm_operands (CONST_CAST_RTX (body));
- int n_sets = 0;
+ int i, n_sets = 0;
if (asm_op == NULL)
- return -1;
+ {
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) >= 2
+ && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
+ {
+ /* body is [(asm_input ...) (clobber (reg ...))...]. */
+ for (i = XVECLEN (body, 0) - 1; i > 0; i--)
+ if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
+ return -1;
+ return 0;
+ }
+ return -1;
+ }
if (GET_CODE (body) == SET)
n_sets = 1;
else if (GET_CODE (body) == PARALLEL)
{
- int i;
if (GET_CODE (XVECEXP (body, 0, 0)) == SET)
{
/* Multiple output operands, or 1 output plus some clobbers:
@@ -1540,9 +1552,12 @@ asm_noperands (const_rtx body)
the locations of the operands within the insn into the vector OPERAND_LOCS,
and the constraints for the operands into CONSTRAINTS.
Write the modes of the operands into MODES.
+ Write the location info into LOC.
Return the assembler-template.
+ If BODY is an insn body that uses ASM_INPUT with CLOBBERS in PARALLEL,
+ return the basic assembly string.
- If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
+ If LOC, MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
we don't store that info. */
const char *
@@ -1603,6 +1618,12 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
}
nbase = i;
}
+ else if (GET_CODE (asmop) == ASM_INPUT)
+ {
+ if (loc)
+ *loc = ASM_INPUT_SOURCE_LOCATION (asmop);
+ return XSTR (asmop, 0);
+ }
break;
}
@@ -2245,7 +2266,8 @@ extract_insn (rtx_insn *insn)
case PARALLEL:
if ((GET_CODE (XVECEXP (body, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
- || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
+ || GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS
+ || GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
goto asm_insn;
else
goto normal_insn;