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);
--- /dev/null
+/* This used to ICE due to a backend problem on s390. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -mpacked-stack" } */
+
+typedef unsigned int __u32;
+typedef struct
+{
+ volatile int counter;
+} __attribute__ ((aligned (4))) atomic_t;
+static __inline__ __attribute__ ((always_inline))
+ void atomic_inc (volatile atomic_t * v)
+{
+ (
+ {
+ typeof (v->counter) old_val, new_val;
+ __asm__ __volatile__ (
+ " l %0,0(%3)\n"
+ "0: lr %1,%0\n"
+ " ar %1,%4\n"
+ " cs %0,%1,0(%3)\n"
+ " jl 0b":
+ "=&d" (old_val), "=&d" (new_val), "=m" (((atomic_t *) (v))->counter):
+ "a" (v), "d" (1), "m" (((atomic_t *) (v))->counter):
+ "cc", "memory");
+ });
+}
+extern unsigned long volatile __attribute__ ((section (".data"))) jiffies;
+struct inet_peer
+{
+ unsigned long dtime;
+ atomic_t refcnt;
+};
+static volatile int peer_total;
+int inet_peer_threshold = 65536 + 128;
+int inet_peer_minttl = 120 * 100;
+int inet_peer_maxttl = 10 * 60 * 100;
+static int
+cleanup_once (unsigned long ttl)
+{
+ struct inet_peer *p;
+ if (p != ((void *) 0))
+ {
+ if (((
+ {
+ 1;}
+ ) && ((long) (jiffies) - (long) (p->dtime + ttl) < 0)))
+ {
+ return -1;
+ }
+ atomic_inc (&p->refcnt);
+ }
+}
+struct inet_peer *
+inet_getpeer (__u32 daddr, int create)
+{
+ int i;
+ int ttl;
+ if (peer_total >= inet_peer_threshold)
+ ttl = inet_peer_minttl;
+ else
+ ttl =
+ inet_peer_maxttl - (inet_peer_maxttl -
+ inet_peer_minttl) / 100 * peer_total /
+ inet_peer_threshold * 100;
+ for (i = 0; i < 30 && !cleanup_once (ttl); i++);
+}