/* Definitions of target machine for GNU compiler, for Sun SPARC.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
/* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit
capable cpu's. */
#define TARGET_CPU_sparc 0
-#define TARGET_CPU_v7 0 /* alias for previous */
-#define TARGET_CPU_sparclet 1
-#define TARGET_CPU_sparclite 2
-#define TARGET_CPU_v8 3 /* generic v8 implementation */
-#define TARGET_CPU_supersparc 4
-#define TARGET_CPU_hypersparc 5
-#define TARGET_CPU_sparc86x 6
+#define TARGET_CPU_v7 0 /* alias */
+#define TARGET_CPU_cypress 0 /* alias */
+#define TARGET_CPU_v8 1 /* generic v8 implementation */
+#define TARGET_CPU_supersparc 2
+#define TARGET_CPU_hypersparc 3
+#define TARGET_CPU_leon 4
+#define TARGET_CPU_sparclite 5
+#define TARGET_CPU_f930 5 /* alias */
+#define TARGET_CPU_f934 5 /* alias */
#define TARGET_CPU_sparclite86x 6
-#define TARGET_CPU_v9 7 /* generic v9 implementation */
-#define TARGET_CPU_sparcv9 7 /* alias */
-#define TARGET_CPU_sparc64 7 /* alias */
-#define TARGET_CPU_ultrasparc 8
-#define TARGET_CPU_ultrasparc3 9
-#define TARGET_CPU_niagara 10
-#define TARGET_CPU_niagara2 11
+#define TARGET_CPU_sparclet 7
+#define TARGET_CPU_tsc701 7 /* alias */
+#define TARGET_CPU_v9 8 /* generic v9 implementation */
+#define TARGET_CPU_sparcv9 8 /* alias */
+#define TARGET_CPU_sparc64 8 /* alias */
+#define TARGET_CPU_ultrasparc 9
+#define TARGET_CPU_ultrasparc3 10
+#define TARGET_CPU_niagara 11
+#define TARGET_CPU_niagara2 12
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
|| TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
#define ASM_CPU32_DEFAULT_SPEC "-Asparclite"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x
+#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__"
+#define ASM_CPU32_DEFAULT_SPEC "-Asparclite"
+#endif
+
#if TARGET_CPU_DEFAULT == TARGET_CPU_supersparc
#define CPP_CPU32_DEFAULT_SPEC "-D__supersparc__ -D__sparc_v8__"
#define ASM_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
#endif
-#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x
-#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__"
-#define ASM_CPU32_DEFAULT_SPEC "-Asparclite"
+#if TARGET_CPU_DEFAULT == TARGET_CPU_leon
+#define CPP_CPU32_DEFAULT_SPEC "-D__leon__ -D__sparc_v8__"
+#define ASM_CPU32_DEFAULT_SPEC ""
#endif
#endif
for handling -mcpu=xxx switches. */
#define CPP_CPU_SPEC "\
%{msoft-float:-D_SOFT_FLOAT} \
-%{mcypress:} \
-%{msparclite:-D__sparclite__} \
-%{mf930:-D__sparclite__} %{mf934:-D__sparclite__} \
-%{mv8:-D__sparc_v8__} \
-%{msupersparc:-D__supersparc__ -D__sparc_v8__} \
%{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \
%{mcpu=sparclite:-D__sparclite__} \
%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \
+%{mcpu=sparclite86x:-D__sparclite86x__} \
%{mcpu=v8:-D__sparc_v8__} \
%{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \
%{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \
-%{mcpu=sparclite86x:-D__sparclite86x__} \
+%{mcpu=leon:-D__leon__ -D__sparc_v8__} \
%{mcpu=v9:-D__sparc_v9__} \
%{mcpu=ultrasparc:-D__sparc_v9__} \
%{mcpu=ultrasparc3:-D__sparc_v9__} \
%{mcpu=niagara:-D__sparc_v9__} \
%{mcpu=niagara2:-D__sparc_v9__} \
-%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
+%{!mcpu*:%(cpp_cpu_default)} \
"
#define CPP_ARCH32_SPEC ""
#define CPP_ARCH64_SPEC "-D__arch64__"
%{!m32:%{!m64:%(cpp_arch_default)}} \
"
-/* Macros to distinguish endianness. */
+/* Macro to distinguish endianness. */
#define CPP_ENDIAN_SPEC "\
-%{mlittle-endian:-D__LITTLE_ENDIAN__} \
-%{mlittle-endian-data:-D__LITTLE_ENDIAN_DATA__}"
+%{mlittle-endian:-D__LITTLE_ENDIAN__}"
/* Macros to distinguish the particular subtarget. */
#define CPP_SUBTARGET_SPEC ""
#define CPP_SPEC "%(cpp_cpu) %(cpp_arch) %(cpp_endian) %(cpp_subtarget)"
-/* 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. */
-/* Translate old style -m<cpu> into new style -mcpu=<cpu>.
- ??? Delete support for -m<cpu> for 2.9. */
-
-#define CC1_SPEC "\
-%{sun4:} %{target:} \
-%{mcypress:-mcpu=cypress} \
-%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \
-%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \
-"
+
+#define CC1_SPEC ""
/* Override in target specific files. */
#define ASM_CPU_SPEC "\
%{mcpu=sparclet:-Asparclet} %{mcpu=tsc701:-Asparclet} \
-%{msparclite:-Asparclite} \
-%{mf930:-Asparclite} %{mf934:-Asparclite} \
%{mcpu=sparclite:-Asparclite} \
%{mcpu=sparclite86x:-Asparclite} \
%{mcpu=f930:-Asparclite} %{mcpu=f934:-Asparclite} \
%{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
%{mcpu=niagara:%{!mv8plus:-Av9b}} \
%{mcpu=niagara2:%{!mv8plus:-Av9b}} \
-%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
+%{!mcpu*:%(asm_cpu_default)} \
"
/* Word size selection, among other things.
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC "\
-%{R} %{!pg:%{!p:%{fpic|fPIC|fpie|fPIE:-k}}} %{keep-local-as-symbols:-L} \
+%{!pg:%{!p:%{fpic|fPIC|fpie|fPIE:-k}}} %{keep-local-as-symbols:-L} \
%(asm_cpu) %(asm_relax)"
-#define AS_NEEDS_DASH_FOR_PIPED_INPUT
-
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
is an initializer with a subgrouping for each command option.
/* ??? This should be 32 bits for v9 but what can we do? */
#define WCHAR_TYPE "short unsigned int"
#define WCHAR_TYPE_SIZE 16
-
-/* Show we can debug even without a frame pointer. */
-#define CAN_DEBUG_WITHOUT_FP
-
-/* Option handling. */
-
-#define OVERRIDE_OPTIONS sparc_override_options ()
\f
/* Mask of all CPU selection flags. */
#define MASK_ISA \
/* MASK_APP_REGS must always be the default because that's what
FIXED_REGISTERS is set to and -ffixed- is processed before
- CONDITIONAL_REGISTER_USAGE is called (where we process -mno-app-regs). */
+ TARGET_CONDITIONAL_REGISTER_USAGE is called (where we process
+ -mno-app-regs). */
#define TARGET_DEFAULT (MASK_APP_REGS + MASK_FPU)
-/* Processor type.
- These must match the values for the cpu attribute in sparc.md. */
-enum processor_type {
- PROCESSOR_V7,
- PROCESSOR_CYPRESS,
- PROCESSOR_V8,
- PROCESSOR_SUPERSPARC,
- PROCESSOR_SPARCLITE,
- PROCESSOR_F930,
- PROCESSOR_F934,
- PROCESSOR_HYPERSPARC,
- PROCESSOR_SPARCLITE86X,
- PROCESSOR_SPARCLET,
- PROCESSOR_TSC701,
- PROCESSOR_V9,
- PROCESSOR_ULTRASPARC,
- PROCESSOR_ULTRASPARC3,
- PROCESSOR_NIAGARA,
- PROCESSOR_NIAGARA2
-};
-
-/* This is set from -m{cpu,tune}=xxx. */
-extern enum processor_type sparc_cpu;
-
/* Recast the cpu class to be the cpu attribute.
Every file includes us, but not every file includes insn-attr.h. */
#define sparc_cpu_attr ((enum attr_cpu) sparc_cpu)
#define OPTION_DEFAULT_SPECS \
{"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
- {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
-
-/* sparc_select[0] is reserved for the default cpu. */
-struct sparc_cpu_select
-{
- const char *string;
- const char *const name;
- const int set_tune_p;
- const int set_arch_p;
-};
-
-extern struct sparc_cpu_select sparc_select[];
+ {"float", "%{!msoft-float:%{!mhard-float:%{!mfpu:%{!mno-fpu:-m%(VALUE)-float}}}}" }
\f
/* target machine storage layout */
numbered. */
#define WORDS_BIG_ENDIAN 1
-/* Define this to set the endianness to use in libgcc2.c, which can
- not depend on target_flags. */
-#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#endif
-
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
#define MIN_UNITS_PER_WORD 4
#endif
-#define UNITS_PER_SIMD_WORD(MODE) (TARGET_VIS ? 8 : UNITS_PER_WORD)
-
/* Now define the sizes of the C data types. */
#define SHORT_TYPE_SIZE 16
if ptr_mode and Pmode are the same. */
#define POINTERS_EXTEND_UNSIGNED 1
-/* For TARGET_ARCH64 we need this, as we don't have instructions
- for arithmetic operations which do zero/sign extension at the same time,
- so without this we end up with a srl/sra after every assignment to an
- user variable, which means very very bad code. */
-#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
-if (TARGET_ARCH64 \
- && GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
- (MODE) = word_mode;
-
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
stack frames.
Registers fixed in arch32 and not arch64 (or vice-versa) are marked in
- CONDITIONAL_REGISTER_USAGE in order to properly handle -ffixed-.
+ TARGET_CONDITIONAL_REGISTER_USAGE in order to properly handle -ffixed-.
*/
#define FIXED_REGISTERS \
\
1, 1, 1, 1, 1, 1}
-/* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
- they won't be allocated. */
-
-#define CONDITIONAL_REGISTER_USAGE \
-do \
- { \
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- } \
- /* If the user has passed -f{fixed,call-{used,saved}}-g5 */ \
- /* then honor it. */ \
- if (TARGET_ARCH32 && fixed_regs[5]) \
- fixed_regs[5] = 1; \
- else if (TARGET_ARCH64 && fixed_regs[5] == 2) \
- fixed_regs[5] = 0; \
- if (! TARGET_V9) \
- { \
- int regno; \
- for (regno = SPARC_FIRST_V9_FP_REG; \
- regno <= SPARC_LAST_V9_FP_REG; \
- regno++) \
- fixed_regs[regno] = 1; \
- /* %fcc0 is used by v8 and v9. */ \
- for (regno = SPARC_FIRST_V9_FCC_REG + 1; \
- regno <= SPARC_LAST_V9_FCC_REG; \
- regno++) \
- fixed_regs[regno] = 1; \
- } \
- if (! TARGET_FPU) \
- { \
- int regno; \
- for (regno = 32; regno < SPARC_LAST_V9_FCC_REG; regno++) \
- fixed_regs[regno] = 1; \
- } \
- /* If the user has passed -f{fixed,call-{used,saved}}-g2 */ \
- /* then honor it. Likewise with g3 and g4. */ \
- if (fixed_regs[2] == 2) \
- fixed_regs[2] = ! TARGET_APP_REGS; \
- if (fixed_regs[3] == 2) \
- fixed_regs[3] = ! TARGET_APP_REGS; \
- if (TARGET_ARCH32 && fixed_regs[4] == 2) \
- fixed_regs[4] = ! TARGET_APP_REGS; \
- else if (TARGET_CM_EMBMEDANY) \
- fixed_regs[4] = 1; \
- else if (fixed_regs[4] == 2) \
- fixed_regs[4] = 0; \
- } \
-while (0)
-
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
This is ordinarily the length in words of a value of mode MODE
} \
} while (0)
-/* Value should be nonzero if functions must have frame pointers.
- Zero means the frame pointer need not be set up (and parms
- may be accessed via the stack pointer) in functions that seem suitable.
- Used in flow.c, global.c, ra.c and reload1.c. */
-#define FRAME_POINTER_REQUIRED \
- (! (leaf_function_p () && only_leaf_regs_used ()))
-
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
not be a register used by the prologue. */
#define STATIC_CHAIN_REGNUM (TARGET_ARCH64 ? 5 : 2)
+/* Register which holds the global offset table, if any. */
+
+#define GLOBAL_OFFSET_TABLE_REGNUM 23
+
/* Register which holds offset table for position-independent
data references. */
-#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM)
+#define PIC_OFFSET_TABLE_REGNUM \
+ (flag_pic ? GLOBAL_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
/* Pick a default value we can notice from override_options:
!v9: Default is on.
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
{-1, -1, -1, 0x3f}} /* ALL_REGS */
-/* The following macro defines cover classes for Integrated Register
- Allocator. Cover classes is a set of non-intersected register
- classes covering all hard registers used for register allocation
- purpose. Any move between two registers of a cover class should be
- cheaper than load or store of the registers. The macro value is
- array of register classes with LIM_REG_CLASSES used as the end
- marker. */
+/* The same information, inverted:
+ Return the class number of the smallest class containing
+ reg number REGNO. This could be a conditional expression
+ or could index an array. */
-#define IRA_COVER_CLASSES \
-{ \
- GENERAL_REGS, EXTRA_FP_REGS, FPCC_REGS, LIM_REG_CLASSES \
-}
+extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
+
+#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
/* Defines invalid mode changes. Borrowed from pa64-regs.h.
&& GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
-/* The same information, inverted:
- Return the class number of the smallest class containing
- reg number REGNO. This could be a conditional expression
- or could index an array. */
-
-extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
-
-#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
-
/* This is the order in which to allocate registers normally.
We put %f0-%f7 last among the float registers, so as to make it more
96, 97, 98, 99, /* %fcc0-3 */ \
100, 0, 14, 30, 31, 101} /* %icc, %g0, %o6, %i6, %i7, %sfp */
-#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
+#define ADJUST_REG_ALLOC_ORDER order_regs_for_local_alloc ()
extern char sparc_leaf_regs[];
#define LEAF_REGISTERS sparc_leaf_regs
#define SPARC_SETHI32_P(X) \
(SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode)))
-/* Given an rtx X being reloaded into a reg required to be
- 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. */
-/* - We can't load constants into FP registers.
- - We can't load FP constants into integer registers when soft-float,
- because there is no soft-float pattern with a r/F constraint.
- - We can't load FP constants into integer registers for TFmode unless
- it is 0.0L, because there is no movtf pattern with a r/F constraint.
- - Try and reload integer constants (symbolic or otherwise) back into
- registers directly, rather than having them dumped to memory. */
-
-#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- (CONSTANT_P (X) \
- ? ((FP_REG_CLASS_P (CLASS) \
- || (CLASS) == GENERAL_OR_FP_REGS \
- || (CLASS) == GENERAL_OR_EXTRA_FP_REGS \
- || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- && ! TARGET_FPU) \
- || (GET_MODE (X) == TFmode \
- && ! const_zero_operand (X, TFmode))) \
- ? NO_REGS \
- : (!FP_REG_CLASS_P (CLASS) \
- && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
- ? GENERAL_REGS \
- : (CLASS)) \
- : (CLASS))
-
/* Return the register class of a scratch register needed to load IN into
a register of class CLASS in MODE.
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
-/* The way this is structured, we can't eliminate SFP in favor of SP
- if the frame pointer is required: we want to use the SFP->HFP elimination
- in that case. But the test in update_eliminables doesn't know we are
- assuming below that we only do the former elimination. */
-#define CAN_ELIMINATE(FROM, TO) \
- ((TO) == HARD_FRAME_POINTER_REGNUM || !FRAME_POINTER_REQUIRED)
-
/* We always pretend that this is a leaf function because if it's not,
there's no point in trying to eliminate the frame pointer. If it
is a leaf function, we guessed right! */
the function! */
#define ACCUMULATE_OUTGOING_ARGS 1
-/* Value is the number of bytes of arguments automatically
- popped when returning from a subroutine call.
- FUNDECL is the declaration node of the function (as a tree),
- FUNTYPE is the data type of the function (as a tree),
- or for a library call it is an identifier node for the subroutine name.
- SIZE is the number of bytes of arguments passed on the stack. */
-
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
-
/* Define this macro if the target machine has "register windows". This
C expression returns the register number as seen by the called function
corresponding to register number OUT as seen by the calling function.
#define LOCAL_REGNO(REGNO) \
((REGNO) >= 16 && (REGNO) <= 31)
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-
-/* On SPARC the value is found in the first "output" register. */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- function_value ((VALTYPE), TYPE_MODE (VALTYPE), 1)
-
-/* But the called function leaves it in the first "input" register. */
-
-#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
- function_value ((VALTYPE), TYPE_MODE (VALTYPE), 0)
-
-/* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
-
-#define LIBCALL_VALUE(MODE) \
- function_value (NULL_TREE, (MODE), 1)
-
-/* 1 if N is a possible register number for a function value
- as seen by the caller.
- On SPARC, the first "output" reg is used for integer values,
- and the first floating point register is used for floating point values. */
-
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 8 || (N) == 32)
-
/* Define the size of space to allocate for the return value of an
untyped_call. */
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- TYPE is null for libcalls where that information may not be available. */
-
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-function_arg_advance (& (CUM), (MODE), (TYPE), (NAMED))
-
-/* Determine where to put an argument to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode.
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis). */
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-function_arg (& (CUM), (MODE), (TYPE), (NAMED), 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) \
-function_arg (& (CUM), (MODE), (TYPE), (NAMED), 1)
-
/* If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
`enum direction': either `upward' to pad above the argument,
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
function_arg_padding ((MODE), (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.
- For sparc64, objects requiring 16 byte alignment are passed that way. */
-
-#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
-((TARGET_ARCH64 \
- && (GET_MODE_ALIGNMENT (MODE) == 128 \
- || ((TYPE) && TYPE_ALIGN (TYPE) == 128))) \
- ? 128 : PARM_BOUNDARY)
-\f
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-
-extern GTY(()) rtx sparc_compare_op0;
-extern GTY(()) rtx sparc_compare_op1;
-
\f
/* Generate the special assembly code needed to tell the assembler whatever
it might need to know about the return value of a function.
#define TRAMPOLINE_SIZE (TARGET_ARCH64 ? 32 : 16)
#define TRAMPOLINE_ALIGNMENT 128 /* 16 bytes */
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
- FNADDR is an RTX for the address of the function's pure code.
- CXT is an RTX for the static chain value for the function. */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
- if (TARGET_ARCH64) \
- sparc64_initialize_trampoline (TRAMP, FNADDR, CXT); \
- else \
- sparc_initialize_trampoline (TRAMP, FNADDR, CXT)
\f
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
addresses which require two reload registers. */
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
-
-/* Nonzero if the constant value X is a legitimate general operand.
- Anything can be made to work except floating point constants.
- If TARGET_VIS, 0.0 can be made to work as well. */
-
-#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
-
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
- (REGNO (X) < 32 \
- || REGNO (X) == FRAME_POINTER_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-#endif
\f
/* Should gcc use [%reg+%lo(xx)+offset] addresses? */
#define USE_AS_OFFSETABLE_LO10 0
#endif
\f
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
- ordinarily. This changes a bit when generating PIC.
-
- If you change this, execute "rm explow.o recog.o reload.o". */
-
-#define SYMBOLIC_CONST(X) symbolic_operand (X, VOIDmode)
-
-#define RTX_OK_FOR_BASE_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
- || (GET_CODE (X) == SUBREG \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
-
-#define RTX_OK_FOR_INDEX_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \
- || (GET_CODE (X) == SUBREG \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && REG_OK_FOR_INDEX_P (SUBREG_REG (X))))
-
-#define RTX_OK_FOR_OFFSET_P(X) \
- (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000 - 8)
-
-#define RTX_OK_FOR_OLO10_P(X) \
- (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
-
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
-}
-#endif
-
-/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for.
-
- In PIC mode,
-
- (mem:HI [%l7+a])
-
- is not equivalent to
-
- (mem:QI [%l7+a]) (mem:QI [%l7+a+1])
-
- because [%l7+a+1] is interpreted as the address of (a+1). */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
-{ \
- if (flag_pic == 1) \
- { \
- if (GET_CODE (ADDR) == PLUS) \
- { \
- rtx op0 = XEXP (ADDR, 0); \
- rtx op1 = XEXP (ADDR, 1); \
- if (op0 == pic_offset_table_rtx \
- && SYMBOLIC_CONST (op1)) \
- goto LABEL; \
- } \
- } \
-}
-\f
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output. */
-
-/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ \
- (X) = legitimize_address (X, OLDX, MODE); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
- macro is used in only one place: `find_reloads_address' in reload.c.
-
- For SPARC 32, we wish to handle addresses by splitting them into
- HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
- This cuts the number of extra insns by one.
-
- Do nothing when generating PIC code and the address is a
- symbolic operand or requires a scratch register. */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
-do { \
- /* Decompose SImode constants into hi+lo_sum. We do have to \
- rerecognize what we produce, so be careful. */ \
- if (CONSTANT_P (X) \
- && (MODE != TFmode || TARGET_ARCH64) \
- && GET_MODE (X) == SImode \
- && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \
- && ! (flag_pic \
- && (symbolic_operand (X, Pmode) \
- || pic_address_needs_scratch (X))) \
- && sparc_cmodel <= CM_MEDLOW) \
- { \
- X = gen_rtx_LO_SUM (GET_MODE (X), \
- gen_rtx_HIGH (GET_MODE (X), X), X); \
- push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
- BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
- OPNUM, TYPE); \
- goto WIN; \
- } \
- /* ??? 64-bit reloads. */ \
+ macro is used in only one place: `find_reloads_address' in reload.c. */
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
+do { \
+ int win; \
+ (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM), \
+ (int)(TYPE), (IND_LEVELS), &win); \
+ if (win) \
+ goto WIN; \
} while (0)
\f
/* Specify the machine mode that this machine uses
#define DITF_CONVERSION_LIBFUNCS 0
#define SUN_INTEGER_MULTIPLY_64 0
-/* Compute extra cost of moving data between one register class
- and another. */
-#define GENERAL_OR_I64(C) ((C) == GENERAL_REGS || (C) == I64_REGS)
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- (((FP_REG_CLASS_P (CLASS1) && GENERAL_OR_I64 (CLASS2)) \
- || (GENERAL_OR_I64 (CLASS1) && FP_REG_CLASS_P (CLASS2)) \
- || (CLASS1) == FPCC_REGS || (CLASS2) == FPCC_REGS) \
- ? ((sparc_cpu == PROCESSOR_ULTRASPARC \
- || sparc_cpu == PROCESSOR_ULTRASPARC3 \
- || sparc_cpu == PROCESSOR_NIAGARA \
- || sparc_cpu == PROCESSOR_NIAGARA2) ? 12 : 6) : 2)
-
/* Provide the cost of a branch. For pre-v9 processors we use
a value of 3 to take into account the potential annulling of
the delay slot (which ends up being a bubble in the pipeline slot)
if ((LOG) != 0) \
fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
-/* This is how to output an assembler line that says to advance
- the location counter to a multiple of 2**LOG bytes using the
- "nop" instruction as padding. */
-#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
- if ((LOG) != 0) \
- fprintf (FILE, "\t.align %d,0x1000000\n", (1<<(LOG)))
-
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
fprintf (FILE, "\t.skip "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
} \
} while (0)
-#define SPARC_SYMBOL_REF_TLS_P(RTX) \
- (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
-
-#define PRINT_OPERAND_PUNCT_VALID_P(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.
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
-
-#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
-
-/* Print a memory address as an operand to reference that memory location. */
-
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-{ register rtx base, index = 0; \
- int offset = 0; \
- register rtx addr = ADDR; \
- if (GET_CODE (addr) == REG) \
- fputs (reg_names[REGNO (addr)], FILE); \
- else if (GET_CODE (addr) == PLUS) \
- { \
- if (GET_CODE (XEXP (addr, 0)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);\
- else if (GET_CODE (XEXP (addr, 1)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);\
- else \
- base = XEXP (addr, 0), index = XEXP (addr, 1); \
- if (GET_CODE (base) == LO_SUM) \
- { \
- gcc_assert (USE_AS_OFFSETABLE_LO10 \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID); \
- output_operand (XEXP (base, 0), 0); \
- fputs ("+%lo(", FILE); \
- output_address (XEXP (base, 1)); \
- fprintf (FILE, ")+%d", offset); \
- } \
- else \
- { \
- fputs (reg_names[REGNO (base)], FILE); \
- if (index == 0) \
- fprintf (FILE, "%+d", offset); \
- else if (GET_CODE (index) == REG) \
- fprintf (FILE, "+%s", reg_names[REGNO (index)]); \
- else if (GET_CODE (index) == SYMBOL_REF \
- || GET_CODE (index) == LABEL_REF \
- || GET_CODE (index) == CONST) \
- fputc ('+', FILE), output_addr_const (FILE, index); \
- else gcc_unreachable (); \
- } \
- } \
- else if (GET_CODE (addr) == MINUS \
- && GET_CODE (XEXP (addr, 1)) == LABEL_REF) \
- { \
- output_addr_const (FILE, XEXP (addr, 0)); \
- fputs ("-(", FILE); \
- output_addr_const (FILE, XEXP (addr, 1)); \
- fputs ("-.)", FILE); \
- } \
- else if (GET_CODE (addr) == LO_SUM) \
- { \
- output_operand (XEXP (addr, 0), 0); \
- if (TARGET_CM_MEDMID) \
- fputs ("+%l44(", FILE); \
- else \
- fputs ("+%lo(", FILE); \
- output_address (XEXP (addr, 1)); \
- fputc (')', FILE); \
- } \
- else if (flag_pic && GET_CODE (addr) == CONST \
- && GET_CODE (XEXP (addr, 0)) == MINUS \
- && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST \
- && GET_CODE (XEXP (XEXP (XEXP (addr, 0), 1), 0)) == MINUS \
- && XEXP (XEXP (XEXP (XEXP (addr, 0), 1), 0), 1) == pc_rtx) \
- { \
- addr = XEXP (addr, 0); \
- output_addr_const (FILE, XEXP (addr, 0)); \
- /* Group the args of the second CONST in parenthesis. */ \
- fputs ("-(", FILE); \
- /* Skip past the second CONST--it does nothing for us. */\
- output_addr_const (FILE, XEXP (XEXP (addr, 1), 0)); \
- /* Close the parenthesis. */ \
- fputc (')', FILE); \
- } \
- else \
- { \
- output_addr_const (FILE, addr); \
- } \
-}
-
/* TLS support defaulting to original Sun flavor. GNU extensions
must be activated in separate configuration files. */
#ifdef HAVE_AS_TLS