/* This testcase derives from gnu obstack.c/obstack.h and failed with
|
/* This testcase derives from gnu obstack.c/obstack.h and failed with
|
-O3 -funroll-all-loops, or -O1 -frename-registers -funroll-loops on
|
-O3 -funroll-all-loops, or -O1 -frename-registers -funroll-loops on
|
sparc-sun-solaris2.7.
|
sparc-sun-solaris2.7.
|
|
|
Copyright (C) 2001 Free Software Foundation. */
|
Copyright (C) 2001 Free Software Foundation. */
|
|
|
# define PTR_INT_TYPE __PTRDIFF_TYPE__
|
# define PTR_INT_TYPE __PTRDIFF_TYPE__
|
|
|
struct _obstack_chunk
|
struct _obstack_chunk
|
{
|
{
|
char *limit;
|
char *limit;
|
struct _obstack_chunk *prev;
|
struct _obstack_chunk *prev;
|
char contents[4];
|
char contents[4];
|
};
|
};
|
|
|
struct obstack
|
struct obstack
|
{
|
{
|
long chunk_size;
|
long chunk_size;
|
struct _obstack_chunk *chunk;
|
struct _obstack_chunk *chunk;
|
char *object_base;
|
char *object_base;
|
char *next_free;
|
char *next_free;
|
char *chunk_limit;
|
char *chunk_limit;
|
PTR_INT_TYPE temp;
|
PTR_INT_TYPE temp;
|
int alignment_mask;
|
int alignment_mask;
|
struct _obstack_chunk *(*chunkfun) (void *, long);
|
struct _obstack_chunk *(*chunkfun) (void *, long);
|
void (*freefun) (void *, struct _obstack_chunk *);
|
void (*freefun) (void *, struct _obstack_chunk *);
|
void *extra_arg;
|
void *extra_arg;
|
unsigned use_extra_arg:1;
|
unsigned use_extra_arg:1;
|
unsigned maybe_empty_object:1;
|
unsigned maybe_empty_object:1;
|
unsigned alloc_failed:1;
|
unsigned alloc_failed:1;
|
};
|
};
|
|
|
extern void _obstack_newchunk (struct obstack *, int);
|
extern void _obstack_newchunk (struct obstack *, int);
|
|
|
struct fooalign {char x; double d;};
|
struct fooalign {char x; double d;};
|
#define DEFAULT_ALIGNMENT \
|
#define DEFAULT_ALIGNMENT \
|
((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
|
((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
|
union fooround {long x; double d;};
|
union fooround {long x; double d;};
|
#define DEFAULT_ROUNDING (sizeof (union fooround))
|
#define DEFAULT_ROUNDING (sizeof (union fooround))
|
|
|
#ifndef COPYING_UNIT
|
#ifndef COPYING_UNIT
|
#define COPYING_UNIT int
|
#define COPYING_UNIT int
|
#endif
|
#endif
|
|
|
#define CALL_CHUNKFUN(h, size) \
|
#define CALL_CHUNKFUN(h, size) \
|
(((h) -> use_extra_arg) \
|
(((h) -> use_extra_arg) \
|
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
|
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
|
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
|
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
|
|
|
#define CALL_FREEFUN(h, old_chunk) \
|
#define CALL_FREEFUN(h, old_chunk) \
|
do { \
|
do { \
|
if ((h) -> use_extra_arg) \
|
if ((h) -> use_extra_arg) \
|
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
|
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
|
else \
|
else \
|
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
|
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
|
} while (0)
|
} while (0)
|
|
|
void
|
void
|
_obstack_newchunk (h, length)
|
_obstack_newchunk (h, length)
|
struct obstack *h;
|
struct obstack *h;
|
int length;
|
int length;
|
{
|
{
|
register struct _obstack_chunk *old_chunk = h->chunk;
|
register struct _obstack_chunk *old_chunk = h->chunk;
|
register struct _obstack_chunk *new_chunk;
|
register struct _obstack_chunk *new_chunk;
|
register long new_size;
|
register long new_size;
|
register long obj_size = h->next_free - h->object_base;
|
register long obj_size = h->next_free - h->object_base;
|
register long i;
|
register long i;
|
long already;
|
long already;
|
|
|
new_size = (obj_size + length) + (obj_size >> 3) + 100;
|
new_size = (obj_size + length) + (obj_size >> 3) + 100;
|
if (new_size < h->chunk_size)
|
if (new_size < h->chunk_size)
|
new_size = h->chunk_size;
|
new_size = h->chunk_size;
|
|
|
new_chunk = CALL_CHUNKFUN (h, new_size);
|
new_chunk = CALL_CHUNKFUN (h, new_size);
|
h->chunk = new_chunk;
|
h->chunk = new_chunk;
|
new_chunk->prev = old_chunk;
|
new_chunk->prev = old_chunk;
|
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
|
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
|
|
|
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
|
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
|
{
|
{
|
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
|
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
|
i >= 0; i--)
|
i >= 0; i--)
|
((COPYING_UNIT *)new_chunk->contents)[i]
|
((COPYING_UNIT *)new_chunk->contents)[i]
|
= ((COPYING_UNIT *)h->object_base)[i];
|
= ((COPYING_UNIT *)h->object_base)[i];
|
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
|
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
|
}
|
}
|
else
|
else
|
already = 0;
|
already = 0;
|
for (i = already; i < obj_size; i++)
|
for (i = already; i < obj_size; i++)
|
new_chunk->contents[i] = h->object_base[i];
|
new_chunk->contents[i] = h->object_base[i];
|
|
|
if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
|
if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
|
{
|
{
|
new_chunk->prev = old_chunk->prev;
|
new_chunk->prev = old_chunk->prev;
|
CALL_FREEFUN (h, old_chunk);
|
CALL_FREEFUN (h, old_chunk);
|
}
|
}
|
|
|
h->object_base = new_chunk->contents;
|
h->object_base = new_chunk->contents;
|
h->next_free = h->object_base + obj_size;
|
h->next_free = h->object_base + obj_size;
|
h->maybe_empty_object = 0;
|
h->maybe_empty_object = 0;
|
}
|
}
|
|
|