OSDN Git Service

2001-08-01 H.J. Lu <hjl@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / abi64.h
1 /* Definitions of target machine for GNU compiler.  64 bit ABI support.
2    Copyright (C) 1994, 1995, 1996, 1998, 1999, 2001 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 /* Macros to implement the 64 bit ABI.  This file is meant to be included
22    after mips.h.  */
23
24 #undef SUBTARGET_TARGET_OPTIONS
25 #define SUBTARGET_TARGET_OPTIONS \
26   { "abi=", &mips_abi_string,                                           \
27       "Specify ABI to use"},
28
29 #undef STACK_BOUNDARY
30 #define STACK_BOUNDARY \
31   ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
32    ? 64 : 128)
33
34 #undef MIPS_STACK_ALIGN
35 #define MIPS_STACK_ALIGN(LOC)                                           \
36   ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)  \
37    ? ((LOC) + 7) & ~7                                                   \
38    : ((LOC) + 15) & ~15)
39
40 #undef GP_ARG_LAST
41 #define GP_ARG_LAST  ((mips_abi == ABI_32 || mips_abi == ABI_O64)       \
42                       ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
43 #undef FP_ARG_LAST
44 #define FP_ARG_LAST  ((mips_abi == ABI_32 || mips_abi == ABI_O64)       \
45                       ? FP_REG_FIRST + 15 : FP_REG_FIRST + 19)
46
47 #undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
48 #define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
49 {                                                                       \
50   /* fp20-23 are now caller saved.  */                                  \
51   if (mips_abi == ABI_64)                                               \
52     {                                                                   \
53       int regno;                                                        \
54       for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++) \
55         call_used_regs[regno] = 1;                                      \
56     }                                                                   \
57   /* odd registers from fp21 to fp31 are now caller saved.  */          \
58   if (mips_abi == ABI_N32)                                              \
59     {                                                                   \
60       int regno;                                                        \
61       for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2) \
62         call_used_regs[regno] = 1;                                      \
63     }                                                                   \
64 }
65
66 #undef MAX_ARGS_IN_REGISTERS
67 #define MAX_ARGS_IN_REGISTERS ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
68                                ? 4 : 8)
69
70 #undef REG_PARM_STACK_SPACE
71 #define REG_PARM_STACK_SPACE(FNDECL)                                     \
72   ((mips_abi == ABI_32 || mips_abi == ABI_O64)                           \
73    ? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \
74    : 0)
75
76 #define FUNCTION_ARG_PADDING(MODE, TYPE)                                \
77   (! BYTES_BIG_ENDIAN                                                   \
78    ? upward                                                             \
79    : (((MODE) == BLKmode                                                \
80        ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST         \
81           && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
82        : (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY                       \
83           && (mips_abi == ABI_32                                        \
84               || mips_abi == ABI_O64                                    \
85               || mips_abi == ABI_EABI                                   \
86               || GET_MODE_CLASS (MODE) == MODE_INT)))                   \
87       ? downward : upward))
88
89 /* Under the old (i.e., 32 and O64 ABIs) all BLKmode objects are
90    returned in memory.  Under the new (N32 and 64-bit MIPS ABIs) small
91    structures are returned in a register.  Objects with varying size
92    must still be returned in memory, of course.  */
93 #undef RETURN_IN_MEMORY
94 #define RETURN_IN_MEMORY(TYPE)                                           \
95   ((mips_abi == ABI_32 || mips_abi == ABI_O64)                           \
96    ? TYPE_MODE (TYPE) == BLKmode                                         \
97    : ((int_size_in_bytes (TYPE)                                          \
98        > (2 * UNITS_PER_WORD))                                           \
99       || (int_size_in_bytes (TYPE) == -1)))
100
101 #ifdef ANSI_PROTOTYPES
102 union tree_node;
103 #endif
104 extern struct rtx_def *mips_function_value PARAMS ((union tree_node *, union tree_node *));
105 #undef FUNCTION_VALUE
106 #define FUNCTION_VALUE(VALTYPE, FUNC)   mips_function_value (VALTYPE, FUNC)
107
108 /* For varargs, we must save the current argument, because it is the fake
109    argument va_alist, and will need to be converted to the real argument.
110    For stdarg, we do not need to save the current argument, because it
111    is a real argument.  */
112 #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)       \
113 { unsigned int mips_off                                                 \
114     = (! current_function_varargs) && (! (CUM).last_arg_fp);            \
115     unsigned int mips_fp_off                                            \
116     = (! current_function_varargs) && ((CUM).last_arg_fp);              \
117   if (((mips_abi != ABI_32 && mips_abi != ABI_O64)                      \
118        && (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off)           \
119       || (mips_abi == ABI_EABI                                          \
120           && ! TARGET_SOFT_FLOAT                                        \
121           && (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off)) \
122     {                                                                   \
123       int mips_save_gp_regs                                             \
124         = MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off;           \
125       int mips_save_fp_regs                                             \
126         = (mips_abi != ABI_EABI ? 0                                     \
127            : MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \
128                                                                         \
129       if (mips_save_gp_regs < 0)                                        \
130         mips_save_gp_regs = 0;                                          \
131       if (mips_save_fp_regs < 0)                                        \
132         mips_save_fp_regs = 0;                                          \
133       PRETEND_SIZE = ((mips_save_gp_regs * UNITS_PER_WORD)              \
134                       + (mips_save_fp_regs * UNITS_PER_FPREG));         \
135                                                                         \
136       if (! (NO_RTL))                                                   \
137         {                                                               \
138           if ((CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off)       \
139             {                                                           \
140               rtx ptr, mem;                                             \
141               if (mips_abi != ABI_EABI)                                 \
142                 ptr = virtual_incoming_args_rtx;                        \
143               else                                                      \
144                 ptr = plus_constant (virtual_incoming_args_rtx,         \
145                                      - (mips_save_gp_regs               \
146                                         * UNITS_PER_WORD));             \
147               mem = gen_rtx_MEM (BLKmode, ptr);                 \
148               /* va_arg is an array access in this case, which causes   \
149                  it to get MEM_IN_STRUCT_P set.  We must set it here    \
150                  so that the insn scheduler won't assume that these     \
151                  stores can't possibly overlap with the va_arg loads.  */ \
152               if (mips_abi != ABI_EABI && BYTES_BIG_ENDIAN)             \
153                 MEM_SET_IN_STRUCT_P (mem, 1);                           \
154               move_block_from_reg                                       \
155                 ((CUM).arg_words + GP_ARG_FIRST + mips_off,             \
156                  mem,                                                   \
157                  mips_save_gp_regs,                                     \
158                  mips_save_gp_regs * UNITS_PER_WORD);                   \
159             }                                                           \
160           if (mips_abi == ABI_EABI                                      \
161               && ! TARGET_SOFT_FLOAT                                    \
162               && (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off) \
163             {                                                           \
164               enum machine_mode mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode; \
165               int size = GET_MODE_SIZE (mode);                          \
166               int off;                                                  \
167               int i;                                                    \
168               /* We can't use move_block_from_reg, because it will use  \
169                  the wrong mode.  */                                    \
170               off = - (mips_save_gp_regs * UNITS_PER_WORD);             \
171               if (! TARGET_SINGLE_FLOAT)                                \
172                 off &= ~ 7;                                             \
173               if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT)              \
174                 off -= (mips_save_fp_regs / 2) * size;                  \
175               else                                                      \
176                 off -= mips_save_fp_regs * size;                        \
177               for (i = 0; i < mips_save_fp_regs; i++)                   \
178                 {                                                       \
179                   rtx tem =                                             \
180                     gen_rtx_MEM (mode,                                  \
181                                  plus_constant (virtual_incoming_args_rtx, \
182                                                 off));                  \
183                   emit_move_insn (tem,                                  \
184                                   gen_rtx_REG (mode,                    \
185                                                ((CUM).fp_arg_words      \
186                                                 + FP_ARG_FIRST          \
187                                                 + i                     \
188                                                 + mips_fp_off)));       \
189                   off += size;                                          \
190                   if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT)          \
191                     ++i;                                                \
192                 }                                                       \
193             }                                                           \
194         }                                                               \
195     }                                                                   \
196 }
197
198 #define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
199
200 /* A C expression that indicates when an argument must be passed by
201    reference.  If nonzero for an argument, a copy of that argument is
202    made in memory and a pointer to the argument is passed instead of the
203    argument itself.  The pointer is passed in whatever way is appropriate
204    for passing a pointer to that type.  */
205 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)          \
206   function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
207
208 /* A C expression that indicates when it is the called function's
209    responsibility to make a copy of arguments passed by invisible
210    reference.  Normally, the caller makes a copy and passes the
211    address of the copy to the routine being called.  When
212    FUNCTION_ARG_CALLEE_COPIES is defined and is nonzero, the caller
213    does not make a copy.  Instead, it passes a pointer to the "live"
214    value.  The called function must not modify this value.  If it can
215    be determined that the value won't be modified, it need not make a
216    copy; otherwise a copy must be made.
217
218    ??? The MIPS EABI says that the caller should copy in ``K&R mode.''
219    I don't know how to detect that here, since flag_traditional is not
220    a back end flag.  */
221 #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED)              \
222   (mips_abi == ABI_EABI && (NAMED)                                      \
223    && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))
224
225 /* Define LONG_MAX correctly for all users.  We need to handle 32 bit EABI,
226    64 bit EABI, N32, and N64 as possible defaults.  The checks performed here
227    are the same as the checks in override_options in mips.c that determines
228    whether MASK_LONG64 will be set.
229
230    This does not handle inappropriate options or ununusal option
231    combinations.  */
232
233 #undef LONG_MAX_SPEC
234 #if ((MIPS_ABI_DEFAULT == ABI_64) || ((MIPS_ABI_DEFAULT == ABI_EABI) && ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_64BIT)))
235 #define LONG_MAX_SPEC \
236   "%{!mabi=32:%{!mabi=n32:%{!mlong32:%{!mgp32:%{!mips1:%{!mips2:-D__LONG_MAX__=9223372036854775807L}}}}}}"
237 #else
238 #define LONG_MAX_SPEC \
239   "%{mabi=64:-D__LONG_MAX__=9223372036854775807L} \
240    %{mlong64:-D__LONG_MAX__=9223372036854775807L} \
241    %{mgp64:-D__LONG_MAX__=9223372036854775807L}"
242 #endif
243
244 /* ??? Unimplemented stuff follows.  */
245
246 /* ??? Add support for 16 byte/128 bit long doubles here when
247    mips_abi != ABI32.  */
248
249 /* ??? Make main return zero if user did not specify return value.  */
250
251 /* ??? Add support for .interfaces section, so as to get linker warnings
252    when stdarg functions called without prototype in scope?  */
253
254 /* ??? Could optimize structure passing by putting the right register rtx
255    into the field decl, so that if we use the field, we can take the value from
256    a register instead of from memory.  */
257
258
259