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