/* Provide required defaults for linker -e and -d switches. */
#define LINK_SPEC \
- "%{!nostdlib:%{!e*:-e start}} -dc -dp %{static:-Bstatic} %{assert*}"
+ "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}"
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC " %{pipe:-} %{fpic:-k} %{fPIC:-k}"
+/* Define macros to distinguish architectures. */
+#define CPP_SPEC "%{msparclite:-D__sparclite__} %{mv8:-D__sparc_v8__}"
+
/* 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. */
seem worth trying to fix. */
#define TARGET_FORCE_ALIGN (target_flags & 32)
+/* Nonzero means that we should generate code for a v8 sparc. */
+#define TARGET_V8 (target_flags & 64)
+
+/* Nonzero means that we should generate code for a sparclite. */
+#define TARGET_SPARCLITE (target_flags & 128)
+
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE }
{"no-epilogue", -2}, \
{"hope-align", 16}, \
{"force-align", 48}, \
+ {"v8", 64}, \
+ {"no-v8", -64}, \
+ {"sparclite", 128}, \
+ {"no-sparclite", -128}, \
{ "", TARGET_DEFAULT}}
#define TARGET_DEFAULT 3
/* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY 64
+/* ALIGN FRAMES on double word boundaries */
+
+#define SPARC_STACK_ALIGN(LOC) (((LOC)+7) & 0xfffffff8)
+
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
/* No data type wants to be aligned rounder than this. */
#define BIGGEST_ALIGNMENT 64
+/* The best alignment to use in cases where we have a choice. */
+#define FASTEST_ALIGNMENT 64
+
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- (TREE_CODE (EXP) == STRING_CST \
- && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < FASTEST_ALIGNMENT) \
+ ? FASTEST_ALIGNMENT : (ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Set this nonzero if move instructions will actually fail to work
when given unaligned data. */
#define FINALIZE_PIC finalize_pic ()
/* Sparc ABI says that quad-precision floats and all structures are returned
- in memory. */
+ in memory. We go along regarding floats, but for structures
+ we follow GCC's normal policy. Use -fpcc-struct-value
+ if you want to follow the ABI. */
#define RETURN_IN_MEMORY(TYPE) \
- (TREE_CODE (TYPE) == RECORD_TYPE || TREE_CODE (TYPE) == UNION_TYPE \
- || TYPE_MODE (TYPE) == TFmode)
+ (TYPE_MODE (TYPE) == TFmode)
/* Functions which return large structures get the address
to place the wanted value at offset 64 from the frame.
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
in some cases it is preferable to use a more restrictive class. */
-#define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
+/* We can't load constants into FP registers. We can't load any FP constant
+ if an 'E' constraint fails to match it. */
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ (CONSTANT_P (X) \
+ && ((CLASS) == FP_REGS \
+ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \
+ || HOST_BITS_PER_INT != BITS_PER_WORD))) \
+ ? NO_REGS : (CLASS))
/* Return the register class of a scratch register needed to load IN into
a register of class CLASS in MODE.
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
(flag_pic && pic_address_needs_scratch (IN) ? GENERAL_REGS : NO_REGS)
+/* On SPARC it is not possible to directly move data between
+ GENERAL_REGS and FP_REGS. */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+ ((CLASS1 == FP_REGS && CLASS2 == GENERAL_REGS) \
+ || (CLASS1 == GENERAL_REGS && CLASS2 == FP_REGS))
+
+
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
/* On SPARC, this is the size of MODE in words. */
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
-#define FUNCTION_PROFILER(FILE, LABELNO) \
- fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \
- (LABELNO), (LABELNO))
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+ do { \
+ fputs ("\tsethi %hi(", (FILE)); \
+ ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO); \
+ fputs ("),%o0\n\tcall mcount\n\tor %lo(", (FILE)); \
+ ASM_OUTPUT_INTERNAL_LABELREF (FILE, "LP", LABELNO); \
+ fputs ("),%o0,%o0\n", (FILE)); \
+ } while (0)
/* Output assembler code to FILE to initialize this source file's
basic block profiling info, if that has not already been done. */
+/* FIXME -- this does not parameterize how it generates labels (like the
+ above FUNCTION_PROFILER). Broken on Solaris-2. --gnu@cygnus.com */
#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n", \
#define REG_OK_FOR_BASE_P(X) (((unsigned) REGNO (X)) - 32 >= 32 && REGNO (X) != 0)
#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? \
- ((GET_CODE (OP) == MEM \
- && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \
- && ! symbolic_memory_operand (OP, VOIDmode))) \
- : ((C) == 'R' ? \
- (GET_CODE (OP) == LO_SUM \
- && GET_CODE (XEXP (OP, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
- : ((C) == 'S' \
- ? CONSTANT_P (OP) || memory_address_p (Pmode, OP) : 0)))
-
+ ((C) == 'Q' \
+ ? ((GET_CODE (OP) == MEM \
+ && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \
+ && ! symbolic_memory_operand (OP, VOIDmode)) \
+ || (reload_in_progress && GET_CODE (OP) == REG \
+ && REGNO (OP) >= FIRST_PSEUDO_REGISTER)) \
+ : (C) == 'R' \
+ ? (GET_CODE (OP) == LO_SUM \
+ && GET_CODE (XEXP (OP, 0)) == REG \
+ && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
+ : (C) == 'S' \
+ ? (CONSTANT_P (OP) || memory_address_p (Pmode, OP)) \
+ : (C) == 'T' \
+ ? (mem_aligned_8 (OP)) \
+ : (C) == 'U' \
+ ? (register_ok_for_ldd (OP)) \
+ : 0)
+
#else
/* Nonzero if X is a hard reg that can be used as an index. */
: ((C) == 'S' \
? (CONSTANT_P (OP) \
|| (GET_CODE (OP) == REG && reg_renumber[REGNO (OP)] > 0)\
- || strict_memory_address_p (Pmode, OP)) : 0)))
+ || strict_memory_address_p (Pmode, OP)) \
+ : ((C) == 'T' ? \
+ mem_aligned_8 (OP) && strict_memory_address_p (Pmode, OP) \
+ : ((C) == 'U' ? \
+ register_ok_for_ldd (OP) : 0)))))
#endif
\f
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
in one reasonably fast instruction. */
#define MOVE_MAX 8
+/* This is the value of the error code EDOM for this machine,
+ used by the sqrt instruction. */
+#define TARGET_EDOM 33
+
+/* This is how to refer to the variable errno. */
+#define GEN_ERRNO_RTX \
+ gen_rtx (MEM, SImode, gen_rtx (SYMBOL_REF, Pmode, "errno"))
+
/* Define if normal loads of shorter-than-word items from memory clears
the rest of the bigs in the register. */
#define BYTE_LOADS_ZERO_EXTEND
CCFP[E]mode is used. CC_NOOVmode should be used when the first operand is a
PLUS, MINUS, or NEG. CCmode should be used when no special processing is
needed. */
-#define SELECT_CC_MODE(OP,X) \
+#define SELECT_CC_MODE(OP,X,Y) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
? ((OP == EQ || OP == NE) ? CCFPmode : CCFPEmode) \
: ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS || GET_CODE (X) == NEG) \
#define ASM_APP_OFF ""
+#define ASM_LONG ".word"
+#define ASM_SHORT ".half"
+#define ASM_BYTE_OP ".byte"
+
/* Output before read-only data. */
#define TEXT_SECTION_ASM_OP ".text"
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
fprintf (FILE, "_%s", NAME)
-/* This is how to output an internal numbered label where
+/* This is how to output a definition of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
fprintf (FILE, "%s%d:\n", PREFIX, NUM)
+/* This is how to output a reference to an internal numbered label where
+ PREFIX is the class of label and NUM is the number within the class. */
+/* FIXME: This should be used throughout gcc, and documented in the texinfo
+ files. There is no reason you should have to allocate a buffer and
+ `sprintf' to reference an internal label (as opposed to defining it). */
+
+#define ASM_OUTPUT_INTERNAL_LABELREF(FILE,PREFIX,NUM) \
+ fprintf (FILE, "%s%d", PREFIX, NUM)
+
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
They reject 99e9999, but accept inf. */
#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
{ \
- if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.double 0r%sinf\n", (VALUE) > 0 ? "" : "-"); \
- else if (REAL_VALUE_ISNAN (VALUE) \
- || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
- union { double d; long l[2];} t; \
- t.d = (VALUE); \
- fprintf (FILE, "\t.word 0x%lx\n\t.word 0x%lx\n", t.l[0], t.l[1]); \
+ long t[2]; \
+ REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
+ fprintf (FILE, "\t%s\t0x%lx\n\t%s\t0x%lx\n", \
+ ASM_LONG, t[0], ASM_LONG, t[1]); \
} \
else \
fprintf (FILE, "\t.double 0r%.17g\n", VALUE); \
#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
{ \
- if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.single 0r%sinf\n", (VALUE) > 0 ? "" : "-"); \
- else if (REAL_VALUE_ISNAN (VALUE) \
- || REAL_VALUE_MINUS_ZERO (VALUE)) \
+ if (REAL_VALUE_ISINF (VALUE) \
+ || REAL_VALUE_ISNAN (VALUE) \
+ || REAL_VALUE_MINUS_ZERO (VALUE)) \
{ \
- union { float f; long l;} t; \
- t.f = (VALUE); \
- fprintf (FILE, "\t.word 0x%lx\n", t.l); \
+ long t; \
+ REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
+ fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t); \
} \
else \
fprintf (FILE, "\t.single 0r%.9g\n", VALUE); \
/* This is how to output an assembler line defining an `int' constant. */
#define ASM_OUTPUT_INT(FILE,VALUE) \
-( fprintf (FILE, "\t.word "), \
+( fprintf (FILE, "\t%s\t", ASM_LONG), \
output_addr_const (FILE, (VALUE)), \
fprintf (FILE, "\n"))
/* Likewise for `char' and `short' constants. */
#define ASM_OUTPUT_SHORT(FILE,VALUE) \
-( fprintf (FILE, "\t.half "), \
+( fprintf (FILE, "\t%s\t", ASM_SHORT), \
output_addr_const (FILE, (VALUE)), \
fprintf (FILE, "\n"))
#define ASM_OUTPUT_CHAR(FILE,VALUE) \
-( fprintf (FILE, "\t.byte "), \
+( fprintf (FILE, "\t%s\t", ASM_BYTE_OP), \
output_addr_const (FILE, (VALUE)), \
fprintf (FILE, "\n"))
/* This is how to output an assembler line for a numeric constant byte. */
#define ASM_OUTPUT_BYTE(FILE,VALUE) \
- fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
+ fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE))
/* This is how to output an element of a case-vector that is absolute. */
#define TARGET_CR 015
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
- ((CHAR) == '@' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^')
+ ((CHAR) == '@' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' \
+ || (CHAR) == '(')
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
extern char *output_scc_insn ();
extern char *output_cbranch ();
extern char *output_return ();
-extern char *output_floatsisf2 ();
-extern char *output_floatsidf2 ();
-extern char *output_floatsitf2 ();
/* Defined in flags.h, but insn-emit.c does not include flags.h. */