diff options
Diffstat (limited to 'contrib/gcc/config/sparc/sparc.h')
-rw-r--r-- | contrib/gcc/config/sparc/sparc.h | 525 |
1 files changed, 158 insertions, 367 deletions
diff --git a/contrib/gcc/config/sparc/sparc.h b/contrib/gcc/config/sparc/sparc.h index 7c6a7fd..3202359 100644 --- a/contrib/gcc/config/sparc/sparc.h +++ b/contrib/gcc/config/sparc/sparc.h @@ -1,30 +1,50 @@ /* 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, 2004 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com). - 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, + 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, at Cygnus Support. -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to +along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Note that some other tm.h files include this one and then override whatever definitions are necessary. */ +/* Target CPU builtins. FIXME: Defining sparc is for the benefit of + Solaris only; otherwise just define __sparc__. Sadly the headers + are such a mess there is no Solaris-specific header. */ +#define TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("sparc"); \ + if (TARGET_64BIT) \ + { \ + builtin_assert ("cpu=sparc64"); \ + builtin_assert ("machine=sparc64"); \ + } \ + else \ + { \ + builtin_assert ("cpu=sparc"); \ + builtin_assert ("machine=sparc"); \ + } \ + } \ + while (0) + /* Specify this in a cover file to provide bi-architecture (32/64) support. */ /* #define SPARC_BI_ARCH */ @@ -49,35 +69,41 @@ Boston, MA 02111-1307, USA. */ #endif /* IN_LIBGCC2 */ #define TARGET_ARCH64 (! TARGET_ARCH32) -/* Code model selection. - -mcmodel is used to select the v9 code model. - Different code models aren't supported for v7/8 code. - - TARGET_CM_32: 32 bit address space, top 32 bits = 0, - pointers are 32 bits. Note that this isn't intended - to imply a v7/8 abi. - - TARGET_CM_MEDLOW: 32 bit address space, top 32 bits = 0, - avoid generating %uhi and %ulo terms, - pointers are 64 bits. - - TARGET_CM_MEDMID: 64 bit address space. - The executable must be in the low 16 TB of memory. - This corresponds to the low 44 bits, and the %[hml]44 - relocs are used. The text segment has a maximum size - of 31 bits. - - TARGET_CM_MEDANY: 64 bit address space. - The text and data segments have a maximum size of 31 - bits and may be located anywhere. The maximum offset - from any instruction to the label _GLOBAL_OFFSET_TABLE_ - is 31 bits. - - TARGET_CM_EMBMEDANY: 64 bit address space. - The text and data segments have a maximum size of 31 bits - and may be located anywhere. Register %g4 contains - the start address of the data segment. -*/ +/* Code model selection in 64-bit environment. + + The machine mode used for addresses is 32-bit wide: + + TARGET_CM_32: 32-bit address space. + It is the code model used when generating 32-bit code. + + The machine mode used for addresses is 64-bit wide: + + TARGET_CM_MEDLOW: 32-bit address space. + The executable must be in the low 32 bits of memory. + This avoids generating %uhi and %ulo terms. Programs + can be statically or dynamically linked. + + TARGET_CM_MEDMID: 44-bit address space. + The executable must be in the low 44 bits of memory, + and the %[hml]44 terms are used. The text and data + segments have a maximum size of 2GB (31-bit span). + The maximum offset from any instruction to the label + _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span). + + TARGET_CM_MEDANY: 64-bit address space. + The text and data segments have a maximum size of 2GB + (31-bit span) and may be located anywhere in memory. + The maximum offset from any instruction to the label + _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span). + + TARGET_CM_EMBMEDANY: 64-bit address space. + The text and data segments have a maximum size of 2GB + (31-bit span) and may be located anywhere in memory. + The global register %g4 contains the start address of + the data segment. Programs are statically linked and + PIC is not supported. + + Different code models are not supported in 32-bit environment. */ enum cmodel { CM_32, @@ -239,15 +265,8 @@ extern enum cmodel sparc_cmodel; %{mcpu=ultrasparc3:-D__sparc_v9__} \ %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ " - -/* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses - the right varags.h file when bootstrapping. */ -/* ??? It's not clear what value we want to use for -Acpu/machine for - sparc64 in 32 bit environments, so for now we only use `sparc64' in - 64 bit environments. */ - -#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc" -#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64" +#define CPP_ARCH32_SPEC "" +#define CPP_ARCH64_SPEC "-D__arch64__" #define CPP_ARCH_DEFAULT_SPEC \ (DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC) @@ -323,15 +342,17 @@ extern enum cmodel sparc_cmodel; /* 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|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. Each subgrouping contains a string constant, that defines the - specification name, and a string constant that used by the GNU CC driver + specification name, and a string constant that used by the GCC driver program. Do not define this macro if it does not need to do anything. */ @@ -630,17 +651,27 @@ extern enum processor_type sparc_cpu; #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 \ } /* This is meant to be redefined in target specific files. */ #define SUBTARGET_OPTIONS +/* Support for a compile-time default CPU, et cetera. The rules are: + --with-cpu is ignored if -mcpu is specified. + --with-tune is ignored if -mtune is specified. + --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu + are specified. */ +#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 { @@ -755,7 +786,13 @@ if (TARGET_ARCH64 \ #define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32) /* Boundary (in *bits*) on which stack pointer should be aligned. */ +/* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because + then sp+2047 is 128-bit aligned so sp is really only byte-aligned. */ #define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64) +/* Temporary hack until the FIXME above is fixed. This macro is used + only in pad_to_arg_alignment in function.c; see the comment there + for details about what it does. */ +#define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS) /* ALIGN FRAMES on double word boundaries */ @@ -1018,7 +1055,7 @@ while (0) : (GET_MODE_SIZE (MODE) + 3) / 4) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) -/* Due to the ARCH64 descrepancy above we must override this next +/* Due to the ARCH64 discrepancy above we must override this next macro too. */ #define REGMODE_NATURAL_SIZE(MODE) \ ((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD) @@ -1126,8 +1163,7 @@ extern int sparc_mode_class[]; #define RETURN_IN_MEMORY(TYPE) \ (TARGET_ARCH32 \ ? (TYPE_MODE (TYPE) == BLKmode \ - || TYPE_MODE (TYPE) == TFmode \ - || TYPE_MODE (TYPE) == TCmode) \ + || TYPE_MODE (TYPE) == TFmode) \ : (TYPE_MODE (TYPE) == BLKmode \ && (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 32)) @@ -1233,6 +1269,20 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \ {-1, -1, -1, 0x3f}} /* ALL_REGS */ +/* Defines invalid mode changes. Borrowed from pa64-regs.h. + + SImode loads to floating-point registers are not zero-extended. + The definition for LOAD_EXTEND_OP specifies that integer loads + narrower than BITS_PER_WORD will be zero-extended. As a result, + we inhibit changes from SImode unless they are to a mode that is + identical in size. */ + +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + (TARGET_ARCH64 \ + && (FROM) == SImode \ + && 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 @@ -1253,7 +1303,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; 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 + The register allocator is given the global and out registers first because these registers are call clobbered and thus less useful to global register allocation. @@ -1626,13 +1676,13 @@ extern char leaf_reg_remap[]; #define BASE_RETURN_VALUE_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ - : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8)) + : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32 : 8)) #define BASE_OUTGOING_VALUE_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ : TARGET_FLAT ? 8 : 24) \ - : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \ + : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32\ : (TARGET_FLAT ? 8 : 24))) #define BASE_PASSING_ARG_REG(MODE) \ @@ -1735,8 +1785,8 @@ 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, 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. @@ -1935,27 +1985,6 @@ do { \ #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. - - Also, on sparc 32-bit we cannot emit a sibling call when the - current function returns a structure. This is because the "unimp - after call" convention would cause the callee to return to the - wrong place. The generic code already disallows cases where the - function being called returns a structure. - - It may seem strange how this last case could occur. Usually there - is code after the call which jumps to epilogue code which dumps the - return value into the struct return area. That ought to invalidate - the sibling call right? Well, in the c++ case we can end up passing - the pointer to the struct return area to a constructor (which returns - void) and then nothing else happens. Such a sibling call would look - valid without the added check here. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) \ - (DECL \ - && ! TARGET_FLAT \ - && (TARGET_ARCH64 || ! current_function_returns_struct)) - /* Generate RTL to flush the register windows so as to make arbitrary frames available. */ #define SETUP_FRAME_ADDRESSES() \ @@ -2050,12 +2079,6 @@ do { \ /* 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. @@ -2101,27 +2124,18 @@ do { \ When PIC, we do not accept an address that would require a scratch reg to load into a register. */ -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ - || (GET_CODE (X) == CONST \ - && ! (flag_pic && pic_address_needs_scratch (X)))) +#define CONSTANT_ADDRESS_P(X) constant_address_p (X) /* Define this, so that when PIC, reload won't try to reload invalid addresses which require two reload registers. */ -#define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X)) +#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) \ - (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode || \ - (TARGET_VIS && \ - (GET_MODE (X) == SFmode || GET_MODE (X) == DFmode || \ - GET_MODE (X) == TFmode) && \ - fp_zero_operand (X, GET_MODE (X)))) +#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. @@ -2228,110 +2242,19 @@ do { \ #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 (RTX_OK_FOR_BASE_P (X)) \ +{ \ + if (legitimate_address_p (MODE, X, 1)) \ goto ADDR; \ - else if (GET_CODE (X) == PLUS) \ - { \ - register rtx op0 = XEXP (X, 0); \ - register rtx op1 = XEXP (X, 1); \ - if (flag_pic && op0 == pic_offset_table_rtx) \ - { \ - if (RTX_OK_FOR_BASE_P (op1)) \ - goto ADDR; \ - else if (flag_pic == 1 \ - && 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 (RTX_OK_FOR_BASE_P (op0)) \ - { \ - if ((RTX_OK_FOR_INDEX_P (op1) \ - /* We prohibit REG + REG for TFmode when \ - there are no instructions which accept \ - REG+REG instructions. We do this \ - because REG+REG is not an offsetable \ - address. If we get the situation \ - in reload where source and destination \ - of a movtf pattern are both MEMs with \ - REG+REG address, then only one of them \ - gets converted to an offsetable \ - address. */ \ - && (MODE != TFmode \ - || (TARGET_FPU && TARGET_ARCH64 \ - && TARGET_V9 \ - && TARGET_HARD_QUAD)) \ - /* We prohibit REG + REG on ARCH32 if \ - not optimizing for DFmode/DImode \ - because then mem_min_alignment is \ - likely to be zero after reload and the \ - forced split would lack a matching \ - splitter pattern. */ \ - && (TARGET_ARCH64 || optimize \ - || (MODE != DFmode \ - && MODE != DImode))) \ - || RTX_OK_FOR_OFFSET_P (op1)) \ - goto ADDR; \ - } \ - else if (RTX_OK_FOR_BASE_P (op1)) \ - { \ - if ((RTX_OK_FOR_INDEX_P (op0) \ - /* See the previous comment. */ \ - && (MODE != TFmode \ - || (TARGET_FPU && TARGET_ARCH64 \ - && TARGET_V9 \ - && TARGET_HARD_QUAD)) \ - && (TARGET_ARCH64 || optimize \ - || (MODE != DFmode \ - && MODE != DImode))) \ - || RTX_OK_FOR_OFFSET_P (op0)) \ - goto ADDR; \ - } \ - else if (USE_AS_OFFSETABLE_LO10 \ - && GET_CODE (op0) == LO_SUM \ - && TARGET_ARCH64 \ - && ! TARGET_CM_MEDMID \ - && RTX_OK_FOR_OLO10_P (op1)) \ - { \ - register rtx op00 = XEXP (op0, 0); \ - register rtx op01 = XEXP (op0, 1); \ - if (RTX_OK_FOR_BASE_P (op00) \ - && CONSTANT_P (op01)) \ - goto ADDR; \ - } \ - else if (USE_AS_OFFSETABLE_LO10 \ - && GET_CODE (op1) == LO_SUM \ - && TARGET_ARCH64 \ - && ! TARGET_CM_MEDMID \ - && RTX_OK_FOR_OLO10_P (op0)) \ - { \ - register rtx op10 = XEXP (op1, 0); \ - register rtx op11 = XEXP (op1, 1); \ - if (RTX_OK_FOR_BASE_P (op10) \ - && CONSTANT_P (op11)) \ - goto ADDR; \ - } \ - } \ - else if (GET_CODE (X) == LO_SUM) \ - { \ - register rtx op0 = XEXP (X, 0); \ - register rtx op1 = XEXP (X, 1); \ - if (RTX_OK_FOR_BASE_P (op0) \ - && CONSTANT_P (op1) \ - /* We can't allow TFmode, because an offset \ - greater than or equal to the alignment (8) \ - may cause the LO_SUM to overflow if !v9. */\ - && (MODE != TFmode || TARGET_V9)) \ - goto ADDR; \ - } \ - else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \ +} +#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. @@ -2376,33 +2299,11 @@ do { \ /* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ -{ rtx sparc_x = (X); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \ - force_operand (XEXP (X, 0), NULL_RTX)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - force_operand (XEXP (X, 1), NULL_RTX)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS) \ - (X) = gen_rtx_PLUS (Pmode, force_operand (XEXP (X, 0), NULL_RTX),\ - XEXP (X, 1)); \ - if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS) \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - force_operand (XEXP (X, 1), NULL_RTX)); \ - if (sparc_x != (X) && memory_address_p (MODE, X)) \ - goto WIN; \ - if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0); \ - else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \ - copy_to_mode_reg (Pmode, XEXP (X, 1))); \ - else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \ - (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \ - copy_to_mode_reg (Pmode, XEXP (X, 0))); \ - else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \ - || GET_CODE (X) == LABEL_REF) \ - (X) = copy_to_suggested_reg (X, NULL_RTX, Pmode); \ - if (memory_address_p (MODE, X)) \ - goto 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 @@ -2491,11 +2392,6 @@ do { \ and maybe make use of that. */ #define SLOW_BYTE_ACCESS 1 -/* We assume that the store-condition-codes instructions store 0 for false - and some other value for true. This is the value stored for true. */ - -#define STORE_FLAG_VALUE 1 - /* When a prototype says `char' or `short', really pass an `int'. */ #define PROMOTE_PROTOTYPES (TARGET_ARCH32) @@ -2507,9 +2403,7 @@ do { \ is done just by pretending it is already truncated. */ #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 -/* Specify the machine mode that pointers have. - After generation of rtl, the compiler makes no further distinction - between pointers and any other objects of this machine mode. */ +/* Specify the machine mode used for addresses. */ #define Pmode (TARGET_ARCH64 ? DImode : SImode) /* Generate calls to memcpy, memcmp and memset. */ @@ -2540,100 +2434,20 @@ do { \ /* alloca should avoid clobbering the old register save area. */ #define SETJMP_VIA_SAVE_AREA -/* Define subroutines to call to handle multiply and divide. - Use the subroutines that Sun's library provides. - The `*' prevents an underscore from being prepended by the compiler. */ - -#define DIVSI3_LIBCALL "*.div" -#define UDIVSI3_LIBCALL "*.udiv" -#define MODSI3_LIBCALL "*.rem" -#define UMODSI3_LIBCALL "*.urem" -/* .umul is a little faster than .mul. */ -#define MULSI3_LIBCALL "*.umul" - -/* Define library calls for quad FP operations. These are all part of the - SPARC 32bit ABI. */ -#define ADDTF3_LIBCALL "_Q_add" -#define SUBTF3_LIBCALL "_Q_sub" -#define NEGTF2_LIBCALL "_Q_neg" -#define MULTF3_LIBCALL "_Q_mul" -#define DIVTF3_LIBCALL "_Q_div" -#define FLOATSITF2_LIBCALL "_Q_itoq" -#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi" -#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou" -#define EXTENDSFTF2_LIBCALL "_Q_stoq" -#define TRUNCTFSF2_LIBCALL "_Q_qtos" -#define EXTENDDFTF2_LIBCALL "_Q_dtoq" -#define TRUNCTFDF2_LIBCALL "_Q_qtod" -#define EQTF2_LIBCALL "_Q_feq" -#define NETF2_LIBCALL "_Q_fne" -#define GTTF2_LIBCALL "_Q_fgt" -#define GETF2_LIBCALL "_Q_fge" -#define LTTF2_LIBCALL "_Q_flt" -#define LETF2_LIBCALL "_Q_fle" +/* The _Q_* comparison libcalls return booleans. */ +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode) /* 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 - for calls to the builtin function sqrt, but this fails. */ -#define INIT_TARGET_OPTABS \ - do { \ - if (TARGET_ARCH32) \ - { \ - add_optab->handlers[(int) TFmode].libfunc \ - = init_one_libfunc (ADDTF3_LIBCALL); \ - sub_optab->handlers[(int) TFmode].libfunc \ - = init_one_libfunc (SUBTF3_LIBCALL); \ - neg_optab->handlers[(int) TFmode].libfunc \ - = init_one_libfunc (NEGTF2_LIBCALL); \ - smul_optab->handlers[(int) TFmode].libfunc \ - = init_one_libfunc (MULTF3_LIBCALL); \ - sdiv_optab->handlers[(int) TFmode].libfunc \ - = init_one_libfunc (DIVTF3_LIBCALL); \ - eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \ - netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \ - gttf2_libfunc = init_one_libfunc (GTTF2_LIBCALL); \ - getf2_libfunc = init_one_libfunc (GETF2_LIBCALL); \ - lttf2_libfunc = init_one_libfunc (LTTF2_LIBCALL); \ - letf2_libfunc = init_one_libfunc (LETF2_LIBCALL); \ - trunctfsf2_libfunc = init_one_libfunc (TRUNCTFSF2_LIBCALL); \ - trunctfdf2_libfunc = init_one_libfunc (TRUNCTFDF2_LIBCALL); \ - extendsftf2_libfunc = init_one_libfunc (EXTENDSFTF2_LIBCALL); \ - extenddftf2_libfunc = init_one_libfunc (EXTENDDFTF2_LIBCALL); \ - floatsitf_libfunc = init_one_libfunc (FLOATSITF2_LIBCALL); \ - fixtfsi_libfunc = init_one_libfunc (FIX_TRUNCTFSI2_LIBCALL); \ - fixunstfsi_libfunc \ - = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL); \ - if (TARGET_FPU) \ - 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) - -/* This is meant to be redefined in the host dependent files */ -#define INIT_SUBTARGET_OPTABS +/* Assume by default that we do not have the Solaris-specific conversion + routines nor 64-bit integer multiply and divide routines. */ -/* Nonzero if a floating point comparison library call for - mode MODE that will return a boolean value. Zero if one - of the libgcc2 functions is used. */ -#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode) +#define SUN_CONVERSION_LIBFUNCS 0 +#define DITF_CONVERSION_LIBFUNCS 0 +#define SUN_INTEGER_MULTIPLY_64 0 /* Compute extra cost of moving data between one register class and another. */ @@ -2662,29 +2476,6 @@ do { \ : (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. */ - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - RTX_COSTS_CASES \ - return sparc_rtx_costs(X,CODE,OUTER_CODE); - -#define ADDRESS_COST(RTX) 1 - #define PREFETCH_BLOCK \ ((sparc_cpu == PROCESSOR_ULTRASPARC \ || sparc_cpu == PROCESSOR_ULTRASPARC3) \ @@ -2698,10 +2489,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE: /* Control the assembler format that we output. */ -/* Output at beginning of assembler file. */ - -#define ASM_FILE_START(file) - /* A C string constant describing how to begin a comment in the target assembler language. The compiler assumes that the comment will end at the end of the line. */ @@ -2765,12 +2552,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE: #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. @@ -2849,7 +2630,7 @@ do { \ fprintf (FILE, "\t.align %d,0x1000000\n", (1<<(LOG))) #define ASM_OUTPUT_SKIP(FILE,SIZE) \ - fprintf (FILE, "\t.skip %u\n", (SIZE)) + fprintf (FILE, "\t.skip "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)) /* This says how to output an assembler line to define a global common symbol. */ @@ -2857,7 +2638,7 @@ do { \ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ ( fputs ("\t.common ", (FILE)), \ assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u,\"bss\"\n", (SIZE))) + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\"\n", (SIZE))) /* This says how to output an assembler line to define a local common symbol. */ @@ -2865,7 +2646,7 @@ do { \ #define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \ ( fputs ("\t.reserve ", (FILE)), \ assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%u,\"bss\",%u\n", \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\",%u\n", \ (SIZE), ((ALIGNED) / BITS_PER_UNIT))) /* A C statement (sans semicolon) to output to the stdio stream @@ -2875,20 +2656,9 @@ do { \ #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. */ @@ -2896,8 +2666,16 @@ do { \ #define ASM_OUTPUT_IDENT(FILE, NAME) \ fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME); +/* Emit a dtp-relative reference to a TLS variable. */ + +#ifdef HAVE_AS_TLS +#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \ + sparc_output_dwarf_dtprel (FILE, SIZE, X) +#endif + #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ - ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_') + ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' \ + || (CHAR) == '(' || (CHAR) == '_' || (CHAR) == '&') /* Print operand X (an rtx) in assembler syntax to file FILE. CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. @@ -2984,6 +2762,14 @@ do { \ } \ } +#ifdef HAVE_AS_TLS +#define TARGET_TLS 1 +#else +#define TARGET_TLS 0 +#endif +#define TARGET_SUN_TLS TARGET_TLS +#define TARGET_GNU_TLS 0 + /* Define the codes that are matched by predicates in sparc.c. */ #define PREDICATE_CODES \ @@ -3030,8 +2816,13 @@ do { \ {"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \ {"clobbered_register", {REG}}, \ {"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \ +{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}}, \ {"const64_operand", {CONST_INT, CONST_DOUBLE}}, \ -{"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, +{"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, \ +{"tgd_symbolic_operand", {SYMBOL_REF}}, \ +{"tld_symbolic_operand", {SYMBOL_REF}}, \ +{"tie_symbolic_operand", {SYMBOL_REF}}, \ +{"tle_symbolic_operand", {SYMBOL_REF}}, /* The number of Pmode words for the setjmp buffer. */ #define JMP_BUF_SIZE 12 |