rs6000.c (rs6000_emit_prologue): Do not place a RTX_FRAME_RELATED_P marker on the UNSPEC_MOVESI_FROM_CR insn.

ChangeLog:

2013-11-14  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* config/rs6000/rs6000.c (rs6000_emit_prologue): Do not place a
	RTX_FRAME_RELATED_P marker on the UNSPEC_MOVESI_FROM_CR insn.
	Instead, add USEs of all modified call-saved CR fields to the
	insn storing the result to the stack slot, and provide an
	appropriate REG_FRAME_RELATED_EXPR for that insn.
	* config/rs6000/rs6000.md ("*crsave"): New insn pattern.
	* config/rs6000/predicates.md ("crsave_operation"): New predicate.

testsuite/ChangeLog:

2013-11-14  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	* g++.dg/eh/ppc64-sighandle-cr.C: New test.

From-SVN: r204799
This commit is contained in:
Ulrich Weigand 2013-11-14 18:24:32 +00:00 committed by Ulrich Weigand
parent 2e4ceca56c
commit dc2faee140
5 changed files with 90 additions and 24 deletions

View File

@ -1,3 +1,13 @@
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* config/rs6000/rs6000.c (rs6000_emit_prologue): Do not place a
RTX_FRAME_RELATED_P marker on the UNSPEC_MOVESI_FROM_CR insn.
Instead, add USEs of all modified call-saved CR fields to the
insn storing the result to the stack slot, and provide an
appropriate REG_FRAME_RELATED_EXPR for that insn.
* config/rs6000/rs6000.md ("*crsave"): New insn pattern.
* config/rs6000/predicates.md ("crsave_operation"): New predicate.
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Alan Modra <amodra@gmail.com>

View File

@ -1538,6 +1538,26 @@
return 1;
})
;; Return 1 if OP is valid for crsave insn, known to be a PARALLEL.
(define_predicate "crsave_operation"
(match_code "parallel")
{
int count = XVECLEN (op, 0);
int i;
for (i = 1; i < count; i++)
{
rtx exp = XVECEXP (op, 0, i);
if (GET_CODE (exp) != USE
|| GET_CODE (XEXP (exp, 0)) != REG
|| GET_MODE (XEXP (exp, 0)) != CCmode
|| ! CR_REGNO_P (REGNO (XEXP (exp, 0))))
return 0;
}
return 1;
})
;; Return 1 if OP is valid for lmw insn, known to be a PARALLEL.
(define_predicate "lmw_operation"
(match_code "parallel")

View File

@ -21766,21 +21766,9 @@ rs6000_emit_prologue (void)
&& REGNO (frame_reg_rtx) != cr_save_regno
&& !(using_static_chain_p && cr_save_regno == 11))
{
rtx set;
cr_save_rtx = gen_rtx_REG (SImode, cr_save_regno);
START_USE (cr_save_regno);
insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
/* Now, there's no way that dwarf2out_frame_debug_expr is going
to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
But that's OK. All we have to do is specify that _one_ condition
code register is saved in this stack slot. The thrower's epilogue
will then restore all the call-saved registers.
We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
set = gen_rtx_SET (VOIDmode, cr_save_rtx,
gen_rtx_REG (SImode, CR2_REGNO));
add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
emit_insn (gen_movesi_from_cr (cr_save_rtx));
}
/* Do any required saving of fpr's. If only one or two to save, do
@ -22091,26 +22079,62 @@ rs6000_emit_prologue (void)
rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->cr_save_offset + frame_off));
rtx mem = gen_frame_mem (SImode, addr);
/* See the large comment above about why CR2_REGNO is used. */
rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
/* If we didn't copy cr before, do so now using r0. */
if (cr_save_rtx == NULL_RTX)
{
rtx set;
START_USE (0);
cr_save_rtx = gen_rtx_REG (SImode, 0);
insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
emit_insn (gen_movesi_from_cr (cr_save_rtx));
}
insn = emit_move_insn (mem, cr_save_rtx);
/* Saving CR requires a two-instruction sequence: one instruction
to move the CR to a general-purpose register, and a second
instruction that stores the GPR to memory.
We do not emit any DWARF CFI records for the first of these,
because we cannot properly represent the fact that CR is saved in
a register. One reason is that we cannot express that multiple
CR fields are saved; another reason is that on 64-bit, the size
of the CR register in DWARF (4 bytes) differs from the size of
a general-purpose register.
This means if any intervening instruction were to clobber one of
the call-saved CR fields, we'd have incorrect CFI. To prevent
this from happening, we mark the store to memory as a use of
those CR fields, which prevents any such instruction from being
scheduled in between the two instructions. */
rtx crsave_v[9];
int n_crsave = 0;
int i;
crsave_v[n_crsave++] = gen_rtx_SET (VOIDmode, mem, cr_save_rtx);
for (i = 0; i < 8; i++)
if (save_reg_p (CR0_REGNO + i))
crsave_v[n_crsave++]
= gen_rtx_USE (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO + i));
insn = emit_insn (gen_rtx_PARALLEL (VOIDmode,
gen_rtvec_v (n_crsave, crsave_v)));
END_USE (REGNO (cr_save_rtx));
rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
NULL_RTX, NULL_RTX);
/* Now, there's no way that dwarf2out_frame_debug_expr is going to
understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)',
so we need to construct a frame expression manually. */
RTX_FRAME_RELATED_P (insn) = 1;
/* Update address to be stack-pointer relative, like
rs6000_frame_related would do. */
addr = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM),
GEN_INT (info->cr_save_offset + sp_off));
mem = gen_frame_mem (SImode, addr);
/* We still cannot express that multiple CR fields are saved in the
CR save slot. By convention, we use a single CR regnum to represent
the fact that all call-saved CR fields are saved. We use CR2_REGNO
to be compatible with gcc-2.95 on Linux. */
rtx set = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, CR2_REGNO));
add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
}
/* Update stack and set back pointer unless this is V.4,

View File

@ -15035,6 +15035,14 @@
"mfcr %0"
[(set_attr "type" "mfcr")])
(define_insn "*crsave"
[(match_parallel 0 "crsave_operation"
[(set (match_operand:SI 1 "memory_operand" "=m")
(match_operand:SI 2 "gpc_reg_operand" "r"))])]
""
"stw %2,%1"
[(set_attr "type" "store")])
(define_insn "*stmw"
[(match_parallel 0 "stmw_operation"
[(set (match_operand:SI 1 "memory_operand" "=m")

View File

@ -1,3 +1,7 @@
2013-11-14 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* g++.dg/eh/ppc64-sighandle-cr.C: New test.
2013-11-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc.dg/torture/float128-cmp-invalid.c: Require fenv_exceptions.