diff options
author | Bernd Edlinger <bernd.edlinger@hotmail.de> | 2016-06-06 12:31:59 +0000 |
---|---|---|
committer | Bernd Edlinger <edlinger@gcc.gnu.org> | 2016-06-06 12:31:59 +0000 |
commit | 93671519e202e3bc5ab592bb6318aa738e4ae58f (patch) | |
tree | 4c408260aa6953423d714fd94976bb8529014f19 /gcc/recog.c | |
parent | 690f24b7754826f08fc19119dd3a30a6c07e9919 (diff) | |
download | gcc-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.c | 32 |
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; |