--- gcc/config/i960/i960.h 2018/04/24 18:10:26 1.1.1.1 +++ gcc/config/i960/i960.h 2018/04/24 18:30:27 1.1.1.4 @@ -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 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,13 +18,14 @@ GNU General Public License for more deta 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\ @@ -45,16 +46,22 @@ the Free Software Foundation, 675 Mass A %{!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:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:-mkb}}}}}}}}\ - %{mbout:%{g*:-gstabs}}\ - %{mcoff:%{g*:-gcoff}}\ - %{!mbout:%{!mcoff:%{g*:-gstabs}}}" + %{!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 @@ -63,7 +70,7 @@ the Free Software Foundation, 675 Mass A "%{mka:-AKA}%{mkb:-AKB}%{msa:-ASA}%{msb:-ASB}\ %{mmc:-AMC}%{mca:-ACA}%{mcc:-ACC}%{mcf:-ACF}\ %{!mka:%{!mkb:%{!msa:%{!msb:%{!mmc:%{!mca:%{!mcc:%{!mcf:-AKB}}}}}}}}\ - %{mlink-relax:-link-relax}" + %{mlink-relax:-linkrelax}" /* Specs for the linker, to handle processor variations. For compatibility with Intel's gnu960 tool chain, pass -F and -A options @@ -80,12 +87,14 @@ the Free Software Foundation, 675 Mass A #define LIB_SPEC "%{!nostdlib:-lcg %{p:-lprof}%{pg:-lgprof}\ %{mka:-lfpg}%{msa:-lfpg}%{mca:-lfpg}%{mcf:-lfpg} -lgnu}" -/* Omit frame pointer at -O2. Inline functions at -O3. */ +/* Show we can debug even without a frame pointer. */ +#define CAN_DEBUG_WITHOUT_FP + +/* Do leaf procedure and tail call optimizations for -O2 and higher. */ #define OPTIMIZATION_OPTIONS(LEVEL) \ { \ if ((LEVEL) >= 2) \ { \ - flag_omit_frame_pointer = 1; \ target_flags |= TARGET_FLAG_LEAFPROC; \ target_flags |= TARGET_FLAG_TAILCALL; \ } \ @@ -103,8 +112,14 @@ the Free Software Foundation, 675 Mass A /* 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 and adjust values like GNU960. The extra + bit is used to handle the type long double. Gcc does not support long + double in sdb output, but we do support the non-standard format. */ +#define PUT_SDB_TYPE(A) \ + fprintf (asm_out_file, "\t.type\t0x%x;", (A & 0xf) + 2 * (A & ~0xf)) + +/* Handle pragmas for compatibility with Intel's compilers. */ +#define HANDLE_PRAGMA(FILE) process_pragma (FILE) /* Run-time compilation parameters selecting different hardware subsets. */ @@ -241,8 +256,8 @@ 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}, \ { "", TARGET_DEFAULT}} @@ -292,6 +307,10 @@ extern int target_flags; /* 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 @@ -356,7 +375,7 @@ 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 minimal alignment requirement. This allows strings to be @@ -368,6 +387,12 @@ extern int target_flags; ? 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 @@ -375,14 +400,15 @@ 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 && 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) : (COMPUTED)) /* Standard register usage. */ @@ -465,7 +491,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) @@ -498,13 +524,20 @@ extern unsigned int hard_regno_mode_ok[F 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 @@ -625,12 +658,10 @@ enum reg_class { NO_REGS, GLOBAL_REGS, L 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. @@ -704,10 +735,11 @@ enum reg_class { NO_REGS, GLOBAL_REGS, L /* 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. */ @@ -921,10 +953,12 @@ extern struct rtx_def *i960_function_arg 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. @@ -1048,9 +1082,15 @@ extern struct rtx_def *legitimize_addres 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. */ @@ -1062,10 +1102,9 @@ extern struct rtx_def *legitimize_addres #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 1 /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits is done just by pretending it is already truncated. */ @@ -1241,6 +1280,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) @@ -1316,7 +1360,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)); \ } \ } @@ -1469,7 +1513,8 @@ extern enum insn_types i960_last_insn_ty {"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. */