X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi960%2Fi960.h;h=1ef3ba7291260f7ae2bde498b4987c724f4d0e7e;hb=5736198392201c503b0bd9f8ee86fb8073f19f45;hp=67656862af26292b41affe2adb1f74056de01a7f;hpb=77a5425ad0840ea6b165c2e1fbb74d831bed58fe;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h index 67656862af2..1ef3ba72912 100644 --- a/gcc/config/i960/i960.h +++ b/gcc/config/i960/i960.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for Intel 80960 - Copyright (C) 1992 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1995, 1996, 1998 Free Software Foundation, Inc. Contributed by Steven McGeady, Intel Corp. Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support. @@ -18,88 +18,89 @@ 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 -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Note that some other tm.h files may include this one and then override many of the definitions that relate to assembler syntax. */ /* Names to predefine in the preprocessor for this target machine. */ -#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960" +#define CPP_PREDEFINES "-Di960 -Di80960 -DI960 -DI80960 -Acpu(i960) -Amachine(i960)" /* Name to predefine in the preprocessor for processor variations. */ #define CPP_SPEC "%{mic*:-D__i960\ - %{mka:-D__i960KA}%{mkb:-D__i960KB}%{mkc:-D__i960KC}\ - %{msa:-D__i960SA}%{msb:-D__i960SB}%{msc:-D__i960SC}\ + %{mka:-D__i960KA}%{mkb:-D__i960KB}\ + %{mja:-D__i960JA}%{mjd:-D__i960JD}%{mjf:-D__i960JF}\ + %{mrp:-D__i960RP}\ + %{msa:-D__i960SA}%{msb:-D__i960SB}\ %{mmc:-D__i960MC}\ - %{mca:-D__i960CA}%{mcb:-D__i960CB}%{mcc:-D__i960CC}\ + %{mca:-D__i960CA}%{mcc:-D__i960CC}\ %{mcf:-D__i960CF}}\ %{mka:-D__i960KA__ -D__i960_KA__}\ %{mkb:-D__i960KB__ -D__i960_KB__}\ - %{mkc:-D__i960KC__ -D__i960_KC__}\ %{msa:-D__i960SA__ -D__i960_SA__}\ %{msb:-D__i960SB__ -D__i960_SB__}\ - %{msc:-D__i960SC__ -D__i960_SC__}\ %{mmc:-D__i960MC__ -D__i960_MC__}\ %{mca:-D__i960CA__ -D__i960_CA__}\ - %{mcb:-D__i960CB__ -D__i960_CB__}\ %{mcc:-D__i960CC__ -D__i960_CC__}\ %{mcf:-D__i960CF__ -D__i960_CF__}\ - %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\ - %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}}}}" + %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:\ + %{!mcc:%{!mcf:-D__i960_KB -D__i960KB__ %{mic*:-D__i960KB}}}}}}}}}" /* -mic* options make characters signed by default. */ -#define SIGNED_CHAR_SPEC \ - (DEFAULT_SIGNED_CHAR ? "%{funsigned-char:-D__CHAR_UNSIGNED__}" \ - : "%{!fsigned-char:%{!mic*:-D__CHAR_UNSIGNED__}}") +/* Use #if rather than ?: because MIPS C compiler rejects ?: in + initializers. */ +#if DEFAULT_SIGNED_CHAR +#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}" +#else +#define SIGNED_CHAR_SPEC "%{!fsigned-char:%{!mic*:-D__CHAR_UNSIGNED__}}" +#endif -/* Specs for the compiler, to handle processor variations. */ +/* Specs for the compiler, to handle processor variations. + If the user gives an explicit -gstabs or -gcoff option, then do not + try to add an implicit one, as this will fail. */ #define CC1_SPEC \ - "%{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\ - %{!mcc:%{!mcf:-mkb}}}}}}}}}}}\ - %{mbout:%{g*:-gstabs}}\ - %{mcoff:%{g*:-gcoff}}\ - %{!mbout:%{!mcoff:%{g*:-gstabs}}}" + "%{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-mka}}}}}}}}}}}}\ + %{!gs*:%{!gc*:%{mbout:%{g*:-gstabs}}\ + %{mcoff:%{g*:-gcoff}}\ + %{!mbout:%{!mcoff:%{g*:-gstabs}}}}}" /* Specs for the assembler, to handle processor variations. For compatibility with Intel's gnu960 tool chain, pass -A options to the assembler. */ #define ASM_SPEC \ - "%{mka:-AKA}%{mkb:-AKB}%{mkc:-AKC}%{msa:-ASA}%{msb:-ASB}\ - %{msc:-ASC}%{mmc:-AMC}%{mca:-ACA}%{mcb:-ACB}%{mcc:-ACC}%{mcf:-ACF}\ - %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\ - %{!mcc:%{!mcf:-AKB}}}}}}}}}}}" + "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\ + %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\ + %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX}\ + %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:%{!mja:%{!mjd:%{!mjf:%{!mrp:-AKB}}}}}}}}}}}}\ + %{mlink-relax:-linkrelax}" /* Specs for the linker, to handle processor variations. For compatibility with Intel's gnu960 tool chain, pass -F and -A options to the linker. */ #define LINK_SPEC \ - "%{mka:-AKA}%{mkb:-AKB}%{mkc:-AKC}%{msa:-ASA}%{msb:-ASB}\ - %{msc:-ASC}%{mmc:-AMC}%{mca:-ACA}%{mcb:-ACB}%{mcc:-ACC}%{mcf:-ACF}\ - %{!mka:%{!mkb:%{!mkc:%{!msa:%{!msb:%{!msc:%{!mmc:%{!mca:%{!mcb:\ - %{!mcc:%{!mcf:-AKB}}}}}}}}}}}\ - %{mbout:-Fbout}%{mcoff:-Fcoff}" + "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\ + %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\ + %{mja:-AJX}%{mjd:-AJX}%{mjf:-AJX}%{mrp:-AJX}\ + %{mbout:-Fbout}%{mcoff:-Fcoff}\ + %{mlink-relax:-relax}" /* Specs for the libraries to link with, to handle processor variations. Compatible with Intel's gnu960 tool chain. */ #define LIB_SPEC "%{!nostdlib:-lcg %{p:-lprof}%{pg:-lgprof}\ %{mka:-lfpg}%{msa:-lfpg}%{mca:-lfpg}%{mcf:-lfpg} -lgnu}" -/* These compiler options take an argument. */ -#define WORD_SWITCH_TAKES_ARG(STR) \ - (!strcmp (STR, "Tdata") || !strcmp (STR, "include") \ - || !strcmp (STR, "imacros") || !strcmp (STR, "Ttext")) +/* Show we can debug even without a frame pointer. */ +#define CAN_DEBUG_WITHOUT_FP -/* Omit frame pointer at -O2. Inline functions at -O3. */ -#define OPTIMIZATION_OPTIONS(LEVEL) \ +/* Do leaf procedure and tail call optimizations for -O2 and higher. */ +#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \ { \ if ((LEVEL) >= 2) \ { \ - flag_omit_frame_pointer = 1; \ target_flags |= TARGET_FLAG_LEAFPROC; \ target_flags |= TARGET_FLAG_TAILCALL; \ } \ - if ((LEVEL) >= 3) \ - flag_inline_functions = 1; \ } /* Print subsidiary information on the compiler version in use. */ @@ -110,12 +111,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Generate SDB style debugging information. */ #define SDB_DEBUGGING_INFO +#define EXTENDED_SDB_BASIC_TYPES /* Generate DBX_DEBUGGING_INFO by default. */ #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG -/* Redefine this to print in hex like iC960. */ -#define PUT_SDB_TYPE(A) fprintf (asm_out_file, "\t.type\t0x%x;", A) +/* Redefine this to print in hex. No value adjustment is necessary + anymore. */ +#define PUT_SDB_TYPE(A) \ + fprintf (asm_out_file, "\t.type\t0x%x;", A) + +/* Handle pragmas for compatibility with Intel's compilers. */ +#define HANDLE_PRAGMA(FILE, NODE) process_pragma (FILE, NODE) /* Run-time compilation parameters selecting different hardware subsets. */ @@ -129,7 +136,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define TARGET_PROTECTED (target_flags & TARGET_FLAG_PROTECTED) /* The following three are mainly used to provide a little sanity checking - against the -mARCH flags given. */ + against the -mARCH flags given. The Jx series, for the purposes of + gcc, is a Kx with a data cache. */ /* Nonzero if we should generate code for the KA and similar processors. No FPU, no microcode instructions. */ @@ -196,7 +204,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define TARGET_ASM_COMPAT (target_flags & TARGET_FLAG_ASM_COMPAT) /* For compatibility with the gcc960 v1.2 compiler. Use the old structure - alignement rules. Also, turns on STRICT_ALIGNMENT. */ + alignment rules. Also, turns on STRICT_ALIGNMENT. */ #define TARGET_FLAG_OLD_ALIGN 0x8000 #define TARGET_OLD_ALIGN (target_flags & TARGET_FLAG_OLD_ALIGN) @@ -215,22 +223,27 @@ extern int target_flags; { {"sa", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\ {"sb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \ TARGET_FLAG_COMPLEX_ADDR)},\ - {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ - TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\ +/* {"sc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ + TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \ {"ka", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\ {"kb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \ TARGET_FLAG_COMPLEX_ADDR)},\ - {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ - TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\ +/* {"kc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ + TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},*/ \ + {"ja", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\ + {"jd", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\ + {"jf", (TARGET_FLAG_NUMERICS|TARGET_FLAG_K_SERIES| \ + TARGET_FLAG_COMPLEX_ADDR)},\ + {"rp", (TARGET_FLAG_K_SERIES|TARGET_FLAG_COMPLEX_ADDR)},\ {"mc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ TARGET_FLAG_MC|TARGET_FLAG_COMPLEX_ADDR)},\ {"ca", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\ TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\ - {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES|\ +/* {"cb", (TARGET_FLAG_NUMERICS|TARGET_FLAG_C_SERIES|\ TARGET_FLAG_BRANCH_PREDICT|TARGET_FLAG_CODE_ALIGN)},\ {"cc", (TARGET_FLAG_NUMERICS|TARGET_FLAG_PROTECTED|\ TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\ - TARGET_FLAG_CODE_ALIGN)}, \ + TARGET_FLAG_CODE_ALIGN)}, */ \ {"cf", (TARGET_FLAG_C_SERIES|TARGET_FLAG_BRANCH_PREDICT|\ TARGET_FLAG_CODE_ALIGN|TARGET_FLAG_COMPLEX_ADDR)},\ {"numerics", (TARGET_FLAG_NUMERICS)}, \ @@ -252,10 +265,16 @@ extern int target_flags; {"intel-asm",TARGET_FLAG_ASM_COMPAT}, \ {"strict-align", TARGET_FLAG_STRICT_ALIGN}, \ {"no-strict-align", -(TARGET_FLAG_STRICT_ALIGN)}, \ - {"old-align", TARGET_FLAG_OLD_ALIGN}, \ - {"no-old-align", -(TARGET_FLAG_OLD_ALIGN)}, \ + {"old-align", (TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)}, \ + {"no-old-align", -(TARGET_FLAG_OLD_ALIGN|TARGET_FLAG_STRICT_ALIGN)}, \ + {"link-relax", 0}, \ + {"no-link-relax", 0}, \ + SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT}} +/* This are meant to be redefined in the host dependent files */ +#define SUBTARGET_SWITCHES + /* Override conflicting target switch options. Doesn't actually detect if more than one -mARCH option is given, but does handle the case of two blatantly conflicting -mARCH options. */ @@ -296,11 +315,15 @@ extern int target_flags; } /* Don't enable anything by default. The user is expected to supply a -mARCH - option. If none is given, then -mkb is added by CC1_SPEC. */ + option. If none is given, then -mka is added by CC1_SPEC. */ #define TARGET_DEFAULT 0 /* Target machine storage layout. */ +/* Define for cross-compilation from a host with a different float format + or endianness, as well as to support 80 bit long doubles on the i960. */ +#define REAL_ARITHMETIC + /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */ #define BITS_BIG_ENDIAN 0 @@ -314,7 +337,7 @@ extern int target_flags; numbered. */ #define WORDS_BIG_ENDIAN 0 -/* Number of bits in an addressible storage unit. */ +/* Number of bits in an addressable storage unit. */ #define BITS_PER_UNIT 8 /* Bitfields cannot cross word boundaries. */ @@ -365,17 +388,24 @@ extern int target_flags; /* Define this if move instructions will actually fail to work when given unaligned data. 80960 will work even with unaligned data, but it is slow. */ -#define STRICT_ALIGNMENT TARGET_OLD_ALIGN +#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN /* Specify alignment for string literals (which might be higher than the - base type's minimnal alignment requirement. This allows strings to be + base type's minimal alignment requirement. This allows strings to be aligned on word boundaries, and optimizes calls to the str* and mem* library functions. */ #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ - (i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP))) > (ALIGN) \ + (TREE_CODE (EXP) == STRING_CST \ + && i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP))) > (ALIGN) \ ? i960_object_bytes_bitalign (int_size_in_bytes (TREE_TYPE (EXP))) \ : (ALIGN)) +/* Make XFmode floating point quantities be 128 bit aligned. */ +#define DATA_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == ARRAY_TYPE \ + && TYPE_MODE (TREE_TYPE (TYPE)) == XFmode \ + && (ALIGN) < 128 ? 128 : (ALIGN)) + /* Macros to determine size of aggregates (structures and unions in C). Normally, these may be defined to simply return the maximum alignment and simple rounded-up size, but on some machines (like @@ -383,14 +413,16 @@ extern int target_flags; rounding method. */ #define ROUND_TYPE_ALIGN(TYPE, COMPUTED, SPECIFIED) \ - ((!TARGET_OLD_ALIGN && TREE_CODE (TYPE) == RECORD_TYPE) \ - ? i960_round_align ((SPECIFIED), TYPE_SIZE (TYPE)) \ - : MAX ((COMPUTED), (SPECIFIED))) - -#define ROUND_TYPE_SIZE(TYPE, SIZE, ALIGN) \ - ((!TARGET_OLD_ALIGN && TREE_CODE (TYPE) == RECORD_TYPE) \ - ? (tree) i960_round_size (SIZE) \ - : round_up ((SIZE), (ALIGN))) + ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode) \ + ? 128 /* Put 80 bit floating point elements on 128 bit boundaries. */ \ + : ((!TARGET_OLD_ALIGN && !TYPE_PACKED (TYPE) \ + && TREE_CODE (TYPE) == RECORD_TYPE) \ + ? i960_round_align (MAX ((COMPUTED), (SPECIFIED)), TYPE_SIZE (TYPE)) \ + : MAX ((COMPUTED), (SPECIFIED)))) + +#define ROUND_TYPE_SIZE(TYPE, COMPUTED, SPECIFIED) \ + ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode) \ + ? build_int_2 (128, 0) : round_up (COMPUTED, SPECIFIED)) /* Standard register usage. */ @@ -439,6 +471,9 @@ extern int target_flags; r1 is the stack pointer, r2 is the return instruction pointer, r3-r15 are always available, + r3 is clobbered by calls in functions that use the arg pointer + r4-r11 may be clobbered by the mcount call when profiling + r4-r15 if otherwise unused may be used for preserving global registers fp0..fp3 are never available. */ #define CALL_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 1, 1, \ @@ -470,7 +505,7 @@ extern int target_flags; /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. On 80960, the cpu registers can hold any mode but the float registers - can only hold SFmode, DFmode, or TFmode. */ + can only hold SFmode, DFmode, or XFmode. */ extern unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER]; #define HARD_REGNO_MODE_OK(REGNO, MODE) \ ((hard_regno_mode_ok[REGNO] & (1 << (int) (MODE))) != 0) @@ -503,13 +538,20 @@ extern unsigned int hard_regno_mode_ok[FIRST_PSEUDO_REGISTER]; Zero means the frame pointer need not be set up (and parms may be accessed via the stack pointer) in functions that seem suitable. This is computed in `reload', in reload1.c. */ +/* ??? It isn't clear to me why this is here. Perhaps because of a bug (since + fixed) in the definition of INITIAL_FRAME_POINTER_OFFSET which would have + caused this to fail. */ #define FRAME_POINTER_REQUIRED (! leaf_function_p ()) /* C statement to store the difference between the frame pointer - and the stack pointer values immediately after the function prologue. */ + and the stack pointer values immediately after the function prologue. + + Since the stack grows upward on the i960, this must be a negative number. + This includes the 64 byte hardware register save area and the size of + the frame. */ #define INITIAL_FRAME_POINTER_OFFSET(VAR) \ - do { (VAR) = compute_frame_size (get_frame_size ()); } while (0) + do { (VAR) = - (64 + compute_frame_size (get_frame_size ())); } while (0) /* Base register for access to arguments of the function. */ #define ARG_POINTER_REGNUM 14 @@ -623,19 +665,18 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS, #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? (((unsigned) (VALUE)) <= 31) \ : (C) == 'J' ? ((VALUE) == 0) \ - : (C) == 'K' ? ((VALUE) > -32 && (VALUE) <= 0) \ - : 0) + : (C) == 'K' ? ((VALUE) >= -31 && (VALUE) <= 0) \ + : (C) == 'M' ? ((VALUE) >= -32 && (VALUE) <= 0) \ + : 0) /* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. For the 80960, G is 0.0 and H is 1.0. */ -#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - ((TARGET_NUMERICS) && \ - (((C) == 'G' && ((VALUE) == CONST0_RTX (DFmode) \ - || (VALUE) == CONST0_RTX (SFmode))) \ - || ((C) == 'H' && ((VALUE) == CONST1_RTX (DFmode) \ - || (VALUE) == CONST1_RTX (SFmode))))) +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ + ((TARGET_NUMERICS) && \ + (((C) == 'G' && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \ + || ((C) == 'H' && ((VALUE) == CONST1_RTX (GET_MODE (VALUE)))))) /* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. @@ -709,10 +750,11 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS, /* Value is 1 if returning from a function call automatically pops the arguments described by the number-of-args field in the call. + FUNDECL is the declaration node of the function (as a tree), FUNTYPE is the data type of the function (as a tree), or for a library call it is an identifier node for the subroutine name. */ -#define RETURN_POPS_ARGS(FUNTYPE, SIZE) 0 +#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 /* Define how to find the value returned by a library function assuming the value has mode MODE. */ @@ -723,7 +765,7 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS, as seen by the caller. On 80960, returns are in g0..g3 */ -#define FUNCTION_VALUE_REGNO_P(N) ((N) < 4) +#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) /* 1 if N is a possible register number for function argument passing. On 80960, parameters are passed in g0..g11 */ @@ -766,7 +808,7 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; }; /* Define how to round to the next parameter boundary. This macro is used only in macro definitions below and/or i960.c. */ -#define ROUND(X, MULTIPLE_OF) \ +#define ROUND_PARM(X, MULTIPLE_OF) \ ((((X) + (MULTIPLE_OF) - 1) / (MULTIPLE_OF)) * MULTIPLE_OF) /* Initialize a variable CUM of type CUMULATIVE_ARGS @@ -775,7 +817,7 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; }; On 80960, the offset always starts at 0; the first parm reg is g0. */ -#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ ((CUM).ca_nregparms = 0, (CUM).ca_nstackparms = 0) /* Update the data in CUM to advance over an argument @@ -790,8 +832,13 @@ struct cum_args { int ca_nregparms; int ca_nstackparms; }; /* Indicate the alignment boundary for an argument of the specified mode and type. */ #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \ - ((TYPE) && TYPE_ALIGN (TYPE) > PARM_BOUNDARY ? TYPE_ALIGN (TYPE) \ - : PARM_BOUNDARY) + (((TYPE) != 0) \ + ? ((TYPE_ALIGN (TYPE) <= PARM_BOUNDARY) \ + ? PARM_BOUNDARY \ + : TYPE_ALIGN (TYPE)) \ + : ((GET_MODE_ALIGNMENT (MODE) <= PARM_BOUNDARY) \ + ? PARM_BOUNDARY \ + : GET_MODE_ALIGNMENT (MODE))) /* Determine where to put an argument to a function. Value is zero to push the argument on the stack, @@ -815,13 +862,18 @@ extern struct rtx_def *i960_function_arg (); If the precise function being called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0. */ -extern struct rtx_def *i960_function_value (); -#define FUNCTION_VALUE(TYPE, FUNC) i960_function_value (TYPE) +#define FUNCTION_VALUE(TYPE, FUNC) \ + gen_rtx (REG, TYPE_MODE (TYPE), 0) + +/* Force aggregates and objects larger than 16 bytes to be returned in memory, + since we only have 4 registers available for return values. */ -/* Force objects larger than 16 bytes to be returned in memory, since we - only have 4 registers available for return values. */ +#define RETURN_IN_MEMORY(TYPE) \ + (TYPE_MODE (TYPE) == BLKmode || int_size_in_bytes (TYPE) > 16) -#define RETURN_IN_MEMORY(TYPE) (int_size_in_bytes (TYPE) > 16) +/* Don't default to pcc-struct-return, because we have already specified + exactly how to return structures in the RETURN_IN_MEMORY macro. */ +#define DEFAULT_PCC_STRUCT_RETURN 0 /* For an arg passed partly in registers and partly in memory, this is the number of registers used. @@ -848,8 +900,8 @@ extern struct rtx_def *i960_function_value (); /* Output assembler code to FILE to increment profiler label # LABELNO for profiling a function entry. */ -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tlda LP%d,g0\n\tbal mcount\n", (LABELNO)) +#define FUNCTION_PROFILER(FILE, LABELNO) \ + output_function_profiler ((FILE), (LABELNO)); /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in @@ -907,16 +959,21 @@ extern struct rtx_def *i960_function_value (); /* Maximum number of registers that can appear in a valid memory address. */ #define MAX_REGS_PER_ADDRESS 2 -#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X) +#define CONSTANT_ADDRESS_P(X) \ + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ + || GET_CODE (X) == HIGH) /* LEGITIMATE_CONSTANT_P is nonzero if the constant value X is a legitimate general operand. It is given that X satisfies CONSTANT_P. - Anything but a CONST_DOUBLE can be made to work, excepting 0.0 and 1.0. */ + Anything but a CONST_DOUBLE can be made to work, excepting 0.0 and 1.0. + + ??? This probably should be defined to 1. */ #define LEGITIMATE_CONSTANT_P(X) \ - ((GET_CODE (X) != CONST_DOUBLE) || fp_literal ((X), VOIDmode)) + ((GET_CODE (X) != CONST_DOUBLE) || fp_literal ((X), GET_MODE (X))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. @@ -1000,7 +1057,7 @@ extern struct rtx_def *i960_function_value (); It is always safe for this macro to do nothing. It exists to recognize opportunities to optimize the output. */ -/* On 80960, convert non-cannonical addresses to canonical form. */ +/* On 80960, convert non-canonical addresses to canonical form. */ extern struct rtx_def *legitimize_address (); #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ @@ -1019,10 +1076,11 @@ extern struct rtx_def *legitimize_address (); for the index in the tablejump instruction. */ #define CASE_VECTOR_MODE SImode -/* Define this 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. */ -/* #define CASE_VECTOR_PC_RELATIVE */ +/* 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. */ +/* #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 @@ -1040,9 +1098,15 @@ extern struct rtx_def *legitimize_address (); in one reasonably fast instruction. */ #define MOVE_MAX 16 -/* Define if normal loads of shorter-than-word items from memory clears - the rest of the bigs in the register. */ -#define BYTE_LOADS_ZERO_EXTEND +/* Define if operations between registers always perform the operation + on the full register even if a narrower mode is specified. */ +#define WORD_REGISTER_OPERATIONS + +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD + will either zero-extend or sign-extend. The value of this macro should + be the code that says which one of the two operations is implicitly + done, NIL if none. */ +#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND /* Nonzero if access to memory by bytes is no faster than for words. Defining this results in worse code on the i960. */ @@ -1054,10 +1118,9 @@ extern struct rtx_def *legitimize_address (); #define STORE_FLAG_VALUE 1 -/* Define if shifts truncate the shift count - which implies one can omit a sign-extension or zero-extension - of a shift count. */ -#define SHIFT_COUNT_TRUNCATED +/* Define this to be nonzero if shift instructions ignore all but the low-order + few bits. */ +#define SHIFT_COUNT_TRUNCATED 0 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ @@ -1094,7 +1157,7 @@ extern struct rtx_def *gen_compare_reg (); should be used. CC_NOOVmode should be used when the first operand is a PLUS, MINUS, or NEG. CCmode should be used when no special processing is needed. */ -#define SELECT_CC_MODE(OP,X) select_cc_mode (OP, X) +#define SELECT_CC_MODE(OP,X,Y) select_cc_mode (OP, X) /* A function address in a call instruction is a byte address (for indexing purposes) so give the MEM rtx a byte's mode. */ @@ -1214,10 +1277,9 @@ extern struct rtx_def *gen_compare_reg (); assemble_name (FILE, NAME); \ fputs ("\n", FILE); } -/* This is how to output a reference to a user-level label named NAME. - `assemble_name' uses this. */ +/* The prefix to add to user-visible assembler symbols. */ -#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME) +#define USER_LABEL_PREFIX "_" /* This is how to output an internal numbered label where PREFIX is the class of label and NUM is the number within the class. */ @@ -1233,6 +1295,11 @@ extern struct rtx_def *gen_compare_reg (); #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ sprintf (LABEL, "*%s%d", PREFIX, NUM) +/* This is how to output an assembler line defining a `long double' + constant. */ + +#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) i960_output_long_double(FILE, VALUE) + /* This is how to output an assembler line defining a `double' constant. */ #define ASM_OUTPUT_DOUBLE(FILE,VALUE) i960_output_double(FILE, VALUE) @@ -1308,7 +1375,7 @@ extern struct rtx_def *gen_compare_reg (); assemble_name ((FILE), (NAME)), \ fputs ("\n.comm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ - fprintf ((FILE), ",%d\n", (ROUNDED)); \ + fprintf ((FILE), ",%d\n", (SIZE)); \ } \ } @@ -1320,10 +1387,20 @@ extern struct rtx_def *gen_compare_reg (); ( fputs (".bss\t", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%d,%d\n", (SIZE), \ - ((ALIGN) <= 8 ? 0 \ - : ((ALIGN) <= 16 ? 1 \ - : ((ALIGN) <= 32 ? 2 \ - : ((ALIGN <= 64 ? 3 : 4))))))) + (floor_log2 ((ALIGN) / BITS_PER_UNIT)))) + +/* A C statement (sans semicolon) to output to the stdio stream + FILE the assembler definition of uninitialized global DECL named + NAME whose size is SIZE bytes and alignment is ALIGN bytes. + Try to use asm_output_aligned_bss to implement this macro. */ + +#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) /* Output text for an #ident directive. */ #define ASM_OUTPUT_IDENT(FILE, STR) fprintf(FILE, "\t# %s\n", STR); @@ -1421,7 +1498,7 @@ extern struct rtx_def *gen_compare_reg (); } #if 0 -/* Promote char and short arguments to ints, when want compitibility with +/* Promote char and short arguments to ints, when want compatibility with the iC960 compilers. */ /* ??? In order for this to work, all users would need to be changed @@ -1450,6 +1527,7 @@ extern enum insn_types i960_last_insn_type; {"fpmove_src_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \ LABEL_REF, SUBREG, REG, MEM}}, \ {"arith_operand", {SUBREG, REG, CONST_INT}}, \ + {"logic_operand", {SUBREG, REG, CONST_INT}}, \ {"fp_arith_operand", {SUBREG, REG, CONST_DOUBLE}}, \ {"signed_arith_operand", {SUBREG, REG, CONST_INT}}, \ {"literal", {CONST_INT}}, \ @@ -1461,10 +1539,37 @@ extern enum insn_types i960_last_insn_type; {"eq_or_neq", {EQ, NE}}, \ {"arith32_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST_INT, \ CONST_DOUBLE, CONST}}, \ - {"power2_operand", {CONST_INT}}, + {"power2_operand", {CONST_INT}}, \ + {"cmplpower2_operand", {CONST_INT}}, /* Define functions in i960.c and used in insn-output.c. */ extern char *i960_output_ldconst (); extern char *i960_output_call_insn (); extern char *i960_output_ret_insn (); +extern char *i960_output_move_double (); +extern char *i960_output_move_quad (); + +/* Defined in reload.c, and used in insn-recog.c. */ + +extern int rtx_equal_function_value_matters; + +/* 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 d = (DELTA); \ + if (d < 0 && d > -32) \ + fprintf (FILE, "\tsubo %d,g0,g0\n", -d); \ + else if (d > 0 && d < 32) \ + fprintf (FILE, "\taddo %d,g0,g0\n", d); \ + else \ + { \ + fprintf (FILE, "\tldconst %d,r5\n", d); \ + fprintf (FILE, "\taddo r5,g0,g0\n"); \ + } \ + fprintf (FILE, "\tbx "); \ + assemble_name \ + (FILE, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (FUNCTION))); \ + fprintf (FILE, "\n"); \ +} while (0);