Commit 48b2e0a7 by Richard Sandiford Committed by Richard Sandiford

re PR target/16407 (Unaligned access to local variables)

	PR target/16407
	* config/mips/mips-protos.h (mips_declare_common_object): Declare.
	* config/mips/mips.c (mips_declare_common_object): New function,
	mostly split out from...
	(mips_output_aligned_decl_common): ...here.
	* config/mips/mips.h (ASM_OUTPUT_LOCAL): Remove in favor of...
	(ASM_OUTPUT_ALIGNED_LOCAL): ...this new definition.
	* config/mips/iris6.h (ASM_OUTPUT_ALIGNED_LOCAL): Undefine this
	rather than ASM_OUTPUT_LOCAL.  Call mips_declare_common_object.

From-SVN: r84219
parent 477eff96
2004-07-07 Richard Sandiford <rsandifo@redhat.com>
PR target/16407
* config/mips/mips-protos.h (mips_declare_common_object): Declare.
* config/mips/mips.c (mips_declare_common_object): New function,
mostly split out from...
(mips_output_aligned_decl_common): ...here.
* config/mips/mips.h (ASM_OUTPUT_LOCAL): Remove in favor of...
(ASM_OUTPUT_ALIGNED_LOCAL): ...this new definition.
* config/mips/iris6.h (ASM_OUTPUT_ALIGNED_LOCAL): Undefine this
rather than ASM_OUTPUT_LOCAL. Call mips_declare_common_object.
2004-07-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> 2004-07-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR c/16392 PR c/16392
......
...@@ -357,7 +357,7 @@ do \ ...@@ -357,7 +357,7 @@ do \
while (0) while (0)
/* ??? SGI assembler gives warning whenever .lcomm is used. */ /* ??? SGI assembler gives warning whenever .lcomm is used. */
#undef ASM_OUTPUT_LOCAL #undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \ #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
do \ do \
{ \ { \
...@@ -369,7 +369,8 @@ do \ ...@@ -369,7 +369,8 @@ do \
ASM_OUTPUT_SKIP (STREAM, SIZE); \ ASM_OUTPUT_SKIP (STREAM, SIZE); \
} \ } \
else \ else \
mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (int)(SIZE)); \ mips_declare_common_object (STREAM, NAME, "\n\t.lcomm\t", \
SIZE, ALIGN, false); \
} \ } \
while (0) while (0)
......
...@@ -166,6 +166,9 @@ extern void mips_output_aligned_bss (FILE *, tree, const char *, ...@@ -166,6 +166,9 @@ extern void mips_output_aligned_bss (FILE *, tree, const char *,
extern void mips_output_aligned_decl_common (FILE *, tree, const char *, extern void mips_output_aligned_decl_common (FILE *, tree, const char *,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned int); unsigned int);
extern void mips_declare_common_object (FILE *, const char *,
const char *, unsigned HOST_WIDE_INT,
unsigned int, bool);
extern void mips_declare_object (FILE *, const char *, const char *, extern void mips_declare_object (FILE *, const char *, const char *,
const char *, ...); const char *, ...);
extern void mips_declare_object_name (FILE *, const char *, tree); extern void mips_declare_object_name (FILE *, const char *, tree);
......
...@@ -5987,17 +5987,32 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name, ...@@ -5987,17 +5987,32 @@ mips_output_aligned_decl_common (FILE *stream, tree decl, const char *name,
":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n", ":\n\t.space\t" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
size); size);
} }
else if (TARGET_SGI_O32_AS) else
/* The SGI o32 assembler doesn't accept an alignment. */
mips_declare_common_object (stream, name, "\n\t.comm\t",
size, align, !TARGET_SGI_O32_AS);
}
/* Declare a common object of SIZE bytes using asm directive INIT_STRING.
NAME is the name of the object and ALIGN is the required alignment
in bytes. TAKES_ALIGNMENT_P is true if the directive takes a third
alignment argument. */
void
mips_declare_common_object (FILE *stream, const char *name,
const char *init_string,
unsigned HOST_WIDE_INT size,
unsigned int align, bool takes_alignment_p)
{
if (!takes_alignment_p)
{ {
/* The SGI o32 assembler doesn't accept an alignment, so round up
the size instead. */
size += (align / BITS_PER_UNIT) - 1; size += (align / BITS_PER_UNIT) - 1;
size -= size % (align / BITS_PER_UNIT); size -= size % (align / BITS_PER_UNIT);
mips_declare_object (stream, name, "\n\t.comm\t", mips_declare_object (stream, name, init_string,
"," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size); "," HOST_WIDE_INT_PRINT_UNSIGNED "\n", size);
} }
else else
mips_declare_object (stream, name, "\n\t.comm\t", mips_declare_object (stream, name, init_string,
"," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
size, align / BITS_PER_UNIT); size, align / BITS_PER_UNIT);
} }
......
...@@ -3189,9 +3189,10 @@ while (0) ...@@ -3189,9 +3189,10 @@ while (0)
/* This says how to define a local common symbol (ie, not visible to /* This says how to define a local common symbol (ie, not visible to
linker). */ linker). */
#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \ #ifndef ASM_OUTPUT_ALIGNED_LOCAL
mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (int)(SIZE)) #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
mips_declare_common_object (STREAM, NAME, "\n\t.lcomm\t", SIZE, ALIGN, false)
#endif
/* This says how to output an external. It would be possible not to /* This says how to output an external. It would be possible not to
output anything and let undefined symbol become external. However output anything and let undefined symbol become external. However
......
2004-07-07 Richard Sandiford <rsandifo@redhat.com>
* gcc.c-torture/execute/20040707-1.c: New test.
2004-07-06 Richard Sandiford <rsandifo@redhat.com> 2004-07-06 Richard Sandiford <rsandifo@redhat.com>
* gcc.c-torture/execute/20040706-1.c: New test. * gcc.c-torture/execute/20040706-1.c: New test.
......
struct s { char c1, c2; };
void foo (struct s s)
{
static struct s s1;
s1 = s;
}
int main ()
{
static struct s s2;
foo (s2);
exit (0);
}
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