]>
Commit | Line | Data |
---|---|---|
2ec6afdd | 1 | /* Definitions of target machine for GNU compiler. 64 bit ABI support. |
2fb62c6a | 2 | Copyright (C) 1994, 1995, 1996 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 JW |
24 | #undef SUBTARGET_TARGET_OPTIONS |
25 | #define SUBTARGET_TARGET_OPTIONS\ | |
26 | { "abi=", &mips_abi_string }, | |
2ec6afdd | 27 | |
2ec6afdd | 28 | #undef STACK_BOUNDARY |
293a36eb ILT |
29 | #define STACK_BOUNDARY \ |
30 | ((mips_abi == ABI_32 || mips_abi == ABI_EABI) ? 64 : 128) | |
2ec6afdd JW |
31 | |
32 | #undef MIPS_STACK_ALIGN | |
293a36eb ILT |
33 | #define MIPS_STACK_ALIGN(LOC) \ |
34 | ((mips_abi == ABI_32 || mips_abi == ABI_EABI) \ | |
35 | ? ((LOC) + 7) & ~7 \ | |
36 | : ((LOC) + 15) & ~15) | |
2ec6afdd JW |
37 | |
38 | #undef GP_ARG_LAST | |
93c8a6e6 | 39 | #define GP_ARG_LAST (mips_abi == ABI_32 ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11) |
2ec6afdd | 40 | #undef FP_ARG_LAST |
93c8a6e6 | 41 | #define FP_ARG_LAST (mips_abi == ABI_32 ? FP_REG_FIRST + 15 : FP_REG_FIRST + 19) |
2ec6afdd | 42 | |
2ec6afdd JW |
43 | #undef SUBTARGET_CONDITIONAL_REGISTER_USAGE |
44 | #define SUBTARGET_CONDITIONAL_REGISTER_USAGE \ | |
45 | { \ | |
93c8a6e6 JW |
46 | /* fp20-23 are now caller saved. */ \ |
47 | if (mips_abi == ABI_64) \ | |
2ec6afdd JW |
48 | { \ |
49 | int regno; \ | |
50 | for (regno = FP_REG_FIRST + 20; regno < FP_REG_FIRST + 24; regno++) \ | |
51 | call_used_regs[regno] = 1; \ | |
52 | } \ | |
93c8a6e6 JW |
53 | /* odd registers from fp21 to fp31 are now caller saved. */ \ |
54 | if (mips_abi == ABI_N32) \ | |
55 | { \ | |
56 | int regno; \ | |
57 | for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2) \ | |
58 | call_used_regs[regno] = 1; \ | |
59 | } \ | |
2ec6afdd JW |
60 | } |
61 | ||
62 | #undef MAX_ARGS_IN_REGISTERS | |
93c8a6e6 | 63 | #define MAX_ARGS_IN_REGISTERS (mips_abi == ABI_32 ? 4 : 8) |
2ec6afdd JW |
64 | |
65 | #undef REG_PARM_STACK_SPACE | |
93c8a6e6 JW |
66 | #if 0 |
67 | /* ??? This is necessary in order for the ABI_32 support to work. However, | |
68 | expr.c (emit_push_insn) has no support for a REG_PARM_STACK_SPACE | |
69 | definition that returns zero. That would have to be fixed before this | |
70 | can be enabled. */ | |
71 | #define REG_PARM_STACK_SPACE(FNDECL) \ | |
72 | (mips_abi == ABI_32 \ | |
2ec6afdd JW |
73 | ? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \ |
74 | : 0) | |
93c8a6e6 | 75 | #endif |
2ec6afdd JW |
76 | |
77 | #define FUNCTION_ARG_PADDING(MODE, TYPE) \ | |
78 | (! BYTES_BIG_ENDIAN \ | |
79 | ? upward \ | |
80 | : (((MODE) == BLKmode \ | |
81 | ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ | |
82 | && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\ | |
83 | : (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \ | |
293a36eb ILT |
84 | && (mips_abi == ABI_32 || mips_abi == ABI_EABI \ |
85 | || GET_MODE_CLASS (MODE) == MODE_INT))) \ | |
2ec6afdd JW |
86 | ? downward : upward)) |
87 | ||
2ec6afdd | 88 | #undef RETURN_IN_MEMORY |
293a36eb | 89 | #define RETURN_IN_MEMORY(TYPE) \ |
93c8a6e6 | 90 | (mips_abi == ABI_32 \ |
293a36eb ILT |
91 | ? TYPE_MODE (TYPE) == BLKmode \ |
92 | : (int_size_in_bytes (TYPE) \ | |
93 | > (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16))) | |
2ec6afdd JW |
94 | |
95 | extern struct rtx_def *mips_function_value (); | |
96 | #undef FUNCTION_VALUE | |
97 | #define FUNCTION_VALUE(VALTYPE, FUNC) mips_function_value (VALTYPE, FUNC) | |
98 | ||
99 | /* For varargs, we must save the current argument, because it is the fake | |
100 | argument va_alist, and will need to be converted to the real argument. | |
101 | For stdarg, we do not need to save the current argument, because it | |
102 | is a real argument. */ | |
103 | #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ | |
293a36eb ILT |
104 | { int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \ |
105 | int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \ | |
106 | if ((mips_abi != ABI_32 \ | |
107 | && (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \ | |
108 | || (mips_abi == ABI_EABI \ | |
109 | && ! TARGET_SOFT_FLOAT \ | |
110 | && (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off)) \ | |
2ec6afdd | 111 | { \ |
293a36eb ILT |
112 | int mips_save_gp_regs = \ |
113 | MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off; \ | |
114 | int mips_save_fp_regs = \ | |
115 | (mips_abi != ABI_EABI ? 0 \ | |
116 | : MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \ | |
117 | \ | |
118 | if (mips_save_gp_regs < 0) \ | |
119 | mips_save_gp_regs = 0; \ | |
120 | if (mips_save_fp_regs < 0) \ | |
121 | mips_save_fp_regs = 0; \ | |
122 | PRETEND_SIZE = ((mips_save_gp_regs * UNITS_PER_WORD) \ | |
123 | + (mips_save_fp_regs * UNITS_PER_FPREG)); \ | |
2ec6afdd JW |
124 | \ |
125 | if (! (NO_RTL)) \ | |
c009da4f | 126 | { \ |
293a36eb ILT |
127 | if ((CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \ |
128 | { \ | |
129 | rtx ptr, mem; \ | |
130 | if (mips_abi != ABI_EABI) \ | |
131 | ptr = virtual_incoming_args_rtx; \ | |
132 | else \ | |
133 | ptr = plus_constant (virtual_incoming_args_rtx, \ | |
134 | - (mips_save_gp_regs \ | |
135 | * UNITS_PER_WORD)); \ | |
136 | mem = gen_rtx (MEM, BLKmode, ptr); \ | |
137 | /* va_arg is an array access in this case, which causes \ | |
138 | it to get MEM_IN_STRUCT_P set. We must set it here \ | |
139 | so that the insn scheduler won't assume that these \ | |
140 | stores can't possibly overlap with the va_arg loads. */ \ | |
141 | if (mips_abi != ABI_EABI && BYTES_BIG_ENDIAN) \ | |
142 | MEM_IN_STRUCT_P (mem) = 1; \ | |
143 | move_block_from_reg \ | |
144 | ((CUM).arg_words + GP_ARG_FIRST + mips_off, \ | |
145 | mem, \ | |
146 | mips_save_gp_regs, \ | |
147 | mips_save_gp_regs * UNITS_PER_WORD); \ | |
148 | } \ | |
149 | if (mips_abi == ABI_EABI \ | |
150 | && ! TARGET_SOFT_FLOAT \ | |
151 | && (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off) \ | |
152 | { \ | |
27eb1ab6 ILT |
153 | enum machine_mode mode = TARGET_SINGLE_FLOAT ? SFmode : DFmode; \ |
154 | int size = GET_MODE_SIZE (mode); \ | |
293a36eb ILT |
155 | int off; \ |
156 | int i; \ | |
157 | /* We can't use move_block_from_reg, because it will use \ | |
158 | the wrong mode. */ \ | |
27eb1ab6 ILT |
159 | off = - (mips_save_gp_regs * UNITS_PER_WORD); \ |
160 | if (! TARGET_SINGLE_FLOAT) \ | |
161 | off &= ~ 7; \ | |
162 | if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) \ | |
163 | off -= (mips_save_fp_regs / 2) * size; \ | |
164 | else \ | |
165 | off -= mips_save_fp_regs * size; \ | |
293a36eb ILT |
166 | for (i = 0; i < mips_save_fp_regs; i++) \ |
167 | { \ | |
168 | rtx tem = \ | |
27eb1ab6 | 169 | gen_rtx (MEM, mode, \ |
293a36eb | 170 | plus_constant (virtual_incoming_args_rtx, \ |
27eb1ab6 | 171 | off)); \ |
293a36eb | 172 | emit_move_insn (tem, \ |
27eb1ab6 | 173 | gen_rtx (REG, mode, \ |
293a36eb ILT |
174 | ((CUM).fp_arg_words \ |
175 | + FP_ARG_FIRST \ | |
176 | + i \ | |
177 | + mips_fp_off))); \ | |
27eb1ab6 ILT |
178 | off += size; \ |
179 | if (! TARGET_FLOAT64 || TARGET_SINGLE_FLOAT) \ | |
293a36eb ILT |
180 | ++i; \ |
181 | } \ | |
182 | } \ | |
c009da4f | 183 | } \ |
2ec6afdd JW |
184 | } \ |
185 | } | |
186 | ||
93c8a6e6 | 187 | /* ??? Should disable for mips_abi == ABI32. */ |
2ec6afdd JW |
188 | #define STRICT_ARGUMENT_NAMING |
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) \ | |
196 | (mips_abi == ABI_EABI \ | |
197 | && function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)) | |
198 | ||
199 | /* A C expression that indicates when it is the called function's | |
200 | responsibility to make a copy of arguments passed by invisible | |
201 | reference. Normally, the caller makes a copy and passes the | |
202 | address of the copy to the routine being called. When | |
203 | FUNCTION_ARG_CALLEE_COPIES is defined and is nonzero, the caller | |
204 | does not make a copy. Instead, it passes a pointer to the "live" | |
205 | value. The called function must not modify this value. If it can | |
206 | be determined that the value won't be modified, it need not make a | |
207 | copy; otherwise a copy must be made. | |
208 | ||
209 | ??? The MIPS EABI says that the caller should copy in ``K&R mode.'' | |
210 | I don't know how to detect that here, since flag_traditional is not | |
211 | a back end flag. */ | |
212 | #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ | |
213 | (mips_abi == ABI_EABI && (NAMED) \ | |
214 | && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) | |
215 | ||
04bd620d JW |
216 | /* Define LONG_MAX correctly for all users. We need to handle 32 bit EABI, |
217 | 64 bit EABI, N32, and N64 as possible defaults. The checks performed here | |
218 | are the same as the checks in override_options in mips.c that determines | |
219 | whether MASK_LONG64 will be set. | |
220 | ||
221 | This does not handle inappropriate options or ununusal option | |
222 | combinations. */ | |
223 | ||
4eb66248 | 224 | #undef LONG_MAX_SPEC |
04bd620d JW |
225 | #if ((MIPS_ABI_DEFAULT == ABI_64) || ((MIPS_ABI_DEFAULT == ABI_EABI) && ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_64BIT))) |
226 | #define LONG_MAX_SPEC \ | |
227 | "%{!mabi=n32:%{!mno-long64:%{!mgp32:-D__LONG_MAX__=9223372036854775807L}}}" | |
228 | #else | |
229 | #define LONG_MAX_SPEC \ | |
230 | "%{mabi=64:-D__LONG_MAX__=9223372036854775807L} \ | |
231 | %{mlong64:-D__LONG_MAX__=9223372036854775807L} \ | |
232 | %{mgp64:-D__LONG_MAX__=9223372036854775807L}" | |
233 | #endif | |
4eb66248 | 234 | |
2ec6afdd JW |
235 | /* ??? Unimplemented stuff follows. */ |
236 | ||
237 | /* ??? Add support for 16 byte/128 bit long doubles here when | |
93c8a6e6 | 238 | mips_abi != ABI32. */ |
2ec6afdd JW |
239 | |
240 | /* ??? Make main return zero if user did not specify return value. */ | |
241 | ||
242 | /* ??? Add support for .interfaces section, so as to get linker warnings | |
243 | when stdarg functions called without prototype in scope? */ | |
244 | ||
245 | /* ??? Could optimize structure passing by putting the right register rtx | |
246 | into the field decl, so that if we use the field, we can take the value from | |
247 | a register instead of from memory. */ | |
248 | ||
4eb66248 JL |
249 | |
250 |