#define ASM_SPEC " %{pipe:-} %{fpic:-k} %{fPIC:-k}"
-/* Prevent error on `-dalign', `-sun4' and `-target sun4' options. */
-/* Also, make it easy to specify interesting optimization options. */
+/* Prevent error on `-sun4' and `-target sun4' options. */
+/* This used to translate -dalign to -malign, but that is no good
+ because it can't turn off the usual meaning of making debugging dumps. */
-#define CC1_SPEC "%{dalign:-malign} %{sun4:} %{target:}"
+#define CC1_SPEC "%{sun4:} %{target:}"
#define PTRDIFF_TYPE "int"
#define SIZE_TYPE "int"
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "Tdata") || !strcmp (STR, "include") \
|| !strcmp (STR, "imacros") || !strcmp (STR, "target") \
- || !strcmp (STR, "assert"))
+ || !strcmp (STR, "assert") || !strcmp (STR, "aux-info"))
/* Names to predefine in the preprocessor for this target machine. */
pc-relative range. Useful with -fomit-frame-pointer. */
#define TARGET_TAIL_CALL (target_flags & 8)
-/* Nonzero means that references to doublewords are guaranteed
- aligned...if not, its a bug in the users program! */
-#define TARGET_ALIGN (target_flags & 16)
+/* Nonzero means that reference doublewords as if they were guaranteed
+ to be aligned...if they aren't, too bad for the user!
+ Like -fast in Sun cc. */
+#define TARGET_HOPE_ALIGN (target_flags & 16)
+
+/* Nonzero means that make sure all doubles are on 8-byte boundaries. */
+#define TARGET_FORCE_ALIGN (target_flags & 32)
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
{"epilogue", 2}, \
{"no-epilogue", -2}, \
{"tail-call", 8}, \
- {"align", 16}, \
- { "", TARGET_DEFAULT}}
+ {"hope-align", 16}, \
+ {"force-align", 48}, \
+ { "", TARGET_DEFAULT}}
#define TARGET_DEFAULT 3
\f
#define CUMULATIVE_ARGS int
#define ROUND_ADVANCE(SIZE) \
- ((SIZE + UNITS_PER_WORD - 1)/UNITS_PER_WORD)
+ ((SIZE + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Round a register number up to a proper boundary for an arg of mode MODE.
+ Note that we need an odd/even pair for a two-word arg,
+ since that will become 8-byte aligned when stored in memory. */
+#define ROUND_REG(X, MODE) \
+ (TARGET_FORCE_ALIGN && GET_MODE_UNIT_SIZE ((MODE)) > 4 \
+ ? ((X) + ! ((X) & 1)) : (X))
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
(TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- ((CUM) += ((MODE) != BLKmode \
- ? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
- : ROUND_ADVANCE (int_size_in_bytes (TYPE))))
+ ((CUM) = (ROUND_REG ((CUM), (MODE)) \
+ + ((MODE) != BLKmode \
+ ? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
+ : ROUND_ADVANCE (int_size_in_bytes (TYPE)))))
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
is at least partially passed in a register unless its data type forbids. */
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-((CUM) < NPARM_REGS \
+(ROUND_REG ((CUM), (MODE)) < NPARM_REGS \
&& ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \
- && ((TYPE)==0 || (MODE) != BLKmode || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \
- ? gen_rtx (REG, (MODE), BASE_PASSING_ARG_REG (MODE) + (CUM)) : 0)
+ && ((TYPE)==0 || (MODE) != BLKmode \
+ || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \
+ ? gen_rtx (REG, (MODE), \
+ (BASE_PASSING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE)))) \
+ : 0)
/* Define where a function finds its arguments.
This is different from FUNCTION_ARG because of register windows. */
#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
-((CUM) < NPARM_REGS \
+(ROUND_REG ((CUM), (MODE)) < NPARM_REGS \
&& ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \
- && ((MODE) != BLKmode || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \
- ? gen_rtx (REG, (MODE), BASE_INCOMING_ARG_REG (MODE) + (CUM)) : 0)
+ && ((TYPE)==0 || (MODE) != BLKmode \
+ || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \
+ ? gen_rtx (REG, (MODE), \
+ (BASE_INCOMING_ARG_REG (MODE) + ROUND_REG ((CUM), (MODE)))) \
+ : 0)
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
needs partial registers on the Sparc. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
- (((CUM) < NPARM_REGS \
+ ((ROUND_REG ((CUM), (MODE)) < NPARM_REGS \
&& ((TYPE)==0 || ! TREE_ADDRESSABLE ((tree)(TYPE))) \
- && ((TYPE)==0 || (MODE) != BLKmode || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0))\
- && ((CUM) \
+ && ((TYPE)==0 || (MODE) != BLKmode \
+ || (TYPE_ALIGN ((TYPE)) % PARM_BOUNDARY == 0)) \
+ && (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) == BLKmode \
? ROUND_ADVANCE (int_size_in_bytes (TYPE)) \
- : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))) - NPARM_REGS > 0) \
- ? (NPARM_REGS - (CUM)) \
+ : ROUND_ADVANCE (GET_MODE_SIZE (MODE)))) - NPARM_REGS > 0) \
+ ? (NPARM_REGS - ROUND_REG ((CUM), (MODE))) \
: 0)
/* The SPARC ABI stipulates passing struct arguments (of any size)
by invisible reference. */
-/* Must pass by reference if this is a structure/union type, and this is not
- target gnu or the address of this structure is needed somewhere. */
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
(TYPE && (TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE))
+/* If defined, a C expression that gives the alignment boundary, in
+ bits, of an argument with the specified mode and type. If it is
+ not defined, `PARM_BOUNDARY' is used for all arguments.
+
+ This definition does nothing special unless TARGET_FORCE_ALIGN;
+ in that case, it aligns each arg to the natural boundary. */
+
+#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
+ (! TARGET_FORCE_ALIGN \
+ ? PARM_BOUNDARY \
+ : (((TYPE) != 0) \
+ ? (TYPE_ALIGN (TYPE) <= PARM_BOUNDARY \
+ ? PARM_BOUNDARY \
+ : TYPE_ALIGN (TYPE)) \
+ : (GET_MODE_ALIGNMENT (MODE) <= PARM_BOUNDARY \
+ ? PARM_BOUNDARY \
+ : GET_MODE_ALIGNMENT (MODE))))
+
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
/* This is how to output an assembler line defining a `double' constant. */
+/* Assemblers (both gas 1.35 and as in 4.0.3)
+ seem to treat -0.0 as if it were 0.0.
+ They reject 99e9999, but accept inf. */
#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
{ \
if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.double 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
+ fprintf (FILE, "\t.double 0r%sinf\n", (VALUE) > 0 ? "" : "-"); \
+ else if (REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
union { double d; long l[2];} t; \
t.d = (VALUE); \
#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
{ \
if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.single 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
+ fprintf (FILE, "\t.single 0r%sinf\n", (VALUE) > 0 ? "" : "-"); \
+ else if (REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
union { float f; long l;} t; \
t.f = (VALUE); \