HOST_WIDE_INT f4_offset;
HOST_WIDE_INT f8_offset;
HOST_WIDE_INT backchain_offset;
-
+
+ /* Number of first and last gpr where slots in the register
+ save area are reserved for. */
+ int first_save_gpr_slot;
+ int last_save_gpr_slot;
+
/* Number of first and last gpr to be saved, restored. */
int first_save_gpr;
int first_restore_gpr;
#define cfun_frame_layout (cfun->machine->frame_layout)
#define cfun_save_high_fprs_p (!!cfun_frame_layout.high_fprs)
-#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr - \
- cfun_frame_layout.first_save_gpr + 1) * UNITS_PER_WORD)
+#define cfun_gprs_save_area_size ((cfun_frame_layout.last_save_gpr_slot - \
+ cfun_frame_layout.first_save_gpr_slot + 1) * UNITS_PER_WORD)
#define cfun_set_fpr_bit(BITNUM) (cfun->machine->frame_layout.fpr_bitmap |= \
(1 << (BITNUM)))
#define cfun_fpr_bit_p(BITNUM) (!!(cfun->machine->frame_layout.fpr_bitmap & \
|| current_function_stdarg);
for (i = 6; i < 16; i++)
- if (clobbered_regs[i])
+ if (regs_ever_live[i] || clobbered_regs[i])
break;
for (j = 15; j > i; j--)
- if (clobbered_regs[j])
+ if (regs_ever_live[j] || clobbered_regs[j])
break;
if (i == 16)
{
/* Nothing to save/restore. */
+ cfun_frame_layout.first_save_gpr_slot = -1;
+ cfun_frame_layout.last_save_gpr_slot = -1;
cfun_frame_layout.first_save_gpr = -1;
cfun_frame_layout.first_restore_gpr = -1;
cfun_frame_layout.last_save_gpr = -1;
}
else
{
- /* Save / Restore from gpr i to j. */
- cfun_frame_layout.first_save_gpr = i;
- cfun_frame_layout.first_restore_gpr = i;
- cfun_frame_layout.last_save_gpr = j;
- cfun_frame_layout.last_restore_gpr = j;
+ /* Save slots for gprs from i to j. */
+ cfun_frame_layout.first_save_gpr_slot = i;
+ cfun_frame_layout.last_save_gpr_slot = j;
+
+ for (i = cfun_frame_layout.first_save_gpr_slot;
+ i < cfun_frame_layout.last_save_gpr_slot + 1;
+ i++)
+ if (clobbered_regs[i])
+ break;
+
+ for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
+ if (clobbered_regs[j])
+ break;
+
+ if (i == cfun_frame_layout.last_save_gpr_slot + 1)
+ {
+ /* Nothing to save/restore. */
+ cfun_frame_layout.first_save_gpr = -1;
+ cfun_frame_layout.first_restore_gpr = -1;
+ cfun_frame_layout.last_save_gpr = -1;
+ cfun_frame_layout.last_restore_gpr = -1;
+ }
+ else
+ {
+ /* Save / Restore from gpr i to j. */
+ cfun_frame_layout.first_save_gpr = i;
+ cfun_frame_layout.first_restore_gpr = i;
+ cfun_frame_layout.last_save_gpr = j;
+ cfun_frame_layout.last_restore_gpr = j;
+ }
}
if (current_function_stdarg)
if (cfun_frame_layout.first_save_gpr == -1
|| cfun_frame_layout.first_save_gpr > 2 + min_gpr)
- cfun_frame_layout.first_save_gpr = 2 + min_gpr;
+ {
+ cfun_frame_layout.first_save_gpr = 2 + min_gpr;
+ cfun_frame_layout.first_save_gpr_slot = 2 + min_gpr;
+ }
if (cfun_frame_layout.last_save_gpr == -1
|| cfun_frame_layout.last_save_gpr < 2 + max_gpr - 1)
- cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
+ {
+ cfun_frame_layout.last_save_gpr = 2 + max_gpr - 1;
+ cfun_frame_layout.last_save_gpr_slot = 2 + max_gpr - 1;
+ }
}
/* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */
cfun_frame_layout.f0_offset = 16 * UNITS_PER_WORD;
cfun_frame_layout.f4_offset = cfun_frame_layout.f0_offset + 2 * 8;
cfun_frame_layout.f8_offset = -cfun_frame_layout.high_fprs * 8;
- cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr
+ cfun_frame_layout.gprs_offset = (cfun_frame_layout.first_save_gpr_slot
* UNITS_PER_WORD);
}
else if (TARGET_BACKCHAIN) /* kernel stack layout */
- UNITS_PER_WORD);
cfun_frame_layout.gprs_offset
= (cfun_frame_layout.backchain_offset
- - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr + 1)
+ - (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
* UNITS_PER_WORD);
if (TARGET_64BIT)
case RETURN_ADDRESS_POINTER_REGNUM:
s390_init_frame_layout ();
- index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr;
+ index = RETURN_REGNUM - cfun_frame_layout.first_save_gpr_slot;
gcc_assert (index >= 0);
offset = cfun_frame_layout.frame_size + cfun_frame_layout.gprs_offset;
offset += index * UNITS_PER_WORD;
if (cfun_frame_layout.first_save_gpr != -1)
{
insn = save_gprs (stack_pointer_rtx,
- cfun_frame_layout.gprs_offset,
+ cfun_frame_layout.gprs_offset +
+ UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
+ - cfun_frame_layout.first_save_gpr_slot),
cfun_frame_layout.first_save_gpr,
cfun_frame_layout.last_save_gpr);
emit_insn (insn);
{
addr = plus_constant (frame_pointer,
offset + cfun_frame_layout.gprs_offset
- + (i - cfun_frame_layout.first_save_gpr)
+ + (i - cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
addr = plus_constant (frame_pointer,
offset + cfun_frame_layout.gprs_offset
+ (RETURN_REGNUM
- - cfun_frame_layout.first_save_gpr)
+ - cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
insn = restore_gprs (frame_pointer,
offset + cfun_frame_layout.gprs_offset
+ (cfun_frame_layout.first_restore_gpr
- - cfun_frame_layout.first_save_gpr)
+ - cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD,
cfun_frame_layout.first_restore_gpr,
cfun_frame_layout.last_restore_gpr);
f_sav = TREE_CHAIN (f_ovf);
valist = build_va_arg_indirect_ref (valist);
- gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
- sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
+ gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
+ fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
+ ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
+ sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
/* Count number of gp and fp argument registers used. */
if (cfun->va_list_gpr_size)
{
- t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
- build_int_cst (NULL_TREE, n_gpr));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
+ build_int_cst (NULL_TREE, n_gpr));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
if (cfun->va_list_fpr_size)
{
- t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
- build_int_cst (NULL_TREE, n_fpr));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
+ build_int_cst (NULL_TREE, n_fpr));
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
fprintf (stderr, "va_start: n_gpr = %d, n_fpr = %d off %d\n",
(int)n_gpr, (int)n_fpr, off);
- t = build (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
+ t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t, build_int_cst (NULL_TREE, off));
- t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
|| (cfun->va_list_fpr_size && n_fpr < FP_ARG_NUM_REG))
{
t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
- t = build (PLUS_EXPR, TREE_TYPE (sav), t,
- build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
+ t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
+ build_int_cst (NULL_TREE, -RETURN_REGNUM * UNITS_PER_WORD));
- t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
f_sav = TREE_CHAIN (f_ovf);
valist = build_va_arg_indirect_ref (valist);
- gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
- ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
- sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
+ gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
+ fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
+ ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
+ sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
size = int_size_in_bytes (type);