Alignment fix/workaround for gcc 3.2.2
Posted: Thu Nov 04, 2004 10:11 am
Okay, well. I've finally come up with several patches for gcc. One is a bug I spotted: the BIGGEST_ALIGNMENT constant was wrong. But it doesn't seem to be fixing everything. Well, I've more or less been able to track down that nasty alignment bug, and I think I am closer of it every day.
For the time beeing though, I won't be able to work a lot on that, since I have some other duties, known as Real Life stuff. So, well, for now, I've built up a quick and dirty work around for it. You now have a -malign-all=X option on the gcc's command line. Which mean that, when used, every variable will be at least aligned to 2^X bytes. So, if you put -malign-all=4, every variable will be forcabily aligned to 16 bytes (that is, 128 bits), which is a workaround for that built-in "memcpy" bug, and maybe others. This is defaulted to 1 by default, so it is harmless to have it on a "stable" toolchain, since it won't interfere with the normal code generation.
Here is the whole patch I've provided to ooPo, which should be included to the stable gcc, I think:
For the time beeing though, I won't be able to work a lot on that, since I have some other duties, known as Real Life stuff. So, well, for now, I've built up a quick and dirty work around for it. You now have a -malign-all=X option on the gcc's command line. Which mean that, when used, every variable will be at least aligned to 2^X bytes. So, if you put -malign-all=4, every variable will be forcabily aligned to 16 bytes (that is, 128 bits), which is a workaround for that built-in "memcpy" bug, and maybe others. This is defaulted to 1 by default, so it is harmless to have it on a "stable" toolchain, since it won't interfere with the normal code generation.
Here is the whole patch I've provided to ooPo, which should be included to the stable gcc, I think:
Code: Select all
diff -ur gcc-3.2.2/gcc/config/mips/mips.c gcc-3.2.2-patched/gcc/config/mips/mips.c
--- gcc-3.2.2/gcc/config/mips/mips.c Thu Nov 4 00:50:53 2004
+++ gcc-3.2.2-patched/gcc/config/mips/mips.c Thu Nov 4 00:16:50 2004
@@ -281,6 +281,8 @@
#endif
const char * mips_no_align128_string;
const char * mips_align128_string;
+const char * mips_align_all_string;
+int mips_align_all = 1;
/* Whether we are generating mips16 hard float code. In mips16 mode
we always set TARGET_SOFT_FLOAT; this variable is nonzero if
@@ -4968,6 +4970,14 @@
if (TARGET_SINGLE_FLOAT && TARGET_SOFT_FLOAT)
target_flags &= ~((TARGET_DEFAULT) & (MASK_SOFT_FLOAT | MASK_SINGLE_FLOAT));
#endif
+
+ if (mips_align_all_string == 0)
+ mips_align_all = 1;
+
+ else if (ISDIGIT (*mips_align_all_string))
+ {
+ mips_align_all = atoi (mips_align_all_string);
+ }
/* Get the architectural level. */
if (mips_isa_string == 0)
diff -ur gcc-3.2.2/gcc/config/mips/mips.h gcc-3.2.2-patched/gcc/config/mips/mips.h
--- gcc-3.2.2/gcc/config/mips/mips.h Thu Nov 4 00:50:53 2004
+++ gcc-3.2.2-patched/gcc/config/mips/mips.h Thu Nov 4 00:09:45 2004
@@ -158,6 +158,7 @@
extern const char *mips_no_mips16_string;/* for -mno-mips16 */
extern const char *mips_explicit_type_size_string;/* for -mexplicit-type-size */
extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
+extern const char *mips_align_all_string;/* for -malign-all= */
extern const char * mips_align128_string;/* for -malign128 */
extern const char * mips_no_align128_string;/* for -mno-align128 */
extern int mips_split_addresses; /* perform high/lo_sum support */
@@ -180,6 +181,8 @@
extern void sdata_section PARAMS ((void));
extern void sbss_section PARAMS ((void));
+extern int mips_align_all;
+
/* Stubs for half-pic support if not OSF/1 reference platform. */
#ifndef HALF_PIC_P
@@ -637,6 +640,8 @@
N_("Don't call any cache flush functions")}, \
{ "flush-func=", &mips_cache_flush_func, \
N_("Specify cache flush function")}, \
+ { "align-all=", &mips_align_all_string, \
+ N_("Force lower alignment")}, \
}
/* This is meant to be redefined in the host dependent files. */
@@ -1693,7 +1698,7 @@
#define STRUCTURE_SIZE_BOUNDARY 8
/* There is no point aligning anything to a rounder boundary than this. */
-#define BIGGEST_ALIGNMENT 64
+#define BIGGEST_ALIGNMENT 128
/* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */
@@ -4657,7 +4662,7 @@
to a multiple of 2**LOG bytes. */
#define ASM_OUTPUT_ALIGN(STREAM,LOG) \
- fprintf (STREAM, "\t.align\t%d\n", (LOG))
+ fprintf (STREAM, "\t.align\t%d\n", (LOG) > mips_align_all ? (LOG) : mips_align_all)
/* This is how to output an assembler line to advance the location
counter by SIZE bytes. */