]>
Commit | Line | Data |
---|---|---|
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 | |
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 | |
0e29e3c9 RK |
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
19 | Boston, 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 | |
96 | extern 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 |