X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fsparc%2Fsparc.h;h=61e6f94fffa62467e90aca47b1cc7ca9396c2c14;hb=4d4528537d643a94dfff61b20803871fe127131f;hp=9e49eadb02daa6031c47ed24d48878c0d1f4bd2f;hpb=e4acc5232405f5f8c274e88717308b711b7d760a;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 9e49eadb02d..61e6f94fffa 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for Sun SPARC. Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999 - 2000, 2001 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. @@ -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 @@ -210,19 +216,12 @@ Unrecognized value in TARGET_CPU_DEFAULT. #endif /* !SPARC_BI_ARCH */ -/* Names to predefine in the preprocessor for this target machine. - ??? It would be nice to not include any subtarget specific values here, - however there's no way to portably provide subtarget values to - CPP_PREFINES. Also, -D values in CPP_SUBTARGET_SPEC don't get turned into - foo, __foo and __foo__. */ - -#define CPP_PREDEFINES "-Dsparc -Dsun -Dunix -Asystem=unix -Asystem=bsd" - /* Define macros to distinguish architectures. */ /* Common CPP definitions used by CPP_SPEC amongst the various targets for handling -mcpu=xxx switches. */ #define CPP_CPU_SPEC "\ +%{msoft-float:-D_SOFT_FLOAT} \ %{mcypress:} \ %{msparclite:-D__sparclite__} \ %{mf930:-D__sparclite__} %{mf934:-D__sparclite__} \ @@ -237,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)}}}}}}} \ " @@ -246,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) @@ -303,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)}}}}}}} \ " @@ -333,16 +323,10 @@ Unrecognized value in TARGET_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 LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}" - -/* Provide required defaults for linker -e and -d switches. */ - -#define LINK_SPEC \ - "%{!shared:%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp} %{static:-Bstatic} \ - %{assert*} %{shared:%{!mimpure-text:-assert pure-text}}" +#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 @@ -373,59 +357,27 @@ Unrecognized value in TARGET_CPU_DEFAULT. 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" + -#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_block_flag || profile_arc_flag) \ - { \ - if (flag_pic) \ - { \ - const char *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 - -/* These compiler options take an argument. We ignore -target for now. */ - -#define WORD_SWITCH_TAKES_ARG(STR) \ - (DEFAULT_WORD_SWITCH_TAKES_ARG (STR) \ - || !strcmp (STR, "target") || !strcmp (STR, "assert")) - -/* Print subsidiary information on the compiler version in use. */ - -#define TARGET_VERSION fprintf (stderr, " (sparc)"); +#define OVERRIDE_OPTIONS sparc_override_options () /* Generate DBX debugging information. */ -#define DBX_DEBUGGING_INFO +#define DBX_DEBUGGING_INFO 1 /* Run-time compilation parameters selecting different hardware subsets. */ @@ -435,11 +387,6 @@ extern int target_flags; #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. */ @@ -466,7 +413,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 @@ -478,7 +425,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) @@ -489,7 +436,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 @@ -501,7 +448,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. */ @@ -522,25 +469,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. */ @@ -563,7 +510,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. @@ -583,10 +530,6 @@ extern int target_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, \ @@ -619,15 +562,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") }, \ @@ -655,7 +598,7 @@ extern int target_flags; /* 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 @@ -675,7 +618,8 @@ enum processor_type { PROCESSOR_SPARCLET, PROCESSOR_TSC701, PROCESSOR_V9, - PROCESSOR_ULTRASPARC + PROCESSOR_ULTRASPARC, + PROCESSOR_ULTRASPARC3 }; /* This is set from -m{cpu,tune}=xxx. */ @@ -685,31 +629,14 @@ extern enum processor_type sparc_cpu; Every file includes us, but not every file includes insn-attr.h. */ #define sparc_cpu_attr ((enum attr_cpu) sparc_cpu) -/* This macro is similar to `TARGET_SWITCHES' but defines names of - command options that have values. Its definition is an - initializer with a subgrouping for each command option. - - Each subgrouping contains a string constant, that defines the - fixed part of the option name, and the address of a variable. - The variable, type `char *', is set to the variable part of the - given option if the fixed part matches. The actual option name - is made by appending `-m' to the specified name. - - Here is an example which defines `-mshort-data-NUMBER'. If the - given option is `-mshort-data-512', the variable `m88k_short_data' - will be set to the string `"512"'. - - extern char *m88k_short_data; - #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ - #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 \ } @@ -720,19 +647,15 @@ extern enum processor_type sparc_cpu; struct sparc_cpu_select { const char *string; - const char *name; - int set_tune_p; - int set_arch_p; + const char *const name; + const int set_tune_p; + const int set_arch_p; }; 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 @@ -752,19 +675,15 @@ 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). */ #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. */ @@ -782,8 +701,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 @@ -854,7 +773,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. */ @@ -909,49 +828,6 @@ if (TARGET_ARCH64 \ #ifndef SUNOS4_SHARED_LIBRARIES #define SUNOS4_SHARED_LIBRARIES 0 #endif - -/* This is defined differently for v9 in a cover file. */ -#define SELECT_SECTION(T,RELOC) \ -{ \ - if (TREE_CODE (T) == VAR_DECL) \ - { \ - if (TREE_READONLY (T) && ! TREE_SIDE_EFFECTS (T) \ - && DECL_INITIAL (T) \ - && (DECL_INITIAL (T) == error_mark_node \ - || TREE_CONSTANT (DECL_INITIAL (T))) \ - && DECL_ALIGN (T) <= MAX_TEXT_ALIGN \ - && ! (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))) \ - text_section (); \ - else \ - data_section (); \ - } \ - else if (TREE_CODE (T) == CONSTRUCTOR) \ - { \ - if (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)) \ - data_section (); \ - } \ - else if (TREE_CODE_CLASS (TREE_CODE (T)) == 'c') \ - { \ - if ((TREE_CODE (T) == STRING_CST && flag_writable_strings) \ - || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN \ - || (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))) \ - data_section (); \ - else \ - text_section (); \ - } \ -} - -/* 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) \ -{ \ - 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. */ @@ -966,9 +842,10 @@ if (TARGET_ARCH64 \ accessible. We still account for them to simplify register computations (eg: in CLASS_MAX_NREGS). There are also 4 fp condition code registers, so 32+32+32+4 == 100. - Register 100 is used as the integer condition code register. */ + Register 100 is used as the integer condition code register. + Register 101 is used as the soft frame pointer register. */ -#define FIRST_PSEUDO_REGISTER 101 +#define FIRST_PSEUDO_REGISTER 102 #define SPARC_FIRST_FP_REG 32 /* Additional V9 fp regs. */ @@ -1034,7 +911,7 @@ if (TARGET_ARCH64 \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ \ - 0, 0, 0, 0, 0} + 0, 0, 0, 0, 0, 1} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -1059,7 +936,7 @@ if (TARGET_ARCH64 \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ \ - 1, 1, 1, 1, 1} + 1, 1, 1, 1, 1, 1} /* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that they won't be allocated. */ @@ -1067,13 +944,13 @@ if (TARGET_ARCH64 \ #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) \ @@ -1098,7 +975,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) \ @@ -1111,19 +988,16 @@ do \ 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[FRAME_POINTER_REGNUM] = "%i7"; \ + reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7"; \ /* Disable leaf functions */ \ memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); \ - } \ - if (profile_block_flag) \ - { \ - /* %g1 and %g2 (sparc32) resp. %g4 (sparc64) must be \ - fixed, because BLOCK_PROFILER uses them. */ \ - fixed_regs[1] = 1; \ - fixed_regs[TARGET_ARCH64 ? 4 : 2] = 1; \ + /* Make LEAF_REG_REMAP a noop. */ \ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ + leaf_reg_remap [regno] = regno; \ } \ } \ while (0) @@ -1141,30 +1015,24 @@ while (0) #define HARD_REGNO_NREGS(REGNO, MODE) \ (TARGET_ARCH64 \ - ? ((REGNO) < 32 \ - ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ - : (GET_MODE_SIZE (MODE) + 3) / 4) \ + ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \ + ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ + : (GET_MODE_SIZE (MODE) + 3) / 4) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) -/* A subreg in 64 bit mode will have the wrong offset for a floating point - register. The least significant part is at offset 1, compared to 0 for - integer registers. This only applies when FMODE is a larger mode. - We also need to handle a special case of TF-->DF conversions. */ -#define ALTER_HARD_SUBREG(TMODE, WORD, FMODE, REGNO) \ - (TARGET_ARCH64 \ - && (REGNO) >= SPARC_FIRST_FP_REG \ - && (REGNO) <= SPARC_LAST_V9_FP_REG \ - && (TMODE) == SImode \ - && !((FMODE) == QImode || (FMODE) == HImode) \ - ? ((REGNO) + 1) \ - : ((TMODE) == DFmode && (FMODE) == TFmode) \ - ? ((REGNO) + ((WORD) * 2)) \ - : ((REGNO) + (WORD))) +/* Due to the ARCH64 descrepancy above we must override this next + macro too. */ +#define REGMODE_NATURAL_SIZE(MODE) \ + ((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. See sparc.c for how we initialize this. */ -extern int *hard_regno_mode_classes; +extern const int *hard_regno_mode_classes; extern int sparc_mode_class[]; + +/* ??? Because of the funny way we pass parameters we should allow certain + ??? types of float/complex values to be in integer registers during + ??? RTL generation. This only matters on arch32. */ #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ((hard_regno_mode_classes[REGNO] & sparc_mode_class[MODE]) != 0) @@ -1192,27 +1060,32 @@ extern int sparc_mode_class[]; /* Register to use for pushing function arguments. */ #define STACK_POINTER_REGNUM 14 +/* The stack bias (amount by which the hardware register is offset by). */ +#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0) + /* Actual top-of-stack address is 92/176 greater than the contents of the stack pointer register for !v9/v9. That is: - !v9: 64 bytes for the in and local registers, 4 bytes for structure return address, and 6*4 bytes for the 6 register parameters. - v9: 128 bytes for the in and local registers + 6*8 bytes for the integer parameter regs. */ -#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0) - -/* The stack bias (amount by which the hardware register is offset by). */ -#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0) - -/* Is stack biased? */ -#define STACK_BIAS SPARC_STACK_BIAS +#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS) /* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 30 - -#if 0 -/* Register that is used for the return address for the flat model. */ -#define RETURN_ADDR_REGNUM 15 -#endif +#define HARD_FRAME_POINTER_REGNUM 30 + +/* The soft frame pointer does not have the stack bias applied. */ +#define FRAME_POINTER_REGNUM 101 + +/* Given the stack bias, the stack pointer isn't actually aligned. */ +#define INIT_EXPANDERS \ + do { \ + if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS) \ + { \ + REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT; \ + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \ + } \ + } while (0) /* Value should be nonzero if functions must have frame pointers. Zero means the frame pointer need not be set up (and parms @@ -1223,21 +1096,12 @@ extern int sparc_mode_class[]; Being a non-leaf function does not mean a frame pointer is needed in the flat window model. However, the debugger won't be able to backtrace through us with out it. */ -#define FRAME_POINTER_REQUIRED \ - (TARGET_FLAT ? (current_function_calls_alloca || current_function_varargs \ - || !leaf_function_p ()) \ +#define FRAME_POINTER_REQUIRED \ + (TARGET_FLAT \ + ? (current_function_calls_alloca \ + || !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 @@ -1248,7 +1112,7 @@ extern int sparc_mode_class[]; /* 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. @@ -1256,7 +1120,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. */ @@ -1349,7 +1213,7 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, #define N_REG_CLASSES (int) LIM_REG_CLASSES -/* Give names of register classes as strings for dump file. */ +/* Give names of register classes as strings for dump file. */ #define REG_CLASS_NAMES \ { "NO_REGS", "FPCC_REGS", "I64_REGS", "GENERAL_REGS", "FP_REGS", \ @@ -1360,32 +1224,53 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. */ -#define REG_CLASS_CONTENTS \ - {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \ - {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \ - {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}} +#define REG_CLASS_CONTENTS \ + {{0, 0, 0, 0}, /* NO_REGS */ \ + {0, 0, 0, 0xf}, /* FPCC_REGS */ \ + {0xffff, 0, 0, 0}, /* I64_REGS */ \ + {-1, 0, 0, 0x20}, /* GENERAL_REGS */ \ + {0, -1, 0, 0}, /* FP_REGS */ \ + {0, -1, -1, 0}, /* EXTRA_FP_REGS */ \ + {-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \ + {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \ + {-1, -1, -1, 0x3f}} /* ALL_REGS */ /* The same information, inverted: Return the class number of the smallest class containing reg number REGNO. This could be a conditional expression or could index an array. */ -extern enum reg_class sparc_regno_reg_class[]; +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 */ \ @@ -1393,31 +1278,49 @@ extern enum reg_class sparc_regno_reg_class[]; 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} + 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} - +{ 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[]; @@ -1438,7 +1341,7 @@ extern char leaf_reg_remap[]; .md file for v8 and v9. 'd' and 'b' are used for single and double precision VIS operations, if TARGET_VIS. - 'h' is used for V8+ 64 bit global and out registers. */ + 'h' is used for V8+ 64 bit global and out registers. */ #define REG_CLASS_FROM_LETTER(C) \ (TARGET_V9 \ @@ -1464,7 +1367,8 @@ extern char leaf_reg_remap[]; `J' is used for the range which is just zero (since that is R0). `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. */ + `M' is used for the range of constants supported by the movrcc insns. + `N' is like K, but for constants wider than 32 bits. */ #define SPARC_SIMM10_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x200 < 0x400) #define SPARC_SIMM11_P(X) ((unsigned HOST_WIDE_INT) (X) + 0x400 < 0x800) @@ -1473,17 +1377,21 @@ extern char leaf_reg_remap[]; SMALL_INT is used throughout the port so we continue to use it. */ #define SMALL_INT(X) (SPARC_SIMM13_P (INTVAL (X))) /* 13 bit immediate, considering only the low 32 bits */ -#define SMALL_INT32(X) (SPARC_SIMM13_P ((int)INTVAL (X) & 0xffffffff)) +#define SMALL_INT32(X) (SPARC_SIMM13_P (trunc_int_for_mode \ + (INTVAL (X), SImode))) #define SPARC_SETHI_P(X) \ -(((unsigned HOST_WIDE_INT) (X) & \ - (TARGET_ARCH64 ? ~(unsigned HOST_WIDE_INT) 0xfffffc00 : 0x3ff)) == 0) + (((unsigned HOST_WIDE_INT) (X) \ + & ((unsigned HOST_WIDE_INT) 0x3ff - GET_MODE_MASK (SImode) - 1)) == 0) +#define SPARC_SETHI32_P(X) \ + (SPARC_SETHI_P ((unsigned HOST_WIDE_INT) (X) & GET_MODE_MASK (SImode))) #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? SPARC_SIMM13_P (VALUE) \ : (C) == 'J' ? (VALUE) == 0 \ - : (C) == 'K' ? SPARC_SETHI_P (VALUE) \ + : (C) == 'K' ? SPARC_SETHI32_P (VALUE) \ : (C) == 'L' ? SPARC_SIMM11_P (VALUE) \ : (C) == 'M' ? SPARC_SIMM10_P (VALUE) \ + : (C) == 'N' ? SPARC_SETHI_P (VALUE) \ : 0) /* Similar, but for floating constants, and defining letters G and H. @@ -1509,6 +1417,8 @@ extern char leaf_reg_remap[]; #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 \ @@ -1525,7 +1435,10 @@ extern char leaf_reg_remap[]; 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) \ @@ -1534,30 +1447,38 @@ extern char leaf_reg_remap[]; || ((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)) @@ -1620,7 +1541,7 @@ extern char leaf_reg_remap[]; of the first local allocated. */ /* This allows space for one TFmode floating point value. */ #define STARTING_FRAME_OFFSET \ - (TARGET_ARCH64 ? (SPARC_STACK_BIAS - 16) \ + (TARGET_ARCH64 ? -16 \ : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT))) /* If we generate an insn to push BYTES bytes, @@ -1633,19 +1554,17 @@ extern char leaf_reg_remap[]; even if this function isn't going to use it. v9: This is 128 for the ins and locals. */ #define FIRST_PARM_OFFSET(FNDECL) \ - (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \ - : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD)) + (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD) /* Offset from the argument pointer register value to the CFA. This is different from FIRST_PARM_OFFSET because the register window comes between the CFA and the arguments. */ - -#define ARG_POINTER_CFA_OFFSET(FNDECL) SPARC_STACK_BIAS +#define ARG_POINTER_CFA_OFFSET(FNDECL) 0 /* When a parameter is passed in a register, stack space is still allocated for it. !v9: All 6 possible integer registers have backing store allocated. - v9: Only space for the arguments passed is allocated. */ + v9: Only space for the arguments passed is allocated. */ /* ??? Ideally, we'd use zero here (as the minimum), but zero has special meaning to the backend. Further, we need to be able to detect if a varargs/unprototyped function is called, as they may want to spill more @@ -1653,6 +1572,38 @@ extern char leaf_reg_remap[]; all 6 slots even for v9. */ #define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD) +/* 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} } + +/* 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) \ + 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 doesn't behave itself when the stack pointer moves within @@ -1688,7 +1639,7 @@ extern char leaf_reg_remap[]; ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \ : 8) -/* ??? FIXME -- seems wrong for v9 structure passing... */ +/* ??? FIXME -- seems wrong for v9 structure passing... */ #define BASE_INCOMING_ARG_REG(MODE) \ (TARGET_ARCH64 \ ? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \ @@ -1774,8 +1725,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 @@ -1783,8 +1734,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) \ +init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL)); /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. @@ -1861,29 +1812,22 @@ 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). */ #define ASM_DECLARE_RESULT(FILE, RESULT) \ fprintf ((FILE), "\t.proc\t0%lo\n", sparc_type_code (TREE_TYPE (RESULT))) -/* Output the label for a function definition. */ - -#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ -do { \ - ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ - ASM_OUTPUT_LABEL (FILE, NAME); \ -} while (0) - /* 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 @@ -1920,195 +1864,15 @@ do { \ } while (0) #endif -/* This macro generates the assembly code for function entry. - FILE is a stdio stream to output the code to. - SIZE is an int: how many units of temporary storage to allocate. - Refer to the array `regs_ever_live' to determine which registers - to save; `regs_ever_live[I]' is nonzero if register number I - is ever used in the function. This macro is responsible for - knowing which registers should not be saved even if used. */ - -/* On SPARC, move-double insns between fpu and cpu need an 8-byte block - of memory. If any fpu reg is used in the function, we allocate - such a block here, at the bottom of the frame, just in case it's needed. - - If this function is a leaf procedure, then we may choose not - to do a "save" insn. The decision about whether or not - to do this is made in regclass.c. */ - -#define FUNCTION_PROLOGUE(FILE, SIZE) \ - (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, (int)SIZE) \ - : output_function_prologue (FILE, (int)SIZE, \ - current_function_uses_only_leaf_regs)) -/* 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" - -/* The following macro shall output assembler code to FILE - to initialize basic-block profiling. */ - -#define FUNCTION_BLOCK_PROFILER(FILE, BLOCK_OR_LABEL) \ - sparc_function_block_profiler(FILE, BLOCK_OR_LABEL) - -/* The following macro shall output assembler code to FILE - to increment a counter associated with basic block number BLOCKNO. */ - -#define BLOCK_PROFILER(FILE, BLOCKNO) \ - sparc_block_profiler (FILE, BLOCKNO) - -/* The following macro shall output assembler code to FILE - to indicate a return from function during basic-block profiling. */ - -#define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \ - sparc_function_block_profiler_exit(FILE) - -#ifdef IN_LIBGCC2 - -/* The function `__bb_trace_func' is called in every basic block - and is not allowed to change the machine state. Saving (restoring) - the state can either be done in the BLOCK_PROFILER macro, - before calling function (rsp. after returning from function) - `__bb_trace_func', or it can be done inside the function by - defining the macros: - - MACHINE_STATE_SAVE(ID) - MACHINE_STATE_RESTORE(ID) - - In the latter case care must be taken, that the prologue code - of function `__bb_trace_func' does not already change the - state prior to saving it with MACHINE_STATE_SAVE. - - The parameter `ID' is a string identifying a unique macro use. - - On sparc it is sufficient to save the psw register to memory. - Unfortunately the psw register can be read in supervisor mode only, - so we read only the condition codes by using branch instructions - and hope that this is enough. - - On V9, life is much sweater: there is a user accessible %ccr - register, but we use it for 64bit libraries only. */ - -#if TARGET_ARCH32 - -#define MACHINE_STATE_SAVE(ID) \ - int ms_flags, ms_saveret; \ - asm volatile( \ - "mov %%g2,%1\n\ - mov %%g0,%0\n\ - be,a LFLGNZ"ID"\n\ - or %0,4,%0\n\ -LFLGNZ"ID":\n\ - bcs,a LFLGNC"ID"\n\ - or %0,1,%0\n\ -LFLGNC"ID":\n\ - bvs,a LFLGNV"ID"\n\ - or %0,2,%0\n\ -LFLGNV"ID":\n\ - bneg,a LFLGNN"ID"\n\ - or %0,8,%0\n\ -LFLGNN"ID":" \ - : "=r"(ms_flags), "=r"(ms_saveret)); - -#else - -#define MACHINE_STATE_SAVE(ID) \ - unsigned long ms_flags, ms_saveret; \ - asm volatile( \ - "mov %%g4,%1\n\ - rd %%ccr,%0" \ - : "=r"(ms_flags), "=r"(ms_saveret)); - -#endif - -/* On sparc MACHINE_STATE_RESTORE restores the psw register from memory. - The psw register can be written in supervisor mode only, - which is true even for simple condition codes. - We use some combination of instructions to produce the - proper condition codes, but some flag combinations can not - be generated in this way. If this happens an unimplemented - instruction will be executed to abort the program. */ - -#if TARGET_ARCH32 - -#define MACHINE_STATE_RESTORE(ID) \ -{ extern char flgtab[] __asm__("LFLGTAB"ID); \ - int scratch; \ - asm volatile ( \ - "jmpl %2+%1,%%g0\n\ - ! Do part of VC in the delay slot here, as it needs 3 insns.\n\ - addcc 2,%3,%%g0\n\ -LFLGTAB" ID ":\n\ - ! 0\n\ - ba LFLGRET"ID"\n\ - orcc 1,%%g0,%%g0\n\ - ! C\n\ - ba LFLGRET"ID"\n\ - addcc 2,%3,%%g0\n\ - ! V\n\ - unimp\n\ - nop\n\ - ! VC\n\ - ba LFLGRET"ID"\n\ - addxcc %4,%4,%0\n\ - ! Z\n\ - ba LFLGRET"ID"\n\ - subcc %%g0,%%g0,%%g0\n\ - ! ZC\n\ - ba LFLGRET"ID"\n\ - addcc 1,%3,%0\n\ - ! ZVC\n\ - ba LFLGRET"ID"\n\ - addcc %4,%4,%0\n\ - ! N\n\ - ba LFLGRET"ID"\n\ - orcc %%g0,-1,%%g0\n\ - ! NC\n\ - ba LFLGRET"ID"\n\ - addcc %%g0,%3,%%g0\n\ - ! NV\n\ - unimp\n\ - nop\n\ - ! NVC\n\ - unimp\n\ - nop\n\ - ! NZ\n\ - unimp\n\ - nop\n\ - ! NZC\n\ - unimp\n\ - nop\n\ - ! NZV\n\ - unimp\n\ - nop\n\ - ! NZVC\n\ - unimp\n\ - nop\n\ -LFLGRET"ID":\n\ - mov %5,%%g2" \ - : "=r"(scratch) \ - : "r"(ms_flags*8), "r"(flgtab), "r"(-1), \ - "r"(0x80000000), "r"(ms_saveret) \ - : "cc", "g2"); } - -#else - -#define MACHINE_STATE_RESTORE(ID) \ - asm volatile ( \ - "wr %0,0,%%ccr\n\ - mov %1,%%g4" \ - : : "r"(ms_flags), "r"(ms_saveret) \ - : "cc", "g4"); - -#endif - -#endif /* IN_LIBGCC2 */ /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in @@ -2119,21 +1883,6 @@ LFLGRET"ID":\n\ (get_frame_size () != 0 \ || current_function_calls_alloca || current_function_outgoing_args_size) -/* This macro generates the assembly code for function exit, - on machines that need it. If FUNCTION_EPILOGUE is not defined - then individual return instructions are generated for each - return statement. Args are same as for FUNCTION_PROLOGUE. - - The function epilogue should not depend on the current stack pointer! - It should use the frame pointer only. This is mandatory because - of alloca; we also take advantage of it to omit stack adjustments - before returning. */ - -#define FUNCTION_EPILOGUE(FILE, SIZE) \ - (TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)SIZE) \ - : output_function_epilogue (FILE, (int)SIZE, \ - current_function_uses_only_leaf_regs)) - #define DELAY_SLOTS_FOR_EPILOGUE \ (TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1) #define ELIGIBLE_FOR_EPILOGUE_DELAY(trial, slots_filled) \ @@ -2165,8 +1914,8 @@ LFLGRET"ID":\n\ #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) \ @@ -2185,10 +1934,6 @@ LFLGRET"ID":\n\ #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() \ @@ -2198,7 +1943,8 @@ LFLGRET"ID":\n\ 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 @@ -2207,7 +1953,7 @@ LFLGRET"ID":\n\ #define RETURN_ADDR_IN_PREVIOUS_FRAME /* This is the offset of the return address to the true next instruction to be - executed for the current function. */ + executed for the current function. */ #define RETURN_ADDR_OFFSET \ (8 + 4 * (! TARGET_ARCH64 && current_function_returns_struct)) @@ -2220,7 +1966,8 @@ LFLGRET"ID":\n\ ? 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. @@ -2239,14 +1986,47 @@ LFLGRET"ID":\n\ #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM) #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 1) /* %g1 */ #define EH_RETURN_HANDLER_RTX gen_rtx_REG (Pmode, 31) /* %i7 */ - -/* Addressing modes, and classification of registers for them. */ -/* #define HAVE_POST_INCREMENT 0 */ -/* #define HAVE_POST_DECREMENT 0 */ +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. + + 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. + + 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 -/* #define HAVE_PRE_DECREMENT 0 */ -/* #define HAVE_PRE_INCREMENT 0 */ +/* Emit a PC-relative relocation. */ +#define ASM_OUTPUT_DWARF_PCREL(FILE, SIZE, LABEL) \ + do { \ + fputs (integer_asm_op (SIZE, FALSE), FILE); \ + fprintf (FILE, "%%r_disp%d(", SIZE * 8); \ + assemble_name (FILE, LABEL); \ + fputc (')', FILE); \ + } while (0) +#endif + +/* Addressing modes, and classification of registers for them. */ /* Macros to check register numbers against specific register classes. */ @@ -2257,9 +2037,12 @@ LFLGRET"ID":\n\ has been allocated, which happens in local-alloc.c. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32 \ + || (REGNO) == FRAME_POINTER_REGNUM \ + || reg_renumber[REGNO] == FRAME_POINTER_REGNUM) + +#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO) + #define REGNO_OK_FOR_FP_P(REGNO) \ (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \ || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32))) @@ -2340,34 +2123,32 @@ LFLGRET"ID":\n\ 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 /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) + (REGNO (X) < 32 \ + || REGNO (X) == FRAME_POINTER_REGNUM \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) + /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) +#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. + 'W' is like 'T' but is assumed true on arch64. -/* 'T', 'U' are for aligned memory loads which aren't needed for 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 @@ -2376,16 +2157,8 @@ LFLGRET"ID":\n\ /* 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 @@ -2407,6 +2180,8 @@ LFLGRET"ID":\n\ 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 \ @@ -2421,7 +2196,7 @@ LFLGRET"ID":\n\ #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) @@ -2440,6 +2215,8 @@ LFLGRET"ID":\n\ && 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; \ @@ -2456,7 +2233,7 @@ LFLGRET"ID":\n\ of a movtf pattern are both MEMs with \ REG+REG address, then only one of them \ gets converted to an offsetable \ - address. */ \ + address. */ \ && (MODE != TFmode \ || (TARGET_FPU && TARGET_ARCH64 \ && TARGET_V9 \ @@ -2466,7 +2243,7 @@ LFLGRET"ID":\n\ because then mem_min_alignment is \ likely to be zero after reload and the \ forced split would lack a matching \ - splitter pattern. */ \ + splitter pattern. */ \ && (TARGET_ARCH64 || optimize \ || (MODE != DFmode \ && MODE != DImode))) \ @@ -2476,7 +2253,7 @@ LFLGRET"ID":\n\ else if (RTX_OK_FOR_BASE_P (op1)) \ { \ if ((RTX_OK_FOR_INDEX_P (op0) \ - /* See the previous comment. */ \ + /* See the previous comment. */ \ && (MODE != TFmode \ || (TARGET_FPU && TARGET_ARCH64 \ && TARGET_V9 \ @@ -2520,13 +2297,41 @@ LFLGRET"ID":\n\ && 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. */\ + 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)) \ 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. @@ -2575,8 +2380,8 @@ LFLGRET"ID":\n\ 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 @@ -2587,38 +2392,23 @@ do { \ /* Decompose SImode constants into hi+lo_sum. We do have to \ rerecognize what we produce, so be careful. */ \ if (CONSTANT_P (X) \ - && (MODE != TFmode || TARGET_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); \ - push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \ + push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ OPNUM, TYPE); \ goto WIN; \ } \ /* ??? 64-bit reloads. */ \ } 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. */ @@ -2629,7 +2419,7 @@ do { \ (! TARGET_PTR64 ? SImode : flag_pic ? SImode : TARGET_CM_MEDLOW ? SImode : DImode) #else /* If assembler does not have working .subsection -1, we use DImode for pic, as otherwise - we have to sign extend which slows things down. */ + we have to sign extend which slows things down. */ #define CASE_VECTOR_MODE \ (! TARGET_PTR64 ? SImode : flag_pic ? DImode : TARGET_CM_MEDLOW ? SImode : DImode) #endif @@ -2637,15 +2427,9 @@ do { \ /* Define as C expression which evaluates to nonzero if the tablejump instruction expects the table to contain offsets from the address of the table. - Do not define this if the table should contain absolute addresses. */ + Do not define this if the table should contain absolute addresses. */ /* #define CASE_VECTOR_PC_RELATIVE 1 */ -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - /* Define this as 1 if `char' should by default be signed; else as 0. */ #define DEFAULT_SIGNED_CHAR 1 @@ -2688,7 +2472,7 @@ do { \ #define PROMOTE_PROTOTYPES (TARGET_ARCH32) /* Define this to be nonzero if shift instructions ignore all but the low-order - few bits. */ + few bits. */ #define SHIFT_COUNT_TRUNCATED 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits @@ -2703,26 +2487,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 @@ -2730,8 +2494,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) @@ -2780,6 +2544,11 @@ do { \ #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 @@ -2796,7 +2565,7 @@ do { \ = init_one_libfunc (NEGTF2_LIBCALL); \ smul_optab->handlers[(int) TFmode].libfunc \ = init_one_libfunc (MULTF3_LIBCALL); \ - flodiv_optab->handlers[(int) TFmode].libfunc \ + 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); \ @@ -2816,6 +2585,17 @@ do { \ 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) @@ -2827,33 +2607,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) @@ -2861,67 +2614,36 @@ 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) - -/* 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; - -#define ISSUE_RATE sparc_issue_rate() - -/* Adjust the cost of dependencies. */ -#define ADJUST_COST(INSN,LINK,DEP,COST) \ - (COST) = sparc_adjust_cost(INSN, LINK, DEP, COST) - -#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \ - if (sparc_cpu == PROCESSOR_ULTRASPARC) \ - ultrasparc_sched_init (DUMP, SCHED_VERBOSE) - -#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \ -do { \ - if (sparc_cpu == PROCESSOR_ULTRASPARC) \ - ultrasparc_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY); \ - CIM = issue_rate; \ -} while (0) - -#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \ -do { \ - if (sparc_cpu == PROCESSOR_ULTRASPARC) \ - (CAN_ISSUE_MORE) = ultrasparc_variable_issue (INSN); \ - else \ - (CAN_ISSUE_MORE)--; \ -} while (0) - -/* 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)) /* Control the assembler format that we output. */ @@ -2947,21 +2669,9 @@ do { \ /* ??? Try to make the style consistent here (_OP?). */ -#define ASM_LONGLONG ".xword" -#define ASM_LONG ".word" -#define ASM_SHORT ".half" -#define ASM_BYTE_OP "\t.byte\t" #define ASM_FLOAT ".single" #define ASM_DOUBLE ".double" -#define ASM_LONGDOUBLE ".xxx" /* ??? Not known (or used yet). */ - -/* Output before read-only data. */ - -#define TEXT_SECTION_ASM_OP "\t.text" - -/* Output before writable data. */ - -#define DATA_SECTION_ASM_OP "\t.data" +#define ASM_LONGDOUBLE ".xxx" /* ??? Not known (or used yet). */ /* How to refer to registers in assembler output. This sequence is indexed by compiler's hard-register-number (see above). */ @@ -2979,19 +2689,13 @@ do { \ "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \ "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \ - "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"} + "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" } /* Define additional names for use in asm clobbers and asm declarations. */ #define ADDITIONAL_REGISTER_NAMES \ {{"ccr", SPARC_ICC_REG}, {"cc", SPARC_ICC_REG}} -/* How to renumber registers for dbx and gdb. In the flat model, the frame - pointer is really %i7. */ - -#define DBX_REGISTER_NUMBER(REGNO) \ - (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO) - /* On Sun 4, this limit is 2048. We use 1000 to be safe, since the length can run past this up to a continuation point. Once we used 1500, but a single entry in C++ can run more than 500 bytes, due to the length of @@ -3000,39 +2704,16 @@ do { \ guess... */ #define DBX_CONTIN_LENGTH 1000 -/* This is how to output a note to DBX telling it the line number - to which the following sequence of instructions corresponds. - - This is needed for SunOS 4.0, and should not hurt for 3.2 - versions either. */ -#define ASM_OUTPUT_SOURCE_LINE(file, line) \ - { static int sym_lineno = 1; \ - fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \ - line, sym_lineno, sym_lineno); \ - sym_lineno += 1; } - -/* 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. */ +/* 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. @@ -3041,81 +2722,6 @@ do { \ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf ((LABEL), "*%s%ld", (PREFIX), (long)(NUM)) -/* This is how to output an assembler line defining a `float' constant. - We always have to use a .long pseudo-op to do this because the native - SVR4 ELF assembler is buggy and it generates incorrect values when we - try to use the .float pseudo-op instead. */ - -#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ - { \ - long t; \ - char str[30]; \ - REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t%s\t0x%lx %s ~%s\n", ASM_LONG, t, \ - ASM_COMMENT_START, str); \ - } \ - -/* This is how to output an assembler line defining a `double' constant. - We always have to use a .long pseudo-op to do this because the native - SVR4 ELF assembler is buggy and it generates incorrect values when we - try to use the .float pseudo-op instead. */ - -#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ - { \ - long t[2]; \ - char str[30]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t%s\t0x%lx %s ~%s\n", ASM_LONG, t[0], \ - ASM_COMMENT_START, str); \ - fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t[1]); \ - } - -/* This is how to output an assembler line defining a `long double' - constant. */ - -#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ - { \ - long t[4]; \ - char str[30]; \ - REAL_VALUE_TO_TARGET_LONG_DOUBLE ((VALUE), t); \ - REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str); \ - fprintf (FILE, "\t%s\t0x%lx %s ~%s\n", ASM_LONG, t[0], \ - ASM_COMMENT_START, str); \ - fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t[1]); \ - fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t[2]); \ - fprintf (FILE, "\t%s\t0x%lx\n", ASM_LONG, t[3]); \ - } - -/* This is how to output an assembler line defining an `int' constant. */ - -#define ASM_OUTPUT_INT(FILE,VALUE) \ -( fprintf (FILE, "\t%s\t", ASM_LONG), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line defining a DImode constant. */ -#define ASM_OUTPUT_DOUBLE_INT(FILE,VALUE) \ - output_double_int (FILE, VALUE) - -/* Likewise for `char' and `short' constants. */ - -#define ASM_OUTPUT_SHORT(FILE,VALUE) \ -( fprintf (FILE, "\t%s\t", ASM_SHORT), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -#define ASM_OUTPUT_CHAR(FILE,VALUE) \ -( fprintf (FILE, "%s", ASM_BYTE_OP), \ - output_addr_const (FILE, (VALUE)), \ - fprintf (FILE, "\n")) - -/* This is how to output an assembler line for a numeric constant byte. */ - -#define ASM_OUTPUT_BYTE(FILE,VALUE) \ - fprintf (FILE, "%s0x%x\n", ASM_BYTE_OP, (VALUE)) - /* This is how we hook in and defer the case-vector until the end of the function. */ #define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \ @@ -3178,6 +2784,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)) @@ -3205,20 +2818,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. */ @@ -3226,42 +2828,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) \ -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 the parentheses used to group arithmetic operations - in assembler code. */ - -#define ASM_OPEN_PAREN "(" -#define ASM_CLOSE_PAREN ")" - -/* Define results of standard character escape sequences. */ -#define TARGET_BELL 007 -#define TARGET_BS 010 -#define TARGET_TAB 011 -#define TARGET_NEWLINE 012 -#define TARGET_VT 013 -#define TARGET_FF 014 -#define TARGET_CR 015 - #define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \ ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_') @@ -3354,9 +2920,12 @@ 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}}, \ {"fcc_reg_operand", {REG}}, \ +{"fcc0_reg_operand", {REG}}, \ {"icc_or_fcc_reg_operand", {REG}}, \ {"restore_operand", {REG}}, \ {"call_operand", {MEM}}, \ @@ -3374,6 +2943,7 @@ do { \ {"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}}, \ @@ -3399,7 +2969,3 @@ do { \ #define JMP_BUF_SIZE 12 #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (flag_pic) - -/* Defined in flags.h, but insn-emit.c does not include flags.h. */ - -extern int flag_pic;