--- gcc/config/clipper/clipper.h 2018/04/24 18:10:23 1.1.1.1 +++ gcc/config/clipper/clipper.h 2018/04/24 18:27:50 1.1.1.4 @@ -1,6 +1,5 @@ /* Definitions of target machine for GNU compiler. Clipper version. - Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. - + Copyright (C) 1987, 88, 91, 93, 94, 1995 Free Software Foundation, Inc. Contributed by Holger Teutsch (holger@hotbso.rhein-main.de) This file is part of GNU CC. @@ -17,7 +16,8 @@ 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. */ extern struct rtx_def *clipper_builtin_saveregs (); extern int clipper_frame_size (); @@ -38,26 +38,22 @@ extern int target_flags; where VALUE is the bits to set or minus the bits to clear. An empty string NAME is used to identify the default VALUE. */ -#define TARGET_SWITCHES \ - { { "", TARGET_DEFAULT} } +#define TARGET_SWITCHES \ + { { "c400", 1 }, \ + { "c300", -1 }, \ + { "", TARGET_DEFAULT} } + +#define TARGET_C400 1 +#define TARGET_C300 0 /* Default target_flags if no switches specified. */ #ifndef TARGET_DEFAULT -#define TARGET_DEFAULT 0 +#define TARGET_DEFAULT TARGET_C300 #endif -/* Omit frame pointer at -O2. Inline functions at -O3. */ - -#define OPTIMIZATION_OPTIONS(LEVEL) \ -{ \ - if ((LEVEL) >= 2) \ - { \ - flag_omit_frame_pointer = 1; \ - } \ - if ((LEVEL) >= 3) \ - flag_inline_functions = 1; \ -} +/* Show that we can debug generated code without a frame pointer. */ +#define CAN_DEBUG_WITHOUT_FP /* Target machine storage layout */ @@ -132,7 +128,7 @@ extern int target_flags; /* Let's keep the stack somewhat aligned. */ #define STACK_BOUNDARY 64 -/* Define this macro if it is advisible to hold scalars in registers +/* Define this macro if it is advisable to hold scalars in registers in a wider mode than that declared by the program. In such cases, the value is constrained to be within the bounds of the declared type, but kept valid in the wider mode. The signedness of the @@ -175,7 +171,7 @@ extern int target_flags; On the clipper, these are the FP and SP . */ #define FIXED_REGISTERS \ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* FIXME: C300 only */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* Default: C300 */ /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -185,7 +181,17 @@ extern int target_flags; Aside from that, you can include as many other registers as you like. */ #define CALL_USED_REGISTERS \ {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,\ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* FIXME: C300 only */ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1} /* default: C300 */ + +/* Zero or more C statements that may conditionally modify two + variables `fixed_regs' and `call_used_regs' (both of type `char + []') after they have been initialized from the two preceding + macros. A C400 has additional floating registers f8 -> f15 */ + +#define CONDITIONAL_REGISTER_USAGE \ + if (target_flags & TARGET_C400) \ + { int i; \ + for (i = 24; i < 32; i++) fixed_regs[i] = call_used_regs[i] = 0; } /* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. @@ -197,15 +203,14 @@ extern int target_flags; ((REGNO) >= 16 ? 1 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) - /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. - On the clipper, 0-15 hold int, 16-31 hold float. DImode regs must be - even */ + On the clipper 0-15 may hold any mode but DImode and DFmode must be even. + Registers 16-31 hold SFmode and DFmode */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((GET_MODE_CLASS(MODE) == MODE_FLOAT) \ - ? (REGNO) >= 16 \ - : (REGNO) < 16 && ((MODE) !=DImode || ((REGNO) & 1) == 0)) +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO) < 16 \ + ? ((MODE) != DImode && (MODE) != DFmode || ((REGNO) & 1) == 0) \ + : ((MODE) == SFmode || (MODE) == DFmode)) /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. @@ -375,11 +380,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, /* Value is the number of bytes of arguments automatically popped when returning from a subroutine 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. SIZE is the number of bytes of arguments passed on the stack. */ -#define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0 +#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 /* Define how to find the value returned by a function. VALTYPE is the data type of the value (as a tree). @@ -409,9 +415,11 @@ enum reg_class { NO_REGS, GENERAL_REGS, ((N) == 0 || (N) == 1 || (N) == 16 || (N) == 17) /* Define this if PCC uses the nonreentrant convention for returning - structure and union values. */ + structure and union values. Old Green Hills C-Clipper returns static + structs but the newer Apogee compiler passes structs as hidden arg 0. + Structs etc are always passed in memory */ -#define PCC_STATIC_STRUCT_RETURN +/* #define PCC_STATIC_STRUCT_RETURN */ /* Define a data type for recording info about an argument list @@ -454,34 +462,46 @@ struct _clipper_cum_args { int num; int clipper passes the address of a struct in r0, set num = 1 in this case */ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ - ((CUM).num = ((FNTYPE) != 0 && aggregate_value_p (FNTYPE)), \ + ((CUM).num = ((FNTYPE) != 0 && aggregate_value_p (TREE_TYPE (FNTYPE))), \ (CUM).size = 0) /* internal helper : size of an argument */ #define CLIPPER_ARG_SIZE(MODE, TYPE) \ -((MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ - : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) +(((MODE) != BLKmode \ + ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \ + : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD) \ + * UNITS_PER_WORD) /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. (TYPE is null for libcalls where that information may not be available.) */ -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ -do \ -{ \ - if ((CUM).num == 0 && (MODE) == DImode) \ - (CUM).num = 2; \ - else \ - (CUM).num++; \ - if ((CUM).num > 2 || (MODE) == BLKmode) \ - { \ - int align = FUNCTION_ARG_BOUNDARY (MODE, TYPE) / BITS_PER_UNIT; \ - (CUM).size += align - 1; \ - (CUM).size &= align - 1; \ - (CUM).size += CLIPPER_ARG_SIZE (MODE, TYPE); \ - } \ +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ +do \ +{ \ + int reg = 0; \ + \ + if ((CUM).num < 2 \ + && (GET_MODE_CLASS(MODE)==MODE_INT || GET_MODE_CLASS(MODE)==MODE_FLOAT) \ + && (GET_MODE_SIZE (MODE) <= 8) \ + && ((TYPE) == NULL || !AGGREGATE_TYPE_P(TYPE)) \ + && ((MODE) != DImode || (CUM).num == 0)) \ + { \ + reg = 1; \ + if ((MODE) == DImode) \ + (CUM).num = 1; \ + } \ + \ + (CUM).num++; \ + \ + if (! reg) \ + { \ + int align = FUNCTION_ARG_BOUNDARY (MODE, TYPE) / BITS_PER_UNIT; \ + (CUM).size += align - 1; \ + (CUM).size &= ~(align - 1); \ + (CUM).size += CLIPPER_ARG_SIZE (MODE, TYPE); \ + } \ } while (0) /* Define where to put the arguments to a function. @@ -495,15 +515,21 @@ do \ CUM is a variable of type CUMULATIVE_ARGS which gives info about the preceding args and about the function being called. NAMED is nonzero if this argument is a named parameter - (otherwise it is an extra parameter matching an ellipsis). */ + (otherwise it is an extra parameter matching an ellipsis). -/* 2 args go into regs, float in f0/f1, anything else in r0/r1 */ - -#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - (((CUM).num >= 2 || (MODE) == BLKmode || \ - ((MODE) == DImode && (CUM).num)) ? 0 : \ - gen_rtx (REG, (MODE), \ - GET_MODE_CLASS(MODE) == MODE_FLOAT ? (CUM).num+16 : (CUM).num)) + 2 args may go into regs. These must be MODE_INT or MODE_FLOAT but only + if they really fit into ONE register. The exception is a DImode arg + that occupies both register slots. */ + +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + (((CUM).num < 2 \ + && (GET_MODE_CLASS(MODE)==MODE_INT || GET_MODE_CLASS(MODE)==MODE_FLOAT) \ + && (GET_MODE_SIZE (MODE) <= 8) \ + && ((TYPE) == NULL || !AGGREGATE_TYPE_P(TYPE)) \ + && ((MODE) != DImode || (CUM).num == 0)) \ + ? gen_rtx (REG, (MODE), \ + GET_MODE_CLASS(MODE) == MODE_FLOAT ? (CUM).num+16 : (CUM).num) \ + : 0) /* If defined, a C expression that gives the alignment boundary, in bits, of an argument with the specified mode and type. If it is not defined, @@ -515,14 +541,15 @@ do \ /* For an arg passed partly in registers and partly in memory, this is the number of registers used. - For args passed entirely in registers or entirely in memory, zero. */ + For args passed entirely in registers or entirely in memory, zero. + Clipper never passed args partially in regs/mem. */ -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 +/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 */ /* Generate necessary RTL for __builtin_saveregs(). ARGLIST is the argument list; see expr.c. */ -#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) clipper_builtin_saveregs (ARGLIST) +#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) clipper_builtin_saveregs (ARGLIST) /* This macro generates the assembly code for function entry. FILE is a stdio stream to output the code to. @@ -577,17 +604,18 @@ do \ #define TRAMPOLINE_TEMPLATE(FILE) \ { \ - fputs ("\tcall sp,.+4\n", FILE); \ + fputs ("\t.word 0x459F,0x0004\t# call sp,.+4\n", FILE); \ fputs ("\tmovw (sp),r3\n", FILE); \ fputs ("\taddq $4,sp\n", FILE); \ - fputs ("\tloadw 32(r3),r2\n", FILE); \ - fputs ("\tloadw 36(r3),r3\n", FILE); \ + fputs ("\tloadw 20(r3),r2\n", FILE); \ + fputs ("\tloadw 24(r3),r3\n", FILE); \ fputs ("\tb (r3)\n", FILE); \ + fputs ("\t.long 0,0\n", FILE); \ } /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE 44 +#define TRAMPOLINE_SIZE 32 /* Alignment required for a trampoline. 128 is used to find the beginning of a line in the instruction cache and to allow for @@ -605,8 +633,8 @@ do \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 36)), CXT); \ - emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 40)), FNADDR); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 24)), CXT); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 28)), FNADDR); \ } /* Addressing modes, and classification of registers for them. */ @@ -759,10 +787,15 @@ do \ jumps to the default label instead. */ /* #define CASE_DROPS_THROUGH */ -/* Define this macro if an instruction to load a value narrower than a - word from memory into a register also sign-extends the value to - the whole register. */ -#define BYTE_LOADS_SIGN_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) SIGN_EXTEND /* Specify the tree operation to be used to convert reals to integers. */ #define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR @@ -853,7 +886,6 @@ do \ case MOD: \ case UMOD: \ return COSTS_N_INSNS (40); \ - case LSHIFT: \ case ASHIFT: \ case LSHIFTRT: \ case ASHIFTRT: \