/* 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__sparcv8__}"
+#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
/* 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
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- (TREE_CODE (EXP) == STRING_CST \
- && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (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) \
#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.
#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. */