/* 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 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
/* Values of TARGET_CPU_DEFAULT, set via -D in the Makefile,
and specified by the user via --with-cpu=foo.
This specifies the cpu implementation, not the architecture size. */
-/* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit
+/* 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_sparcv9 7 /* alias */
#define TARGET_CPU_sparc64 7 /* alias */
#define TARGET_CPU_ultrasparc 8
+#define TARGET_CPU_ultrasparc3 9
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
- || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
#define CPP_CPU32_DEFAULT_SPEC ""
#define ASM_CPU32_DEFAULT_SPEC ""
#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
#define ASM_CPU64_DEFAULT_SPEC "-Av9a"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__"
+#define ASM_CPU64_DEFAULT_SPEC "-Av9b"
+#endif
#else
#endif
#if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC)
-Unrecognized value in TARGET_CPU_DEFAULT.
+ #error Unrecognized value in TARGET_CPU_DEFAULT.
#endif
#ifdef SPARC_BI_ARCH
%{mcpu=sparclite86x:-D__sparclite86x__} \
%{mcpu=v9:-D__sparc_v9__} \
%{mcpu=ultrasparc:-D__sparc_v9__} \
+%{mcpu=ultrasparc3:-D__sparc_v9__} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
"
sparc64 in 32 bit environments, so for now we only use `sparc64' in
64 bit environments. */
-#ifdef SPARC_BI_ARCH
-
-#define CPP_ARCH32_SPEC "-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int \
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
-#define CPP_ARCH64_SPEC "-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int \
--D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
-
-#else
-
#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
-#endif
-
#define CPP_ARCH_DEFAULT_SPEC \
(DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC)
%{mv8plus:-Av8plus} \
%{mcpu=v9:-Av9} \
%{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
+%{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
"
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC "\
-%| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
+%{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-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.
SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS
+
+/* Because libgcc can generate references back to libc (via .umul etc.) we have
+ to list libc again after the second libgcc. */
+#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G %L"
+
\f
-#ifdef SPARC_BI_ARCH
-#define NO_BUILTIN_PTRDIFF_TYPE
-#define NO_BUILTIN_SIZE_TYPE
-#endif
#define PTRDIFF_TYPE (TARGET_ARCH64 ? "long int" : "int")
#define SIZE_TYPE (TARGET_ARCH64 ? "long unsigned int" : "unsigned int")
/* ??? This should be 32 bits for v9 but what can we do? */
#define WCHAR_TYPE "short unsigned int"
#define WCHAR_TYPE_SIZE 16
-#define MAX_WCHAR_TYPE_SIZE 16
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
-/* To make profiling work with -f{pic,PIC}, we need to emit the profiling
- code into the rtl. Also, if we are profiling, we cannot eliminate
- the frame pointer (because the return address will get smashed). */
-
-#define OVERRIDE_OPTIONS \
- do { \
- if (profile_flag || profile_arc_flag) \
- { \
- if (flag_pic) \
- { \
- const char *const pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";\
- warning ("%s and profiling conflict: disabling %s", \
- pic_string, pic_string); \
- flag_pic = 0; \
- } \
- flag_omit_frame_pointer = 0; \
- } \
- sparc_override_options (); \
- SUBTARGET_OVERRIDE_OPTIONS; \
- } while (0)
-
-/* This is meant to be redefined in the host dependent files. */
-#define SUBTARGET_OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS sparc_override_options ()
/* Generate DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
\f
/* Run-time compilation parameters selecting different hardware subsets. */
#define MASK_FPU 1
#define TARGET_FPU (target_flags & MASK_FPU)
-/* Nonzero if we should use function_epilogue(). Otherwise, we
- use fast return insns, but lose some generality. */
-#define MASK_EPILOGUE 2
-#define TARGET_EPILOGUE (target_flags & MASK_EPILOGUE)
-
/* Nonzero if we should assume that double pointers might be unaligned.
This can happen when linking gcc compiled code with other compilers,
because the ABI only guarantees 4 byte alignment. */
#define MASK_V9 0x40
#define TARGET_V9 (target_flags & MASK_V9)
-/* Non-zero to generate code that uses the instructions deprecated in
+/* Nonzero to generate code that uses the instructions deprecated in
the v9 architecture. This option only applies to v9 systems. */
/* ??? This isn't user selectable yet. It's used to enable such insns
on 32 bit v9 systems and for the moment they're permanently disabled
#define MASK_ISA \
(MASK_V8 + MASK_SPARCLITE + MASK_SPARCLET + MASK_V9 + MASK_DEPRECATED_V8_INSNS)
-/* Non-zero means don't pass `-assert pure-text' to the linker. */
+/* Nonzero means don't pass `-assert pure-text' to the linker. */
#define MASK_IMPURE_TEXT 0x100
#define TARGET_IMPURE_TEXT (target_flags & MASK_IMPURE_TEXT)
#define MASK_FLAT 0x200
#define TARGET_FLAT (target_flags & MASK_FLAT)
-/* Nonzero means use the registers that the Sparc ABI reserves for
+/* Nonzero means use the registers that the SPARC ABI reserves for
application software. This must be the default to coincide with the
setting in FIXED_REGISTERS. */
#define MASK_APP_REGS 0x400
#define MASK_HARD_QUAD 0x800
#define TARGET_HARD_QUAD (target_flags & MASK_HARD_QUAD)
-/* Non-zero on little-endian machines. */
+/* Nonzero on little-endian machines. */
/* ??? Little endian support currently only exists for sparclet-aout and
sparc64-elf configurations. May eventually want to expand the support
to all targets, but for now it's kept local to only those two. */
/* 0x20000,0x40000 unused */
-/* Non-zero means use a stack bias of 2047. Stack offsets are obtained by
+/* Nonzero means use a stack bias of 2047. Stack offsets are obtained by
adding 2047 to %sp. This option is for v9 only and is the default. */
#define MASK_STACK_BIAS 0x80000
#define TARGET_STACK_BIAS (target_flags & MASK_STACK_BIAS)
/* 0x100000,0x200000 unused */
-/* Non-zero means -m{,no-}fpu was passed on the command line. */
+/* Nonzero means -m{,no-}fpu was passed on the command line. */
#define MASK_FPU_SET 0x400000
#define TARGET_FPU_SET (target_flags & MASK_FPU_SET)
/* Use the UltraSPARC Visual Instruction Set extensions. */
-#define MASK_VIS 0x1000000
+#define MASK_VIS 0x1000000
#define TARGET_VIS (target_flags & MASK_VIS)
/* Compile for Solaris V8+. 32 bit Solaris preserves the high bits of
the current out and global registers and Linux 2.2+ as well. */
#define MASK_V8PLUS 0x2000000
-#define TARGET_V8PLUS (target_flags & MASK_V8PLUS)
+#define TARGET_V8PLUS (target_flags & MASK_V8PLUS)
/* Force a the fastest alignment on structures to take advantage of
faster copies. */
#define TARGET_HARD_MUL \
(TARGET_V8 || TARGET_SPARCLITE || TARGET_SPARCLET \
- || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS)
+ || TARGET_DEPRECATED_V8_INSNS || TARGET_V8PLUS)
/* Macro to define tables used to set the flags.
{"soft-float", -MASK_FPU, \
N_("Do not use hardware fp") }, \
{"soft-float", MASK_FPU_SET, NULL }, \
- {"epilogue", MASK_EPILOGUE, \
- N_("Use function_epilogue()") }, \
- {"no-epilogue", -MASK_EPILOGUE, \
- N_("Do not use function_epilogue()") }, \
{"unaligned-doubles", MASK_UNALIGNED_DOUBLES, \
N_("Assume possible double misalignment") }, \
{"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES, \
{"cypress", 0, \
N_("Optimize for Cypress processors") }, \
{"sparclite", 0, \
- N_("Optimize for SparcLite processors") }, \
+ N_("Optimize for SPARCLite processors") }, \
{"f930", 0, \
N_("Optimize for F930 processors") }, \
{"f934", 0, \
N_("Optimize for F934 processors") }, \
{"v8", 0, \
- N_("Use V8 Sparc ISA") }, \
+ N_("Use V8 SPARC ISA") }, \
{"supersparc", 0, \
- N_("Optimize for SuperSparc processors") }, \
+ N_("Optimize for SuperSPARC processors") }, \
/* End of deprecated options. */ \
{"ptr64", MASK_PTR64, \
N_("Pointers are 64-bit") }, \
/* 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). */
-#define TARGET_DEFAULT (MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU)
+#define TARGET_DEFAULT (MASK_APP_REGS + MASK_FPU)
/* This is meant to be redefined in target specific files. */
#define SUBTARGET_SWITCHES
PROCESSOR_SPARCLET,
PROCESSOR_TSC701,
PROCESSOR_V9,
- PROCESSOR_ULTRASPARC
+ PROCESSOR_ULTRASPARC,
+ PROCESSOR_ULTRASPARC3
};
/* This is set from -m{cpu,tune}=xxx. */
#define TARGET_OPTIONS \
{ \
{ "cpu=", &sparc_select[1].string, \
- N_("Use features of and schedule code for given CPU") }, \
+ N_("Use features of and schedule code for given CPU"), 0}, \
{ "tune=", &sparc_select[2].string, \
- N_("Schedule code for given CPU") }, \
+ N_("Schedule code for given CPU"), 0}, \
{ "cmodel=", &sparc_cmodel_string, \
- N_("Use given Sparc code model") }, \
+ N_("Use given SPARC code model"), 0}, \
SUBTARGET_OPTIONS \
}
/* Width of a word, in units (bytes). */
#define UNITS_PER_WORD (TARGET_ARCH64 ? 8 : 4)
+#ifdef IN_LIBGCC2
+#define MIN_UNITS_PER_WORD UNITS_PER_WORD
+#else
#define MIN_UNITS_PER_WORD 4
+#endif
/* Now define the sizes of the C data types. */
/* ??? This does not work in SunOS 4.x, so it is not enabled here.
Instead, it is enabled in sol2.h, because it does work under Solaris. */
/* Define for support of TFmode long double.
- Sparc ABI says that long double is 4 words. */
+ SPARC ABI says that long double is 4 words. */
#define LONG_DOUBLE_TYPE_SIZE 128
#endif
/* Every structure's size must be a multiple of this. */
#define STRUCTURE_SIZE_BOUNDARY 8
-/* A bitfield declared as `int' forces `int' alignment for the struct. */
+/* A bit-field declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1
/* No data type wants to be aligned rounder than this. */
#ifndef SUNOS4_SHARED_LIBRARIES
#define SUNOS4_SHARED_LIBRARIES 0
#endif
-
-
-/* Use text section for a constant
- unless we need more alignment than that offers. */
-/* This is defined differently for v9 in a cover file. */
-#define SELECT_RTX_SECTION(MODE, X, ALIGN) \
-{ \
- if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
- && ! (flag_pic && (symbolic_operand ((X), (MODE)) || SUNOS4_SHARED_LIBRARIES))) \
- text_section (); \
- else \
- data_section (); \
-}
\f
/* Standard register usage. */
#define CONDITIONAL_REGISTER_USAGE \
do \
{ \
- if (flag_pic) \
+ 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 honour it. */ \
+ /* then honor it. */ \
if (TARGET_ARCH32 && fixed_regs[5]) \
fixed_regs[5] = 1; \
else if (TARGET_ARCH64 && fixed_regs[5] == 2) \
fixed_regs[regno] = 1; \
} \
/* If the user has passed -f{fixed,call-{used,saved}}-g2 */ \
- /* then honour it. Likewise with g3 and g4. */ \
+ /* 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[4] = 0; \
if (TARGET_FLAT) \
{ \
+ int regno; \
/* Let the compiler believe the frame pointer is still \
%fp, but output it as %i7. */ \
fixed_regs[31] = 1; \
reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7"; \
/* Disable leaf functions */ \
memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); \
+ /* Make LEAF_REG_REMAP a noop. */ \
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
+ leaf_reg_remap [regno] = regno; \
} \
} \
while (0)
#define FRAME_POINTER_REQUIRED \
(TARGET_FLAT \
? (current_function_calls_alloca \
- || current_function_varargs \
|| !leaf_function_p ()) \
: ! (leaf_function_p () && only_leaf_regs_used ()))
-/* C statement to store the difference between the frame pointer
- and the stack pointer values immediately after the function prologue.
-
- Note, 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! */
-#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
- ((VAR) = (TARGET_FLAT ? sparc_flat_compute_frame_size (get_frame_size ()) \
- : compute_frame_size (get_frame_size (), 1)))
-
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
/* Register which holds offset table for position-independent
data references. */
-#define PIC_OFFSET_TABLE_REGNUM 23
+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 23 : INVALID_REGNUM)
/* Pick a default value we can notice from override_options:
!v9: Default is on.
#define DEFAULT_PCC_STRUCT_RETURN -1
-/* Sparc ABI says that quad-precision floats and all structures are returned
+/* SPARC ABI says that quad-precision floats and all structures are returned
in memory.
For v9: unions <= 32 bytes in size are returned in int regs,
structures up to 32 bytes are returned in int and fp regs. */
#define REGNO_REG_CLASS(REGNO) sparc_regno_reg_class[(REGNO)]
-/* This is the order in which to allocate registers normally.
-
- We put %f0/%f1 last among the float registers, so as to make it more
+/* 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
likely that a pseudo-register which dies in the float return register
- will get allocated to the float return register, thus saving a move
- instruction at the end of the function. */
+ area will get allocated to the float return register, thus saving a move
+ instruction at the end of the function.
+
+ Similarly for integer return value registers.
+
+ We know in this case that we will not end up with a leaf function.
+
+ The register allocater is given the global and out registers first
+ because these registers are call clobbered and thus less useful to
+ global register allocation.
+
+ Next we list the local and in registers. They are not call clobbered
+ and thus very useful for global register allocation. We list the input
+ registers before the locals so that it is more likely the incoming
+ arguments received in those registers can just stay there and not be
+ reloaded. */
#define REG_ALLOC_ORDER \
-{ 8, 9, 10, 11, 12, 13, 2, 3, \
- 15, 16, 17, 18, 19, 20, 21, 22, \
- 23, 24, 25, 26, 27, 28, 29, 31, \
- 34, 35, 36, 37, 38, 39, /* %f2-%f7 */ \
+{ 1, 2, 3, 4, 5, 6, 7, /* %g1-%g7 */ \
+ 13, 12, 11, 10, 9, 8, /* %o5-%o0 */ \
+ 15, /* %o7 */ \
+ 16, 17, 18, 19, 20, 21, 22, 23, /* %l0-%l7 */ \
+ 29, 28, 27, 26, 25, 24, 31, /* %i5-%i0,%i7 */\
40, 41, 42, 43, 44, 45, 46, 47, /* %f8-%f15 */ \
48, 49, 50, 51, 52, 53, 54, 55, /* %f16-%f23 */ \
56, 57, 58, 59, 60, 61, 62, 63, /* %f24-%f31 */ \
72, 73, 74, 75, 76, 77, 78, 79, /* %f40-%f47 */ \
80, 81, 82, 83, 84, 85, 86, 87, /* %f48-%f55 */ \
88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
- 32, 33, /* %f0,%f1 */ \
- 96, 97, 98, 99, 100, /* %fcc0-3, %icc */ \
- 1, 4, 5, 6, 7, 0, 14, 30, 101}
+ 39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
+ 96, 97, 98, 99, /* %fcc0-3 */ \
+ 100, 0, 14, 30, 101} /* %icc, %g0, %o6, %i6, %sfp */
/* This is the order in which to allocate registers for
- leaf functions. If all registers can fit in the "gi" registers,
- then we have the possibility of having a leaf function. */
+ leaf functions. If all registers can fit in the global and
+ output registers, then we have the possibility of having a leaf
+ function.
+
+ The macro actually mentioned the input registers first,
+ because they get renumbered into the output registers once
+ we know really do have a leaf function.
+
+ To be more precise, this register allocation order is used
+ when %o7 is found to not be clobbered right before register
+ allocation. Normally, the reason %o7 would be clobbered is
+ due to a call which could not be transformed into a sibling
+ call.
+
+ As a consequence, it is possible to use the leaf register
+ allocation order and not end up with a leaf function. We will
+ not get suboptimal register allocation in that case because by
+ definition of being potentially leaf, there were no function
+ calls. Therefore, allocation order within the local register
+ window is not critical like it is when we do have function calls. */
#define REG_LEAF_ALLOC_ORDER \
-{ 2, 3, 24, 25, 26, 27, 28, 29, \
- 4, 5, 6, 7, 1, \
- 15, 8, 9, 10, 11, 12, 13, \
- 16, 17, 18, 19, 20, 21, 22, 23, \
- 34, 35, 36, 37, 38, 39, \
- 40, 41, 42, 43, 44, 45, 46, 47, \
- 48, 49, 50, 51, 52, 53, 54, 55, \
- 56, 57, 58, 59, 60, 61, 62, 63, \
- 64, 65, 66, 67, 68, 69, 70, 71, \
- 72, 73, 74, 75, 76, 77, 78, 79, \
- 80, 81, 82, 83, 84, 85, 86, 87, \
- 88, 89, 90, 91, 92, 93, 94, 95, \
- 32, 33, \
- 96, 97, 98, 99, 100, \
- 0, 14, 30, 31, 101}
-
+{ 1, 2, 3, 4, 5, 6, 7, /* %g1-%g7 */ \
+ 29, 28, 27, 26, 25, 24, /* %i5-%i0 */ \
+ 15, /* %o7 */ \
+ 13, 12, 11, 10, 9, 8, /* %o5-%o0 */ \
+ 16, 17, 18, 19, 20, 21, 22, 23, /* %l0-%l7 */ \
+ 40, 41, 42, 43, 44, 45, 46, 47, /* %f8-%f15 */ \
+ 48, 49, 50, 51, 52, 53, 54, 55, /* %f16-%f23 */ \
+ 56, 57, 58, 59, 60, 61, 62, 63, /* %f24-%f31 */ \
+ 64, 65, 66, 67, 68, 69, 70, 71, /* %f32-%f39 */ \
+ 72, 73, 74, 75, 76, 77, 78, 79, /* %f40-%f47 */ \
+ 80, 81, 82, 83, 84, 85, 86, 87, /* %f48-%f55 */ \
+ 88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
+ 39, 38, 37, 36, 35, 34, 33, 32, /* %f7-%f0 */ \
+ 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 ()
extern char sparc_leaf_regs[];
#define LEAF_REGISTERS sparc_leaf_regs
-extern const char leaf_reg_remap[];
+extern char leaf_reg_remap[];
#define LEAF_REG_REMAP(REGNO) (leaf_reg_remap[REGNO])
/* The class value for index registers, and the one for base regs. */
#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 \
We need a temporary when loading/storing a HImode/QImode value
between memory and the FPU registers. This can happen when combine puts
- a paradoxical subreg in a float/fix conversion insn. */
+ a paradoxical subreg in a float/fix conversion insn.
+
+ We need a temporary when loading/storing a DFmode value between
+ unaligned memory and the upper FPU registers. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
((FP_REG_CLASS_P (CLASS) \
|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \
&& true_regnum (IN) == -1))) \
? GENERAL_REGS \
- : (((TARGET_CM_MEDANY \
- && symbolic_operand ((IN), (MODE))) \
- || (TARGET_CM_EMBMEDANY \
- && text_segment_operand ((IN), (MODE)))) \
- && !flag_pic) \
- ? GENERAL_REGS \
- : NO_REGS)
+ : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode \
+ && GET_CODE (IN) == MEM && TARGET_ARCH32 \
+ && ! mem_min_alignment ((IN), 8)) \
+ ? FP_REGS \
+ : (((TARGET_CM_MEDANY \
+ && symbolic_operand ((IN), (MODE))) \
+ || (TARGET_CM_EMBMEDANY \
+ && text_segment_operand ((IN), (MODE)))) \
+ && !flag_pic) \
+ ? GENERAL_REGS \
+ : NO_REGS)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \
- ((FP_REG_CLASS_P (CLASS) \
+ ((FP_REG_CLASS_P (CLASS) \
&& ((MODE) == HImode || (MODE) == QImode) \
&& (GET_CODE (IN) == MEM \
|| ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \
&& true_regnum (IN) == -1))) \
- ? GENERAL_REGS \
- : (((TARGET_CM_MEDANY \
- && symbolic_operand ((IN), (MODE))) \
- || (TARGET_CM_EMBMEDANY \
- && text_segment_operand ((IN), (MODE)))) \
- && !flag_pic) \
- ? GENERAL_REGS \
- : NO_REGS)
-
-/* On SPARC it is not possible to directly move data between
+ ? GENERAL_REGS \
+ : ((CLASS) == EXTRA_FP_REGS && (MODE) == DFmode \
+ && GET_CODE (IN) == MEM && TARGET_ARCH32 \
+ && ! mem_min_alignment ((IN), 8)) \
+ ? FP_REGS \
+ : (((TARGET_CM_MEDANY \
+ && symbolic_operand ((IN), (MODE))) \
+ || (TARGET_CM_EMBMEDANY \
+ && text_segment_operand ((IN), (MODE)))) \
+ && !flag_pic) \
+ ? 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) \
(FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
/* Definitions for register elimination. */
/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */
-
+
#define ELIMINABLE_REGS \
- {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+ {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
-#define CAN_ELIMINATE(FROM, TO) 1
+/* 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)
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- ((OFFSET) = SPARC_STACK_BIAS)
+ do { \
+ (OFFSET) = 0; \
+ if ((TO) == STACK_POINTER_REGNUM) \
+ { \
+ /* Note, 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! */ \
+ if (TARGET_FLAT) \
+ (OFFSET) = \
+ sparc_flat_compute_frame_size (get_frame_size ()); \
+ else \
+ (OFFSET) = compute_frame_size (get_frame_size (), 1); \
+ } \
+ (OFFSET) += SPARC_STACK_BIAS; \
+ } while (0)
/* Keep the stack pointer constant throughout the function.
This is both an optimization and a necessity: longjmp
struct sparc_args {
int words; /* number of words passed so far */
- int prototype_p; /* non-zero if a prototype is present */
- int libcall_p; /* non-zero if a library call */
+ int prototype_p; /* nonzero if a prototype is present */
+ int libcall_p; /* nonzero if a library call */
};
#define CUMULATIVE_ARGS struct sparc_args
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
-init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (INDIRECT));
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL) \
+init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
-extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
+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.
- For Sparc assemblers, we need to output a .proc pseudo-op which conveys
+ For SPARC assemblers, we need to output a .proc pseudo-op which conveys
information to the assembler relating to peephole optimization (done in
the assembler). */
fprintf ((FILE), "\t.proc\t0%lo\n", sparc_type_code (TREE_TYPE (RESULT)))
/* Output the special assembly code needed to tell the assembler some
- register is used as global register variable.
+ register is used as global register variable.
SPARC 64bit psABI declares registers %g2 and %g3 as application
registers and %g6 and %g7 as OS registers. Any object using them
#endif
\f
-/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry. */
+/* Emit rtl for profiling. */
+#define PROFILE_HOOK(LABEL) sparc_profile_hook (LABEL)
-#define FUNCTION_PROFILER(FILE, LABELNO) \
- sparc_function_profiler(FILE, LABELNO)
+/* All the work done in PROFILE_HOOK, but still required. */
+#define FUNCTION_PROFILER(FILE, LABELNO) do { } while (0)
/* Set the name of the mcount function for the system. */
-
#define MCOUNT_FUNCTION "*mcount"
\f
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
#define EXPAND_BUILTIN_SAVEREGS() sparc_builtin_saveregs ()
/* Implement `va_start' for varargs and stdarg. */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
- sparc_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+ sparc_va_start (valist, nextarg)
/* Implement `va_arg'. */
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
#define STRICT_ARGUMENT_NAMING TARGET_V9
-/* We do not allow sibling calls if -mflat, nor
- we do not allow indirect calls to be optimized into sibling calls. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) (DECL && ! TARGET_FLAT)
-
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
#define SETUP_FRAME_ADDRESSES() \
return an rtx for the address of the word in the frame
that holds the dynamic chain--the previous frame's address.
??? -mflat support? */
-#define DYNAMIC_CHAIN_ADDRESS(frame) plus_constant (frame, 14 * UNITS_PER_WORD)
+#define DYNAMIC_CHAIN_ADDRESS(frame) \
+ plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
/* The return address isn't on the stack, it is in a register, so we can't
access it from the current frame pointer. We can access it from the
? gen_rtx_REG (Pmode, 31) \
: gen_rtx_MEM (Pmode, \
memory_address (Pmode, plus_constant (frame, \
- 15 * UNITS_PER_WORD))))
+ 15 * UNITS_PER_WORD \
+ + SPARC_STACK_BIAS))))
/* Before the prologue, the return address is %o7 + 8. OK, sometimes it's
+12, but always using +8 is close enough for frame unwind purposes.
If assembler and linker properly support .uaword %r_disp32(foo),
then use PC relative 32-bit relocations instead of absolute relocs
for shared libraries. On sparc64, use pc relative 32-bit relocs even
- for binaries, to save memory. */
+ for binaries, to save memory.
+
+ binutils 2.12 would emit a R_SPARC_DISP32 dynamic relocation if the
+ symbol %r_disp32() is against was not local, but .hidden. In that
+ case, we have to use DW_EH_PE_absptr for pic personality. */
#ifdef HAVE_AS_SPARC_UA_PCREL
+#ifdef HAVE_AS_SPARC_UA_PCREL_HIDDEN
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(flag_pic \
? (GLOBAL ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
: ((TARGET_ARCH64 && ! GLOBAL) \
? (DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
: DW_EH_PE_absptr))
+#else
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
+ (flag_pic \
+ ? (GLOBAL ? DW_EH_PE_absptr : (DW_EH_PE_pcrel | DW_EH_PE_sdata4)) \
+ : ((TARGET_ARCH64 && ! GLOBAL) \
+ ? (DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
+ : DW_EH_PE_absptr))
+#endif
/* Emit a PC-relative relocation. */
#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL) \
\f
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
be at least 8 bytes.
`U' handles all pseudo registers or a hard even numbered
- integer register, needed for ldd/std instructions. */
+ integer register, needed for ldd/std instructions.
-#define EXTRA_CONSTRAINT_BASE(OP, C) \
- ((C) == 'Q' ? fp_sethi_p(OP) \
- : (C) == 'R' ? fp_mov_p(OP) \
- : (C) == 'S' ? fp_high_losum_p(OP) \
- : 0)
+ 'W' handles the memory operand when moving operands in/out
+ of 'e' constraint floating point registers. */
#ifndef REG_OK_STRICT
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
-/* 'T', 'U' are for aligned memory loads which aren't needed for arch64. */
+/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.
+ 'W' is like 'T' but is assumed true on arch64.
+
+ Remember to accept pseudo-registers for memory constraints if reload is
+ in progress. */
-#define EXTRA_CONSTRAINT(OP, C) \
- (EXTRA_CONSTRAINT_BASE(OP, C) \
- || ((! TARGET_ARCH64 && (C) == 'T') \
- ? (mem_min_alignment (OP, 8)) \
- : ((! TARGET_ARCH64 && (C) == 'U') \
- ? (register_ok_for_ldd (OP)) \
- : 0)))
+#define EXTRA_CONSTRAINT(OP, C) \
+ sparc_extra_constraint_check(OP, C, 0)
#else
/* 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))
-#define EXTRA_CONSTRAINT(OP, C) \
- (EXTRA_CONSTRAINT_BASE(OP, C) \
- || ((! TARGET_ARCH64 && (C) == 'T') \
- ? mem_min_alignment (OP, 8) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \
- : ((! TARGET_ARCH64 && (C) == 'U') \
- ? (GET_CODE (OP) == REG \
- && (REGNO (OP) < FIRST_PSEUDO_REGISTER \
- || reg_renumber[REGNO (OP)] >= 0) \
- && register_ok_for_ldd (OP)) \
- : 0)))
+#define EXTRA_CONSTRAINT(OP, C) \
+ sparc_extra_constraint_check(OP, C, 1)
#endif
\f
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 \
#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)
&& GET_CODE (op1) != REG \
&& GET_CODE (op1) != LO_SUM \
&& GET_CODE (op1) != MEM \
+ && (! SYMBOLIC_CONST (op1) \
+ || MODE == Pmode) \
&& (GET_CODE (op1) != CONST_INT \
|| SMALL_INT (op1))) \
goto ADDR; \
else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \
goto ADDR; \
}
+
+/* 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.
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.
+ 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
/* 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_V9) \
+ && (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)))) \
+ || 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); \
} \
/* ??? 64-bit reloads. */ \
} while (0)
-
-/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for.
- On the SPARC this is never true. */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL)
-
-/* If we are referencing a function make the SYMBOL_REF special.
- In the Embedded Medium/Anywhere code model, %g4 points to the data segment
- so we must not add it to function addresses. */
-
-#define ENCODE_SECTION_INFO(DECL, FIRST) \
- do { \
- if (TARGET_CM_EMBMEDANY && TREE_CODE (DECL) == FUNCTION_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- } while (0)
\f
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
/* Generate calls to memcpy, memcmp and memset. */
#define TARGET_MEM_FUNCTIONS
-/* Add any extra modes needed to represent the condition code.
-
- On the Sparc, we have a "no-overflow" mode which is used when an add or
- subtract insn is used to set the condition code. Different branches are
- used in this case for some operations.
-
- We also have two modes to indicate that the relevant condition code is
- in the floating-point condition code register. One for comparisons which
- will generate an exception if the result is unordered (CCFPEmode) and
- one for comparisons which will never trap (CCFPmode).
-
- CCXmode and CCX_NOOVmode are only used by v9. */
-
-#define EXTRA_CC_MODES \
- CC(CCXmode, "CCX") \
- CC(CC_NOOVmode, "CC_NOOV") \
- CC(CCX_NOOVmode, "CCX_NOOV") \
- CC(CCFPmode, "CCFP") \
- CC(CCFPEmode, "CCFPE")
-
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. For floating-point,
CCFP[E]mode is used. CC_NOOVmode should be used when the first operand
processing is needed. */
#define SELECT_CC_MODE(OP,X,Y) select_cc_mode ((OP), (X), (Y))
-/* Return non-zero if MODE implies a floating point inequality can be
- reversed. For Sparc this is always true because we have a full
+/* Return nonzero if MODE implies a floating point inequality can be
+ reversed. For SPARC this is always true because we have a full
compliment of ordered and unordered comparisons, but until generic
code knows how to reverse it correctly we keep the old definition. */
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode && (MODE) != CCFPmode)
#define LTTF2_LIBCALL "_Q_flt"
#define LETF2_LIBCALL "_Q_fle"
+/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
+ that the inputs are fully consumed before the output memory is clobbered. */
+
+#define TARGET_BUGGY_QP_LIB 0
+
/* We can define the TFmode sqrt optab only if TARGET_FPU. This is because
with soft-float, the SFmode and DFmode sqrt instructions will be absent,
and the compiler will notice and try to use the TFmode sqrt instruction
sqrt_optab->handlers[(int) TFmode].libfunc \
= init_one_libfunc ("_Q_sqrt"); \
} \
+ if (TARGET_ARCH64) \
+ { \
+ /* In the SPARC 64bit ABI, these libfuncs do not exist in the \
+ library. Make sure the compiler does not emit calls to them \
+ by accident. */ \
+ sdiv_optab->handlers[(int) SImode].libfunc = NULL; \
+ udiv_optab->handlers[(int) SImode].libfunc = NULL; \
+ smod_optab->handlers[(int) SImode].libfunc = NULL; \
+ umod_optab->handlers[(int) SImode].libfunc = NULL; \
+ smul_optab->handlers[(int) SImode].libfunc = NULL; \
+ } \
INIT_SUBTARGET_OPTABS; \
} while (0)
of the libgcc2 functions is used. */
#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) < 0x1000 && INTVAL (RTX) >= -0x1000) \
- return 0; \
- case HIGH: \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 4; \
- case CONST_DOUBLE: \
- if (GET_MODE (RTX) == DImode) \
- if ((XINT (RTX, 3) == 0 \
- && (unsigned) XINT (RTX, 2) < 0x1000) \
- || (XINT (RTX, 3) == -1 \
- && XINT (RTX, 2) < 0 \
- && XINT (RTX, 2) >= -0x1000)) \
- return 0; \
- return 8;
-
-#define ADDRESS_COST(RTX) 1
-
/* Compute extra cost of moving data between one register class
and another. */
#define GENERAL_OR_I64(C) ((C) == GENERAL_REGS || (C) == I64_REGS)
(((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 ? 12 : 6) : 2)
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable.
-
- If we need more than 12 insns to do a multiply, then go out-of-line,
- since the call overhead will be < 10% of the cost of the multiply. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MULT: \
- if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- return (GET_MODE (X) == DImode ? \
- COSTS_N_INSNS (34) : COSTS_N_INSNS (19)); \
- return TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- return (GET_MODE (X) == DImode ? \
- COSTS_N_INSNS (68) : COSTS_N_INSNS (37)); \
- return COSTS_N_INSNS (25); \
- /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\
- so that cse will favor the latter. */ \
- case FLOAT: \
- case FIX: \
- return 19;
-
-/* Conditional branches with empty delay slots have a length of two. */
-#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
-do { \
- if (GET_CODE (INSN) == CALL_INSN \
- || (GET_CODE (INSN) == JUMP_INSN && ! simplejump_p (insn))) \
- LENGTH += 1; \
-} while (0)
+ ? ((sparc_cpu == PROCESSOR_ULTRASPARC \
+ || sparc_cpu == PROCESSOR_ULTRASPARC3) ? 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)
+ plus a cycle to take into consideration the instruction cache
+ effects.
+
+ On v9 and later, which have branch prediction facilities, we set
+ it to the depth of the pipeline as that is the cost of a
+ mispredicted branch. */
+
+#define BRANCH_COST \
+ ((sparc_cpu == PROCESSOR_V9 \
+ || sparc_cpu == PROCESSOR_ULTRASPARC) \
+ ? 7 \
+ : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+ ? 9 : 3))
+
+#define PREFETCH_BLOCK \
+ ((sparc_cpu == PROCESSOR_ULTRASPARC \
+ || sparc_cpu == PROCESSOR_ULTRASPARC3) \
+ ? 64 : 32)
+
+#define SIMULTANEOUS_PREFETCHES \
+ ((sparc_cpu == PROCESSOR_ULTRASPARC) \
+ ? 2 \
+ : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+ ? 8 : 3))
\f
/* Control the assembler format that we output. */
guess... */
#define DBX_CONTIN_LENGTH 1000
-/* This is how to output the definition of a user-level label named NAME,
- such as the label on a static function or variable NAME. */
-
-#define ASM_OUTPUT_LABEL(FILE,NAME) \
- do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
-
/* This is how to output a command to make the user-level label named NAME
defined for reference from other files. */
-#define ASM_GLOBALIZE_LABEL(FILE,NAME) \
- do { fputs ("\t.global ", FILE); assemble_name (FILE, NAME); fputs ("\n", FILE);} while (0)
+/* Globalizing directive for a label. */
+#define GLOBAL_ASM_OP "\t.global "
/* The prefix to add to user-visible assembler symbols. */
#define USER_LABEL_PREFIX "_"
-/* 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 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.
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 %u\n", (SIZE))
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
- fputs (".globl ", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs ("\n", (FILE)); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
#define IDENT_ASM_OP "\t.ident\t"
/* Output #ident as a .ident. */
#define ASM_OUTPUT_IDENT(FILE, NAME) \
fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
-/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
- Used for C++ multiple inheritance. */
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-do { \
- int reg = 0; \
- \
- if (TARGET_ARCH64 \
- && aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))) \
- reg = 1; \
- if ((DELTA) >= 4096 || (DELTA) < -4096) \
- fprintf (FILE, "\tset\t%d, %%g1\n\tadd\t%%o%d, %%g1, %%o%d\n", \
- (int)(DELTA), reg, reg); \
- else \
- fprintf (FILE, "\tadd\t%%o%d, %d, %%o%d\n", reg, (int)(DELTA), reg);\
- fprintf (FILE, "\tor\t%%o7, %%g0, %%g1\n"); \
- fprintf (FILE, "\tcall\t"); \
- assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
- fprintf (FILE, ", 0\n"); \
- fprintf (FILE, "\t or\t%%g1, %%g0, %%o7\n"); \
-} while (0)
-
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
#define PREDICATE_CODES \
{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+{"const1_operand", {CONST_INT}}, \
{"fp_zero_operand", {CONST_DOUBLE}}, \
+{"fp_register_operand", {SUBREG, REG}}, \
{"intreg_operand", {SUBREG, REG}}, \
{"fcc_reg_operand", {REG}}, \
+{"fcc0_reg_operand", {REG}}, \
{"icc_or_fcc_reg_operand", {REG}}, \
{"restore_operand", {REG}}, \
{"call_operand", {MEM}}, \
{"eq_or_neq", {EQ, NE}}, \
{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \
{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \
+{"noov_compare64_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \
{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \
{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \
{"cc_arithop", {AND, IOR, XOR}}, \
#define JMP_BUF_SIZE 12
#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
-