summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/sparc/sparc.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/sparc/sparc.h')
-rw-r--r--contrib/gcc/config/sparc/sparc.h407
1 files changed, 189 insertions, 218 deletions
diff --git a/contrib/gcc/config/sparc/sparc.h b/contrib/gcc/config/sparc/sparc.h
index 2902f06..7c6a7fd 100644
--- a/contrib/gcc/config/sparc/sparc.h
+++ b/contrib/gcc/config/sparc/sparc.h
@@ -107,7 +107,7 @@ extern enum cmodel sparc_cmodel;
/* 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 */
@@ -122,9 +122,11 @@ extern enum cmodel sparc_cmodel;
#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 ""
@@ -141,6 +143,10 @@ extern enum cmodel sparc_cmodel;
#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
@@ -181,7 +187,7 @@ extern enum cmodel sparc_cmodel;
#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
@@ -230,6 +236,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{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)}}}}}}} \
"
@@ -239,20 +246,9 @@ Unrecognized value in TARGET_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)
@@ -296,6 +292,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mv8plus:-Av8plus} \
%{mcpu=v9:-Av9} \
%{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
+%{mcpu=ultrasparc3:%{!mv8plus:-Av9b}} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(asm_cpu_default)}}}}}}} \
"
@@ -364,10 +361,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G %L"
-#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")
@@ -382,7 +375,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Generate DBX debugging information. */
-#define DBX_DEBUGGING_INFO
+#define DBX_DEBUGGING_INFO 1
/* Run-time compilation parameters selecting different hardware subsets. */
@@ -418,7 +411,7 @@ extern int target_flags;
#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
@@ -430,7 +423,7 @@ extern int target_flags;
#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)
@@ -441,7 +434,7 @@ extern int target_flags;
#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
@@ -453,7 +446,7 @@ extern int target_flags;
#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. */
@@ -474,25 +467,25 @@ extern int target_flags;
/* 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. */
@@ -515,7 +508,7 @@ extern int target_flags;
#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.
@@ -567,15 +560,15 @@ extern int target_flags;
{"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") }, \
@@ -623,7 +616,8 @@ enum processor_type {
PROCESSOR_SPARCLET,
PROCESSOR_TSC701,
PROCESSOR_V9,
- PROCESSOR_ULTRASPARC
+ PROCESSOR_ULTRASPARC,
+ PROCESSOR_ULTRASPARC3
};
/* This is set from -m{cpu,tune}=xxx. */
@@ -640,7 +634,7 @@ extern enum processor_type sparc_cpu;
{ "tune=", &sparc_select[2].string, \
N_("Schedule code for given CPU") }, \
{ "cmodel=", &sparc_cmodel_string, \
- N_("Use given Sparc code model") }, \
+ N_("Use given SPARC code model") }, \
SUBTARGET_OPTIONS \
}
@@ -660,10 +654,6 @@ extern struct sparc_cpu_select sparc_select[];
/* target machine storage layout */
-/* Define for cross-compilation to a sparc target with no TFmode from a host
- with a different float format (e.g. VAX). */
-#define REAL_ARITHMETIC
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 1
@@ -683,14 +673,6 @@ extern struct sparc_cpu_select sparc_select[];
#define LIBGCC2_WORDS_BIG_ENDIAN 1
#endif
-/* number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
- Note that this is not necessarily the width of data type `int';
- if using 16-bit ints on a 68000, this would still be 32.
- But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD (TARGET_ARCH64 ? 64 : 32)
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
@@ -717,8 +699,8 @@ extern struct sparc_cpu_select sparc_select[];
#if 0
/* ??? 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 and REAL_ARITHMETIC.
- Sparc ABI says that long double is 4 words. */
+/* Define for support of TFmode long double.
+ SPARC ABI says that long double is 4 words. */
#define LONG_DOUBLE_TYPE_SIZE 128
#endif
@@ -789,7 +771,7 @@ if (TARGET_ARCH64 \
/* 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. */
@@ -844,19 +826,6 @@ if (TARGET_ARCH64 \
#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 (); \
-}
/* Standard register usage. */
@@ -979,7 +948,7 @@ do \
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) \
@@ -1004,7 +973,7 @@ do \
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) \
@@ -1128,7 +1097,6 @@ extern int sparc_mode_class[];
#define FRAME_POINTER_REQUIRED \
(TARGET_FLAT \
? (current_function_calls_alloca \
- || current_function_varargs \
|| !leaf_function_p ()) \
: ! (leaf_function_p () && only_leaf_regs_used ()))
@@ -1150,7 +1118,7 @@ extern int sparc_mode_class[];
#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. */
@@ -1274,18 +1242,33 @@ 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/%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 */ \
@@ -1293,31 +1276,49 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
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[];
@@ -1365,7 +1366,8 @@ extern char leaf_reg_remap[];
`K' is used for constants which can be loaded with a single sethi insn.
`L' is used for the range of constants supported by the movcc insns.
`M' is used for the range of constants supported by the movrcc insns.
- `N' is like K, but for constants wider than 32 bits. */
+ `N' is like K, but for constants wider than 32 bits.
+ `O' is used for the range which is just 4096. */
#define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400)
#define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800)
@@ -1389,6 +1391,7 @@ extern char leaf_reg_remap[];
: (C) == 'L' ? SPARC_SIMM11_P (VALUE) \
: (C) == 'M' ? SPARC_SIMM10_P (VALUE) \
: (C) == 'N' ? SPARC_SETHI_P (VALUE) \
+ : (C) == 'O' ? (VALUE) == 4096 \
: 0)
/* Similar, but for floating constants, and defining letters G and H.
@@ -1397,6 +1400,7 @@ extern char leaf_reg_remap[];
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'G' ? fp_zero_operand (VALUE, GET_MODE (VALUE)) \
: (C) == 'H' ? arith_double_operand (VALUE, DImode) \
+ : (C) == 'O' ? arith_double_4096_operand (VALUE, DImode) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
@@ -1475,7 +1479,7 @@ extern char leaf_reg_remap[];
? GENERAL_REGS \
: NO_REGS)
-/* On SPARC it is not possible to directly move data between
+/* 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))
@@ -1571,7 +1575,7 @@ extern char leaf_reg_remap[];
/* Definitions for register elimination. */
/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */
-
+
#define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
@@ -1722,8 +1726,8 @@ extern char leaf_reg_remap[];
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
@@ -1809,13 +1813,14 @@ function_arg_padding ((MODE), (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;
/* 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). */
@@ -1823,7 +1828,7 @@ extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
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
@@ -1910,8 +1915,8 @@ do { \
#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) \
@@ -2203,6 +2208,8 @@ do { \
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 \
@@ -2217,7 +2224,7 @@ do { \
#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)
@@ -2236,6 +2243,8 @@ do { \
&& 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; \
@@ -2323,6 +2332,34 @@ do { \
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; \
+ } \
+ } \
+}
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
@@ -2371,8 +2408,8 @@ do { \
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
@@ -2400,22 +2437,6 @@ do { \
} \
/* ??? 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) \
- do { \
- if (TARGET_CM_EMBMEDANY && TREE_CODE (DECL) == FUNCTION_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- } while (0)
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
@@ -2494,26 +2515,6 @@ do { \
/* 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
@@ -2521,8 +2522,8 @@ do { \
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)
@@ -2634,33 +2635,6 @@ do { \
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)
@@ -2668,7 +2642,8 @@ do { \
(((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)
+ ? ((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
@@ -2678,48 +2653,48 @@ do { \
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.
-
- ??? Set to 9 when PROCESSOR_ULTRASPARC3 is added */
+ mispredicted branch. */
#define BRANCH_COST \
((sparc_cpu == PROCESSOR_V9 \
|| sparc_cpu == PROCESSOR_ULTRASPARC) \
- ? 7 : 3)
+ ? 7 \
+ : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+ ? 9 : 3))
+
+/* The cases that RTX_COSTS handles. */
+
+#define RTX_COSTS_CASES \
+case PLUS: case MINUS: case ABS: case NEG: \
+case FLOAT: case UNSIGNED_FLOAT: \
+case FIX: case UNSIGNED_FIX: \
+case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
+case SQRT: \
+case COMPARE: case IF_THEN_ELSE: \
+case MEM: \
+case MULT: case DIV: case UDIV: case MOD: case UMOD: \
+case CONST_INT: case HIGH: case CONST: \
+case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
/* 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. */
+ switch on CODE. */
#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;
+ RTX_COSTS_CASES \
+ return sparc_rtx_costs(X,CODE,OUTER_CODE);
+
+#define ADDRESS_COST(RTX) 1
#define PREFETCH_BLOCK \
- ((sparc_cpu == PROCESSOR_ULTRASPARC) ? 64 : 32)
+ ((sparc_cpu == PROCESSOR_ULTRASPARC \
+ || sparc_cpu == PROCESSOR_ULTRASPARC3) \
+ ? 64 : 32)
-/* ??? UltraSPARC-III note: Can set this to 8 for ultra3. */
#define SIMULTANEOUS_PREFETCHES \
- ((sparc_cpu == PROCESSOR_ULTRASPARC) ? 2 : 3)
+ ((sparc_cpu == PROCESSOR_ULTRASPARC) \
+ ? 2 \
+ : (sparc_cpu == PROCESSOR_ULTRASPARC3 \
+ ? 8 : 3))
/* Control the assembler format that we output. */
@@ -2780,17 +2755,11 @@ do { \
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. */
@@ -2872,6 +2841,13 @@ do { \
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))
@@ -2920,11 +2896,6 @@ do { \
#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) \
- sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
-
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
@@ -3017,6 +2988,7 @@ do { \
#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}}, \
@@ -3065,4 +3037,3 @@ do { \
#define JMP_BUF_SIZE 12
#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic)
-
OpenPOWER on IntegriCloud