Commit 19ec6a36 by Alan Modra Committed by Alan Modra

DWARF2 frame notes for hppa.

	* dwarf2out.c (dwarf2out_frame_debug_expr): Support adjusting
	stack pointer via a LO_SUM.  Ditto for setting a temp register
	used to save to the stack.  Set cfa_temp when setting fp, and
	allow matches to cfa_temp in addition to cfa_store when saving
	regs.  Handle POST_INC and LO_SUM register stores.  Document the
	changes and errors in rule 12 doco.

	* pa.c (set_reg_plus_d, store_reg, load_reg): Return last insn.
	(actual_fsize, local_fsize, save_fregs): Move for store_reg to see.
	(load_reg): Move closer to epilogue code.
	(DO_FRAME_NOTES): Define to control the following..
	(FRP): Define to set RTX_FRAME_RELATED_P on insns.
	(hppa_expand_prologue): Use FRP and REG_FRAME_RELATED_EXPR
	notes as necessary.
	(hppa_expand_epilogue): Likewise.

From-SVN: r41074
parent 78e766a0
2001-04-04 Alan Modra <alan@linuxcare.com.au>
* dwarf2out.c (dwarf2out_frame_debug_expr): Support adjusting
stack pointer via a LO_SUM. Ditto for setting a temp register
used to save to the stack. Set cfa_temp when setting fp, and
allow matches to cfa_temp in addition to cfa_store when saving
regs. Handle POST_INC and LO_SUM register stores. Document the
changes and errors in rule 12 doco.
* pa.c (set_reg_plus_d, store_reg, load_reg): Return last insn.
(actual_fsize, local_fsize, save_fregs): Move for store_reg to see.
(load_reg): Move closer to epilogue code.
(DO_FRAME_NOTES): Define to control the following..
(FRP): Define to set RTX_FRAME_RELATED_P on insns.
(hppa_expand_prologue): Use FRP and REG_FRAME_RELATED_EXPR
notes as necessary.
(hppa_expand_epilogue): Likewise.
2001-04-03 Richard Henderson <rth@redhat.com> 2001-04-03 Richard Henderson <rth@redhat.com>
* configure.in (gcc_cv_as_leb128): Reject gas before 2.11. * configure.in (gcc_cv_as_leb128): Reject gas before 2.11.
......
...@@ -1133,11 +1133,13 @@ static dw_cfa_location cfa_temp; ...@@ -1133,11 +1133,13 @@ static dw_cfa_location cfa_temp;
cfa_store.reg to the actual CFA cfa_store.reg to the actual CFA
cfa_temp register holding an integral value. cfa_temp.offset cfa_temp register holding an integral value. cfa_temp.offset
stores the value, which will be used to adjust the stores the value, which will be used to adjust the
stack pointer. stack pointer. cfa_temp is also used like cfa_store,
to track stores to the stack via fp or a temp reg.
Rules 1- 4: Setting a register's value to cfa.reg or an expression Rules 1- 4: Setting a register's value to cfa.reg or an expression
with cfa.reg as the first operand changes the cfa.reg and its with cfa.reg as the first operand changes the cfa.reg and its
cfa.offset. cfa.offset. Rule 1 and 4 also set cfa_temp.reg and
cfa_temp.offset.
Rules 6- 9: Set a non-cfa.reg register value to a constant or an Rules 6- 9: Set a non-cfa.reg register value to a constant or an
expression yielding a constant. This sets cfa_temp.reg expression yielding a constant. This sets cfa_temp.reg
...@@ -1146,9 +1148,9 @@ static dw_cfa_location cfa_temp; ...@@ -1146,9 +1148,9 @@ static dw_cfa_location cfa_temp;
Rule 5: Create a new register cfa_store used to save items to the Rule 5: Create a new register cfa_store used to save items to the
stack. stack.
Rules 10-13: Save a register to the stack. Define offset as the Rules 10-14: Save a register to the stack. Define offset as the
difference of the original location and cfa_store's difference of the original location and cfa_store's
location. location (or cfa_temp's location if cfa_temp is used).
The Rules The Rules
...@@ -1157,26 +1159,30 @@ static dw_cfa_location cfa_temp; ...@@ -1157,26 +1159,30 @@ static dw_cfa_location cfa_temp;
Rule 1: Rule 1:
(set <reg1> <reg2>:cfa.reg) (set <reg1> <reg2>:cfa.reg)
effects: cfa.reg = <REG1> effects: cfa.reg = <reg1>
cfa.offset unchanged cfa.offset unchanged
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
Rule 2: Rule 2:
(set sp ({minus,plus} {sp,fp}:cfa.reg {<const_int>,<reg>:cfa_temp.reg})) (set sp ({minus,plus,losum} {sp,fp}:cfa.reg {<const_int>,<reg>:cfa_temp.reg}))
effects: cfa.reg = sp if fp used effects: cfa.reg = sp if fp used
cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
cfa_store.offset += {+/- <const_int>, cfa_temp.offset} cfa_store.offset += {+/- <const_int>, cfa_temp.offset}
if cfa_store.reg==sp if cfa_store.reg==sp
Rule 3: Rule 3:
(set fp ({minus,plus} <reg>:cfa.reg <const_int>)) (set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>))
effects: cfa.reg = fp effects: cfa.reg = fp
cfa_offset += +/- <const_int> cfa_offset += +/- <const_int>
Rule 4: Rule 4:
(set <reg1> (plus <reg2>:cfa.reg <const_int>)) (set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>))
constraints: <reg1> != fp constraints: <reg1> != fp
<reg1> != sp <reg1> != sp
effects: cfa.reg = <reg1> effects: cfa.reg = <reg1>
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
Rule 5: Rule 5:
(set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg)) (set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg))
...@@ -1208,30 +1214,31 @@ static dw_cfa_location cfa_temp; ...@@ -1208,30 +1214,31 @@ static dw_cfa_location cfa_temp;
(set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>) (set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>)
effects: cfa_store.offset -= <const_int> effects: cfa_store.offset -= <const_int>
cfa.offset = cfa_store.offset if cfa.reg == sp cfa.offset = cfa_store.offset if cfa.reg == sp
offset = -cfa_store.offset
cfa.reg = sp cfa.reg = sp
cfa.base_offset = offset cfa.base_offset = -cfa_store.offset
Rule 11: Rule 11:
(set (mem ({pre_inc,pre_dec} sp:cfa_store.reg)) <reg>) (set (mem ({pre_inc,pre_dec} sp:cfa_store.reg)) <reg>)
effects: cfa_store.offset += -/+ mode_size(mem) effects: cfa_store.offset += -/+ mode_size(mem)
cfa.offset = cfa_store.offset if cfa.reg == sp cfa.offset = cfa_store.offset if cfa.reg == sp
offset = -cfa_store.offset
cfa.reg = sp cfa.reg = sp
cfa.base_offset = offset cfa.base_offset = -cfa_store.offset
Rule 12: Rule 12:
(set (mem ({minus,plus} <reg1>:cfa_store <const_int>)) <reg2>) (set (mem ({minus,plus,losum} <reg1>:{cfa_store,cfa_temp} <const_int>)) <reg2>)
effects: cfa_store.offset += -/+ <const_int> effects: cfa.reg = <reg1>
offset = -cfa_store.offset cfa.base_offset = -/+ <const_int> - {cfa_store,cfa_temp}.offset
cfa.reg = <reg1
cfa.base_offset = offset
Rule 13: Rule 13:
(set (mem <reg1>:cfa_store) <reg2>) (set (mem <reg1>:{cfa_store,cfa_temp}) <reg2>)
effects: offset = -cfa_store.offset effects: cfa.reg = <reg1>
cfa.reg = <reg1> cfa.base_offset = -{cfa_store,cfa_temp}.offset
cfa.base_offset = offset */
Rule 14:
(set (mem (postinc <reg1>:cfa_temp <const_int>)) <reg2>)
effects: cfa.reg = <reg1>
cfa.base_offset = -cfa_temp.offset
cfa_temp.offset -= mode_size(mem) */
static void static void
dwarf2out_frame_debug_expr (expr, label) dwarf2out_frame_debug_expr (expr, label)
...@@ -1291,10 +1298,13 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1291,10 +1298,13 @@ dwarf2out_frame_debug_expr (expr, label)
FP. So we just rely on the backends to only set FP. So we just rely on the backends to only set
RTX_FRAME_RELATED_P on appropriate insns. */ RTX_FRAME_RELATED_P on appropriate insns. */
cfa.reg = REGNO (dest); cfa.reg = REGNO (dest);
cfa_temp.reg = cfa.reg;
cfa_temp.offset = cfa.offset;
break; break;
case PLUS: case PLUS:
case MINUS: case MINUS:
case LO_SUM:
if (dest == stack_pointer_rtx) if (dest == stack_pointer_rtx)
{ {
/* Rule 2 */ /* Rule 2 */
...@@ -1320,10 +1330,13 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1320,10 +1330,13 @@ dwarf2out_frame_debug_expr (expr, label)
abort (); abort ();
cfa.reg = STACK_POINTER_REGNUM; cfa.reg = STACK_POINTER_REGNUM;
} }
else if (GET_CODE (src) == LO_SUM)
/* Assume we've set the source reg of the LO_SUM from sp. */
;
else if (XEXP (src, 0) != stack_pointer_rtx) else if (XEXP (src, 0) != stack_pointer_rtx)
abort (); abort ();
if (GET_CODE (src) == PLUS) if (GET_CODE (src) != MINUS)
offset = -offset; offset = -offset;
if (cfa.reg == STACK_POINTER_REGNUM) if (cfa.reg == STACK_POINTER_REGNUM)
cfa.offset += offset; cfa.offset += offset;
...@@ -1343,7 +1356,7 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1343,7 +1356,7 @@ dwarf2out_frame_debug_expr (expr, label)
&& GET_CODE (XEXP (src, 1)) == CONST_INT) && GET_CODE (XEXP (src, 1)) == CONST_INT)
{ {
offset = INTVAL (XEXP (src, 1)); offset = INTVAL (XEXP (src, 1));
if (GET_CODE (src) == PLUS) if (GET_CODE (src) != MINUS)
offset = -offset; offset = -offset;
cfa.offset += offset; cfa.offset += offset;
cfa.reg = HARD_FRAME_POINTER_REGNUM; cfa.reg = HARD_FRAME_POINTER_REGNUM;
...@@ -1353,7 +1366,7 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1353,7 +1366,7 @@ dwarf2out_frame_debug_expr (expr, label)
} }
else else
{ {
if (GET_CODE (src) != PLUS) if (GET_CODE (src) == MINUS)
abort (); abort ();
/* Rule 4 */ /* Rule 4 */
...@@ -1363,27 +1376,34 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1363,27 +1376,34 @@ dwarf2out_frame_debug_expr (expr, label)
{ {
/* Setting a temporary CFA register that will be copied /* Setting a temporary CFA register that will be copied
into the FP later on. */ into the FP later on. */
offset = INTVAL (XEXP (src, 1)); offset = - INTVAL (XEXP (src, 1));
if (GET_CODE (src) == PLUS)
offset = -offset;
cfa.offset += offset; cfa.offset += offset;
cfa.reg = REGNO (dest); cfa.reg = REGNO (dest);
/* Or used to save regs to the stack. */
cfa_temp.reg = cfa.reg;
cfa_temp.offset = cfa.offset;
} }
/* Rule 5 */ /* Rule 5 */
else else if (GET_CODE (XEXP (src, 0)) == REG
&& REGNO (XEXP (src, 0)) == cfa_temp.reg
&& XEXP (src, 1) == stack_pointer_rtx)
{ {
/* Setting a scratch register that we will use instead /* Setting a scratch register that we will use instead
of SP for saving registers to the stack. */ of SP for saving registers to the stack. */
if (XEXP (src, 1) != stack_pointer_rtx)
abort ();
if (GET_CODE (XEXP (src, 0)) != REG
|| (unsigned) REGNO (XEXP (src, 0)) != cfa_temp.reg)
abort ();
if (cfa.reg != STACK_POINTER_REGNUM) if (cfa.reg != STACK_POINTER_REGNUM)
abort (); abort ();
cfa_store.reg = REGNO (dest); cfa_store.reg = REGNO (dest);
cfa_store.offset = cfa.offset - cfa_temp.offset; cfa_store.offset = cfa.offset - cfa_temp.offset;
} }
/* Rule 9 */
else if (GET_CODE (src) == LO_SUM
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
{
cfa_temp.reg = REGNO (dest);
cfa_temp.offset = INTVAL (XEXP (src, 1));
}
else
abort ();
} }
break; break;
...@@ -1410,14 +1430,6 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1410,14 +1430,6 @@ dwarf2out_frame_debug_expr (expr, label)
case HIGH: case HIGH:
break; break;
/* Rule 9 */
case LO_SUM:
if (GET_CODE (XEXP (src, 1)) != CONST_INT)
abort ();
cfa_temp.reg = REGNO (dest);
cfa_temp.offset = INTVAL (XEXP (src, 1));
break;
default: default:
abort (); abort ();
} }
...@@ -1470,23 +1482,38 @@ dwarf2out_frame_debug_expr (expr, label) ...@@ -1470,23 +1482,38 @@ dwarf2out_frame_debug_expr (expr, label)
/* With an offset. */ /* With an offset. */
case PLUS: case PLUS:
case MINUS: case MINUS:
case LO_SUM:
if (GET_CODE (XEXP (XEXP (dest, 0), 1)) != CONST_INT) if (GET_CODE (XEXP (XEXP (dest, 0), 1)) != CONST_INT)
abort (); abort ();
offset = INTVAL (XEXP (XEXP (dest, 0), 1)); offset = INTVAL (XEXP (XEXP (dest, 0), 1));
if (GET_CODE (XEXP (dest, 0)) == MINUS) if (GET_CODE (XEXP (dest, 0)) == MINUS)
offset = -offset; offset = -offset;
if (cfa_store.reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0))) if (cfa_store.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
offset -= cfa_store.offset;
else if (cfa_temp.reg == (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
offset -= cfa_temp.offset;
else
abort (); abort ();
offset -= cfa_store.offset;
break; break;
/* Rule 13 */ /* Rule 13 */
/* Without an offset. */ /* Without an offset. */
case REG: case REG:
if (cfa_store.reg != (unsigned) REGNO (XEXP (dest, 0))) if (cfa_store.reg == (unsigned) REGNO (XEXP (dest, 0)))
offset = -cfa_store.offset;
else if (cfa_temp.reg == (unsigned) REGNO (XEXP (dest, 0)))
offset = -cfa_temp.offset;
else
abort (); abort ();
offset = -cfa_store.offset; break;
/* Rule 14 */
case POST_INC:
if (cfa_temp.reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
abort ();
offset = -cfa_temp.offset;
cfa_temp.offset -= GET_MODE_SIZE (GET_MODE (dest));
break; break;
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment