summaryrefslogtreecommitdiff
path: root/gcc/cfgexpand.c
diff options
context:
space:
mode:
authoredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-06 12:31:59 +0000
committeredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-06 12:31:59 +0000
commit43ac2f2f6bd2bf1281103b4bef4fafaed627039f (patch)
tree4c408260aa6953423d714fd94976bb8529014f19 /gcc/cfgexpand.c
parent7e1786b2dd58add72150b4221d2cabf04e181b0a (diff)
downloadgcc-43ac2f2f6bd2bf1281103b4bef4fafaed627039f.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237133 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r--gcc/cfgexpand.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 56ef71dfbab..e4ddb3aac9f 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2674,15 +2674,40 @@ expand_asm_loc (tree string, int vol, location_t locus)
{
rtx body;
- if (TREE_CODE (string) == ADDR_EXPR)
- string = TREE_OPERAND (string, 0);
-
body = gen_rtx_ASM_INPUT_loc (VOIDmode,
ggc_strdup (TREE_STRING_POINTER (string)),
locus);
MEM_VOLATILE_P (body) = vol;
+ /* Non-empty basic ASM implicitly clobbers memory. */
+ if (TREE_STRING_LENGTH (string) != 0)
+ {
+ rtx asm_op, clob;
+ unsigned i, nclobbers;
+ auto_vec<rtx> input_rvec, output_rvec;
+ auto_vec<const char *> constraints;
+ auto_vec<rtx> clobber_rvec;
+ HARD_REG_SET clobbered_regs;
+ CLEAR_HARD_REG_SET (clobbered_regs);
+
+ clob = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
+ clobber_rvec.safe_push (clob);
+
+ if (targetm.md_asm_adjust)
+ targetm.md_asm_adjust (output_rvec, input_rvec,
+ constraints, clobber_rvec,
+ clobbered_regs);
+
+ asm_op = body;
+ nclobbers = clobber_rvec.length ();
+ body = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (1 + nclobbers));
+
+ XVECEXP (body, 0, 0) = asm_op;
+ for (i = 0; i < nclobbers; i++)
+ XVECEXP (body, 0, i + 1) = gen_rtx_CLOBBER (VOIDmode, clobber_rvec[i]);
+ }
+
emit_insn (body);
}