]>
Commit | Line | Data |
---|---|---|
cb0ca284 | 1 | /* Definitions of target machine for GNU compiler. TMS320C[34]x |
c58b209a | 2 | Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, |
fe9565ed | 3 | 2003, 2004, 2005 Free Software Foundation, Inc. |
cb0ca284 MH |
4 | |
5 | Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz) | |
6 | and Herman Ten Brugge (Haj.Ten.Brugge@net.HCC.nl). | |
7 | ||
4db9c756 | 8 | This file is part of GCC. |
cb0ca284 | 9 | |
4db9c756 | 10 | GCC is free software; you can redistribute it and/or modify |
cb0ca284 | 11 | it under the terms of the GNU General Public License as published by |
c063dc98 | 12 | the Free Software Foundation; either version 2, or (at your option) |
cb0ca284 MH |
13 | any later version. |
14 | ||
4db9c756 | 15 | GCC is distributed in the hope that it will be useful, |
cb0ca284 MH |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | GNU General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU General Public License | |
4db9c756 | 21 | along with GCC; see the file COPYING. If not, write to |
39d14dda KC |
22 | the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
23 | Boston, MA 02110-1301, USA. */ | |
cb0ca284 | 24 | |
975ab131 | 25 | /* RUN-TIME TARGET SPECIFICATION. */ |
cb0ca284 MH |
26 | |
27 | #define C4x 1 | |
28 | ||
0d66ad57 NB |
29 | #define TARGET_CPU_CPP_BUILTINS() \ |
30 | do \ | |
31 | { \ | |
c4a3da4e | 32 | extern int flag_inline_trees; \ |
0d66ad57 NB |
33 | if (!TARGET_SMALL) \ |
34 | builtin_define ("_BIGMODEL"); \ | |
35 | if (!TARGET_MEMPARM) \ | |
36 | builtin_define ("_REGPARM"); \ | |
39afeb1a | 37 | if (flag_inline_functions) \ |
0d66ad57 NB |
38 | builtin_define ("_INLINE"); \ |
39 | if (TARGET_C3X) \ | |
40 | { \ | |
41 | builtin_define ("_TMS320C3x"); \ | |
42 | builtin_define ("_C3x"); \ | |
43 | if (TARGET_C30) \ | |
44 | { \ | |
45 | builtin_define ("_TMS320C30"); \ | |
46 | builtin_define ("_C30"); \ | |
47 | } \ | |
48 | else if (TARGET_C31) \ | |
49 | { \ | |
50 | builtin_define ("_TMS320C31"); \ | |
51 | builtin_define ("_C31"); \ | |
52 | } \ | |
53 | else if (TARGET_C32) \ | |
54 | { \ | |
55 | builtin_define ("_TMS320C32"); \ | |
56 | builtin_define ("_C32"); \ | |
57 | } \ | |
58 | else if (TARGET_C33) \ | |
59 | { \ | |
60 | builtin_define ("_TMS320C33"); \ | |
61 | builtin_define ("_C33"); \ | |
62 | } \ | |
63 | } \ | |
64 | else \ | |
65 | { \ | |
66 | builtin_define ("_TMS320C4x"); \ | |
67 | builtin_define ("_C4x"); \ | |
68 | if (TARGET_C40) \ | |
69 | { \ | |
70 | builtin_define ("_TMS320C40"); \ | |
71 | builtin_define ("_C40"); \ | |
72 | } \ | |
73 | else if (TARGET_C44) \ | |
74 | { \ | |
75 | builtin_define ("_TMS320C44"); \ | |
76 | builtin_define ("_C44"); \ | |
77 | } \ | |
78 | } \ | |
79 | } \ | |
80 | while (0) | |
81 | ||
ad69db4a | 82 | /* Define assembler options. */ |
cb0ca284 MH |
83 | |
84 | #define ASM_SPEC "\ | |
eda45b64 | 85 | %{!mcpu=30:%{!mcpu=31:%{!mcpu=32:%{!mcpu=33:%{!mcpu=40:%{!mcpu=44:\ |
cebdac46 SS |
86 | %{!m30:%{!m31:%{!m32:%{!m33:%{!m40:%{!m44:-m40}}}}}}}}}}}} \ |
87 | %{mcpu=30} \ | |
88 | %{mcpu=31} \ | |
89 | %{mcpu=32} \ | |
90 | %{mcpu=33} \ | |
91 | %{mcpu=40} \ | |
92 | %{mcpu=44} \ | |
93 | %{m30} \ | |
94 | %{m31} \ | |
95 | %{m32} \ | |
96 | %{m33} \ | |
97 | %{m40} \ | |
98 | %{m44} \ | |
99 | %{mmemparm} %{mregparm} %{!mmemparm:%{!mregparm:-mregparm}} \ | |
100 | %{mbig} %{msmall} %{!msmall:%{!mbig:-mbig}}" | |
cb0ca284 | 101 | |
ad69db4a | 102 | /* Define linker options. */ |
cb0ca284 MH |
103 | |
104 | #define LINK_SPEC "\ | |
105 | %{m30:--architecture c3x} \ | |
106 | %{m31:--architecture c3x} \ | |
107 | %{m32:--architecture c3x} \ | |
eda45b64 | 108 | %{m33:--architecture c3x} \ |
cb0ca284 MH |
109 | %{mcpu=30:--architecture c3x} \ |
110 | %{mcpu=31:--architecture c3x} \ | |
eda45b64 MH |
111 | %{mcpu=32:--architecture c3x} \ |
112 | %{mcpu=33:--architecture c3x}" | |
cb0ca284 | 113 | |
ad69db4a | 114 | /* Specify the end file to link with. */ |
cb0ca284 MH |
115 | |
116 | #define ENDFILE_SPEC "" | |
117 | ||
cb0ca284 MH |
118 | /* Caveats: |
119 | Max iteration count for RPTB/RPTS is 2^31 + 1. | |
120 | Max iteration count for DB is 2^31 + 1 for C40, but 2^23 + 1 for C30. | |
121 | RPTS blocks interrupts. */ | |
122 | ||
123 | ||
d12f3c1f | 124 | extern int c4x_cpu_version; /* Cpu version C30/31/32/33/40/44. */ |
cb0ca284 | 125 | |
f42850b9 | 126 | #define TARGET_INLINE (! optimize_size) /* Inline MPYI. */ |
2e3e9ead | 127 | #define TARGET_SMALL_REG_CLASS 0 |
cb0ca284 | 128 | |
d12f3c1f RS |
129 | #define TARGET_C3X (c4x_cpu_version >= 30 \ |
130 | && c4x_cpu_version <= 39) | |
131 | ||
132 | #define TARGET_C30 (c4x_cpu_version == 30) | |
133 | #define TARGET_C31 (c4x_cpu_version == 31) | |
134 | #define TARGET_C32 (c4x_cpu_version == 32) | |
135 | #define TARGET_C33 (c4x_cpu_version == 33) | |
136 | #define TARGET_C40 (c4x_cpu_version == 40) | |
137 | #define TARGET_C44 (c4x_cpu_version == 44) | |
cb0ca284 | 138 | |
8f422192 MH |
139 | /* Nonzero to use load_immed_addr pattern rather than forcing memory |
140 | addresses into memory. */ | |
50c33087 | 141 | #define TARGET_LOAD_ADDRESS (1 || (! TARGET_C3X && ! TARGET_SMALL)) |
8f422192 | 142 | |
860b3499 MH |
143 | /* Nonzero to convert direct memory references into HIGH/LO_SUM pairs |
144 | during RTL generation. */ | |
31445126 | 145 | #define TARGET_EXPOSE_LDP 0 |
8f422192 | 146 | |
860b3499 MH |
147 | /* Nonzero to force loading of direct memory references into a register. */ |
148 | #define TARGET_LOAD_DIRECT_MEMS 0 | |
50c33087 | 149 | |
cb0ca284 MH |
150 | /* -mrpts allows the use of the RPTS instruction irregardless. |
151 | -mrpts=max-cycles will use RPTS if the number of cycles is constant | |
1ac7a7f5 | 152 | and less than max-cycles. */ |
cb0ca284 MH |
153 | |
154 | #define TARGET_RPTS_CYCLES(CYCLES) (TARGET_RPTS || (CYCLES) < c4x_rpts_cycles) | |
155 | ||
cb0ca284 MH |
156 | /* Sometimes certain combinations of command options do not make sense |
157 | on a particular target machine. You can define a macro | |
158 | `OVERRIDE_OPTIONS' to take account of this. This macro, if | |
159 | defined, is executed once just after all the command options have | |
1ac7a7f5 | 160 | been parsed. */ |
cb0ca284 | 161 | |
cb0ca284 MH |
162 | #define OVERRIDE_OPTIONS c4x_override_options () |
163 | ||
d5e4ff48 | 164 | /* Define this to change the optimizations performed by default. */ |
798f6e6f | 165 | |
4e6de5a9 | 166 | #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) c4x_optimization_options(LEVEL, SIZE) |
cb0ca284 | 167 | |
975ab131 | 168 | /* Run Time Target Specification. */ |
cb0ca284 | 169 | |
4e6de5a9 | 170 | #define TARGET_VERSION fprintf (stderr, " (TMS320C[34]x, TI syntax)"); |
cb0ca284 | 171 | |
975ab131 | 172 | /* Storage Layout. */ |
cb0ca284 MH |
173 | |
174 | #define BITS_BIG_ENDIAN 0 | |
175 | #define BYTES_BIG_ENDIAN 0 | |
176 | #define WORDS_BIG_ENDIAN 0 | |
177 | ||
178 | /* Technically, we are little endian, but we put the floats out as | |
1ac7a7f5 | 179 | whole longs and this makes GCC put them out in the right order. */ |
cb0ca284 MH |
180 | |
181 | #define FLOAT_WORDS_BIG_ENDIAN 1 | |
182 | ||
183 | /* Note the ANSI C standard requires sizeof(char) = 1. On the C[34]x | |
184 | all integral and floating point data types are stored in memory as | |
185 | 32-bits (floating point types can be stored as 40-bits in the | |
186 | extended precision registers), so sizeof(char) = sizeof(short) = | |
1ac7a7f5 | 187 | sizeof(int) = sizeof(long) = sizeof(float) = sizeof(double) = 1. */ |
cb0ca284 MH |
188 | |
189 | #define BITS_PER_UNIT 32 | |
cb0ca284 | 190 | #define UNITS_PER_WORD 1 |
cb0ca284 MH |
191 | #define PARM_BOUNDARY 32 |
192 | #define STACK_BOUNDARY 32 | |
193 | #define FUNCTION_BOUNDARY 32 | |
194 | #define BIGGEST_ALIGNMENT 32 | |
195 | #define EMPTY_FIELD_BOUNDARY 32 | |
196 | #define STRICT_ALIGNMENT 0 | |
197 | #define TARGET_FLOAT_FORMAT C4X_FLOAT_FORMAT | |
975ab131 | 198 | #define MAX_FIXED_MODE_SIZE 64 /* HImode. */ |
cb0ca284 | 199 | |
7f7680a9 | 200 | /* If a structure has a floating point field then force structure |
182e515e AH |
201 | to have BLKMODE, unless it is the only field. */ |
202 | #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \ | |
203 | (TREE_CODE (TREE_TYPE (FIELD)) == REAL_TYPE && (MODE) == VOIDmode) | |
7f7680a9 | 204 | |
55310df7 MH |
205 | /* Number of bits in the high and low parts of a two stage |
206 | load of an immediate constant. */ | |
207 | #define BITS_PER_HIGH 16 | |
208 | #define BITS_PER_LO_SUM 16 | |
209 | ||
bc46716b | 210 | /* Define register numbers. */ |
cb0ca284 | 211 | |
bc46716b | 212 | /* Extended-precision registers. */ |
cb0ca284 MH |
213 | |
214 | #define R0_REGNO 0 | |
215 | #define R1_REGNO 1 | |
216 | #define R2_REGNO 2 | |
217 | #define R3_REGNO 3 | |
218 | #define R4_REGNO 4 | |
219 | #define R5_REGNO 5 | |
220 | #define R6_REGNO 6 | |
221 | #define R7_REGNO 7 | |
222 | ||
bc46716b | 223 | /* Auxiliary (address) registers. */ |
cb0ca284 MH |
224 | |
225 | #define AR0_REGNO 8 | |
226 | #define AR1_REGNO 9 | |
227 | #define AR2_REGNO 10 | |
228 | #define AR3_REGNO 11 | |
229 | #define AR4_REGNO 12 | |
230 | #define AR5_REGNO 13 | |
231 | #define AR6_REGNO 14 | |
232 | #define AR7_REGNO 15 | |
233 | ||
bc46716b | 234 | /* Data page register. */ |
cb0ca284 MH |
235 | |
236 | #define DP_REGNO 16 | |
237 | ||
bc46716b | 238 | /* Index registers. */ |
cb0ca284 MH |
239 | |
240 | #define IR0_REGNO 17 | |
241 | #define IR1_REGNO 18 | |
242 | ||
bc46716b | 243 | /* Block size register. */ |
cb0ca284 MH |
244 | |
245 | #define BK_REGNO 19 | |
246 | ||
bc46716b | 247 | /* Stack pointer. */ |
cb0ca284 MH |
248 | |
249 | #define SP_REGNO 20 | |
250 | ||
bc46716b | 251 | /* Status register. */ |
cb0ca284 MH |
252 | |
253 | #define ST_REGNO 21 | |
254 | ||
bc46716b | 255 | /* Misc. interrupt registers. */ |
cb0ca284 | 256 | |
bc46716b MH |
257 | #define DIE_REGNO 22 /* C4x only. */ |
258 | #define IE_REGNO 22 /* C3x only. */ | |
259 | #define IIE_REGNO 23 /* C4x only. */ | |
260 | #define IF_REGNO 23 /* C3x only. */ | |
261 | #define IIF_REGNO 24 /* C4x only. */ | |
262 | #define IOF_REGNO 24 /* C3x only. */ | |
cb0ca284 | 263 | |
bc46716b | 264 | /* Repeat block registers. */ |
cb0ca284 MH |
265 | |
266 | #define RS_REGNO 25 | |
267 | #define RE_REGNO 26 | |
268 | #define RC_REGNO 27 | |
269 | ||
bc46716b | 270 | /* Additional extended-precision registers. */ |
cb0ca284 | 271 | |
bc46716b MH |
272 | #define R8_REGNO 28 /* C4x only. */ |
273 | #define R9_REGNO 29 /* C4x only. */ | |
274 | #define R10_REGNO 30 /* C4x only. */ | |
275 | #define R11_REGNO 31 /* C4x only. */ | |
cb0ca284 MH |
276 | |
277 | #define FIRST_PSEUDO_REGISTER 32 | |
278 | ||
bc46716b | 279 | /* Extended precision registers (low set). */ |
cb0ca284 | 280 | |
25cd0db1 MH |
281 | #define IS_R0R1_REGNO(r) \ |
282 | ((unsigned int)((r) - R0_REGNO) <= (R1_REGNO - R0_REGNO)) | |
283 | #define IS_R2R3_REGNO(r) \ | |
284 | ((unsigned int)((r) - R2_REGNO) <= (R3_REGNO - R2_REGNO)) | |
285 | #define IS_EXT_LOW_REGNO(r) \ | |
286 | ((unsigned int)((r) - R0_REGNO) <= (R7_REGNO - R0_REGNO)) | |
cb0ca284 | 287 | |
bc46716b | 288 | /* Extended precision registers (high set). */ |
cb0ca284 | 289 | |
25cd0db1 MH |
290 | #define IS_EXT_HIGH_REGNO(r) \ |
291 | (! TARGET_C3X \ | |
292 | && ((unsigned int) ((r) - R8_REGNO) <= (R11_REGNO - R8_REGNO))) | |
293 | ||
bc46716b MH |
294 | /* Address registers. */ |
295 | ||
25cd0db1 MH |
296 | #define IS_AUX_REGNO(r) \ |
297 | ((unsigned int)((r) - AR0_REGNO) <= (AR7_REGNO - AR0_REGNO)) | |
bc46716b MH |
298 | #define IS_ADDR_REGNO(r) IS_AUX_REGNO(r) |
299 | #define IS_DP_REGNO(r) ((r) == DP_REGNO) | |
300 | #define IS_INDEX_REGNO(r) (((r) == IR0_REGNO) || ((r) == IR1_REGNO)) | |
301 | #define IS_SP_REGNO(r) ((r) == SP_REGNO) | |
302 | #define IS_BK_REGNO(r) (TARGET_BK && (r) == BK_REGNO) | |
303 | ||
304 | /* Misc registers. */ | |
305 | ||
306 | #define IS_ST_REGNO(r) ((r) == ST_REGNO) | |
307 | #define IS_RC_REGNO(r) ((r) == RC_REGNO) | |
308 | #define IS_REPEAT_REGNO(r) (((r) >= RS_REGNO) && ((r) <= RC_REGNO)) | |
309 | ||
310 | /* Composite register sets. */ | |
311 | ||
312 | #define IS_ADDR_OR_INDEX_REGNO(r) (IS_ADDR_REGNO(r) || IS_INDEX_REGNO(r)) | |
313 | #define IS_EXT_REGNO(r) (IS_EXT_LOW_REGNO(r) || IS_EXT_HIGH_REGNO(r)) | |
314 | #define IS_STD_REGNO(r) (IS_ADDR_OR_INDEX_REGNO(r) \ | |
315 | || IS_REPEAT_REGNO(r) \ | |
316 | || IS_SP_REGNO(r) \ | |
317 | || IS_BK_REGNO(r)) | |
318 | #define IS_INT_REGNO(r) (IS_EXT_REGNO(r) || IS_STD_REGNO(r)) | |
319 | #define IS_GROUP1_REGNO(r) (IS_ADDR_OR_INDEX_REGNO(r) || IS_BK_REGNO(r)) | |
0b53f039 MH |
320 | #define IS_INT_CALL_SAVED_REGNO(r) (((r) == R4_REGNO) || ((r) == R5_REGNO) \ |
321 | || ((r) == R8_REGNO)) | |
322 | #define IS_FLOAT_CALL_SAVED_REGNO(r) (((r) == R6_REGNO) || ((r) == R7_REGNO)) | |
bc46716b MH |
323 | |
324 | #define IS_PSEUDO_REGNO(r) ((r) >= FIRST_PSEUDO_REGISTER) | |
325 | #define IS_R0R1_OR_PSEUDO_REGNO(r) (IS_R0R1_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
326 | #define IS_R2R3_OR_PSEUDO_REGNO(r) (IS_R2R3_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
327 | #define IS_EXT_OR_PSEUDO_REGNO(r) (IS_EXT_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
328 | #define IS_STD_OR_PSEUDO_REGNO(r) (IS_STD_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
329 | #define IS_INT_OR_PSEUDO_REGNO(r) (IS_INT_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
330 | #define IS_ADDR_OR_PSEUDO_REGNO(r) (IS_ADDR_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
331 | #define IS_INDEX_OR_PSEUDO_REGNO(r) (IS_INDEX_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
332 | #define IS_EXT_LOW_OR_PSEUDO_REGNO(r) (IS_EXT_LOW_REGNO(r) \ | |
333 | || IS_PSEUDO_REGNO(r)) | |
334 | #define IS_DP_OR_PSEUDO_REGNO(r) (IS_DP_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
335 | #define IS_SP_OR_PSEUDO_REGNO(r) (IS_SP_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
336 | #define IS_ST_OR_PSEUDO_REGNO(r) (IS_ST_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
337 | #define IS_RC_OR_PSEUDO_REGNO(r) (IS_RC_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
338 | ||
339 | #define IS_PSEUDO_REG(op) (IS_PSEUDO_REGNO(REGNO(op))) | |
340 | #define IS_ADDR_REG(op) (IS_ADDR_REGNO(REGNO(op))) | |
341 | #define IS_INDEX_REG(op) (IS_INDEX_REGNO(REGNO(op))) | |
342 | #define IS_GROUP1_REG(r) (IS_GROUP1_REGNO(REGNO(op))) | |
343 | #define IS_SP_REG(op) (IS_SP_REGNO(REGNO(op))) | |
344 | #define IS_STD_REG(op) (IS_STD_REGNO(REGNO(op))) | |
345 | #define IS_EXT_REG(op) (IS_EXT_REGNO(REGNO(op))) | |
346 | ||
347 | #define IS_R0R1_OR_PSEUDO_REG(op) (IS_R0R1_OR_PSEUDO_REGNO(REGNO(op))) | |
348 | #define IS_R2R3_OR_PSEUDO_REG(op) (IS_R2R3_OR_PSEUDO_REGNO(REGNO(op))) | |
349 | #define IS_EXT_OR_PSEUDO_REG(op) (IS_EXT_OR_PSEUDO_REGNO(REGNO(op))) | |
350 | #define IS_STD_OR_PSEUDO_REG(op) (IS_STD_OR_PSEUDO_REGNO(REGNO(op))) | |
351 | #define IS_EXT_LOW_OR_PSEUDO_REG(op) (IS_EXT_LOW_OR_PSEUDO_REGNO(REGNO(op))) | |
352 | #define IS_INT_OR_PSEUDO_REG(op) (IS_INT_OR_PSEUDO_REGNO(REGNO(op))) | |
353 | ||
354 | #define IS_ADDR_OR_PSEUDO_REG(op) (IS_ADDR_OR_PSEUDO_REGNO(REGNO(op))) | |
355 | #define IS_INDEX_OR_PSEUDO_REG(op) (IS_INDEX_OR_PSEUDO_REGNO(REGNO(op))) | |
356 | #define IS_DP_OR_PSEUDO_REG(op) (IS_DP_OR_PSEUDO_REGNO(REGNO(op))) | |
357 | #define IS_SP_OR_PSEUDO_REG(op) (IS_SP_OR_PSEUDO_REGNO(REGNO(op))) | |
358 | #define IS_ST_OR_PSEUDO_REG(op) (IS_ST_OR_PSEUDO_REGNO(REGNO(op))) | |
359 | #define IS_RC_OR_PSEUDO_REG(op) (IS_RC_OR_PSEUDO_REGNO(REGNO(op))) | |
cb0ca284 MH |
360 | |
361 | /* 1 for registers that have pervasive standard uses | |
1ac7a7f5 | 362 | and are not available for the register allocator. */ |
cb0ca284 MH |
363 | |
364 | #define FIXED_REGISTERS \ | |
365 | { \ | |
975ab131 | 366 | /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \ |
cb0ca284 | 367 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ |
975ab131 | 368 | /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \ |
cb0ca284 MH |
369 | 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 \ |
370 | } | |
371 | ||
372 | /* 1 for registers not available across function calls. | |
373 | These must include the FIXED_REGISTERS and also any | |
374 | registers that can be used without being saved. | |
375 | The latter must include the registers where values are returned | |
376 | and the register where structure-value addresses are passed. | |
377 | Aside from that, you can include as many other registers as you like. | |
378 | ||
379 | Note that the extended precision registers are only saved in some | |
380 | modes. The macro HARD_REGNO_CALL_CLOBBERED specifies which modes | |
381 | get clobbered for a given regno. */ | |
382 | ||
383 | #define CALL_USED_REGISTERS \ | |
384 | { \ | |
975ab131 | 385 | /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \ |
cb0ca284 | 386 | 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, \ |
975ab131 | 387 | /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \ |
cb0ca284 MH |
388 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 \ |
389 | } | |
390 | ||
1ac7a7f5 | 391 | /* Macro to conditionally modify fixed_regs/call_used_regs. */ |
cb0ca284 MH |
392 | |
393 | #define CONDITIONAL_REGISTER_USAGE \ | |
394 | { \ | |
4ddb3ea6 | 395 | if (! TARGET_BK) \ |
cb0ca284 MH |
396 | { \ |
397 | fixed_regs[BK_REGNO] = 1; \ | |
398 | call_used_regs[BK_REGNO] = 1; \ | |
399 | c4x_regclass_map[BK_REGNO] = NO_REGS; \ | |
400 | } \ | |
401 | if (TARGET_C3X) \ | |
402 | { \ | |
403 | int i; \ | |
404 | \ | |
975ab131 MH |
405 | reg_names[DIE_REGNO] = "ie"; /* Clobber die. */ \ |
406 | reg_names[IF_REGNO] = "if"; /* Clobber iie. */ \ | |
407 | reg_names[IOF_REGNO] = "iof"; /* Clobber iif. */ \ | |
cb0ca284 MH |
408 | \ |
409 | for (i = R8_REGNO; i <= R11_REGNO; i++) \ | |
410 | { \ | |
411 | fixed_regs[i] = call_used_regs[i] = 1; \ | |
412 | c4x_regclass_map[i] = NO_REGS; \ | |
413 | } \ | |
414 | } \ | |
2e3e9ead MH |
415 | if (TARGET_PRESERVE_FLOAT) \ |
416 | { \ | |
417 | c4x_caller_save_map[R6_REGNO] = HFmode; \ | |
418 | c4x_caller_save_map[R7_REGNO] = HFmode; \ | |
419 | } \ | |
cb0ca284 MH |
420 | } |
421 | ||
975ab131 | 422 | /* Order of Allocation of Registers. */ |
cb0ca284 MH |
423 | |
424 | /* List the order in which to allocate registers. Each register must be | |
425 | listed once, even those in FIXED_REGISTERS. | |
426 | ||
427 | First allocate registers that don't need preservation across calls, | |
428 | except index and address registers. Then allocate data registers | |
429 | that require preservation across calls (even though this invokes an | |
430 | extra overhead of having to save/restore these registers). Next | |
431 | allocate the address and index registers, since using these | |
432 | registers for arithmetic can cause pipeline stalls. Finally | |
433 | allocated the fixed registers which won't be allocated anyhow. */ | |
434 | ||
435 | #define REG_ALLOC_ORDER \ | |
436 | {R0_REGNO, R1_REGNO, R2_REGNO, R3_REGNO, \ | |
437 | R9_REGNO, R10_REGNO, R11_REGNO, \ | |
438 | RS_REGNO, RE_REGNO, RC_REGNO, BK_REGNO, \ | |
439 | R4_REGNO, R5_REGNO, R6_REGNO, R7_REGNO, R8_REGNO, \ | |
440 | AR0_REGNO, AR1_REGNO, AR2_REGNO, AR3_REGNO, \ | |
441 | AR4_REGNO, AR5_REGNO, AR6_REGNO, AR7_REGNO, \ | |
442 | IR0_REGNO, IR1_REGNO, \ | |
443 | SP_REGNO, DP_REGNO, ST_REGNO, IE_REGNO, IF_REGNO, IOF_REGNO} | |
444 | ||
40eef757 HB |
445 | /* A C expression that is nonzero if hard register number REGNO2 can be |
446 | considered for use as a rename register for REGNO1 */ | |
447 | ||
448 | #define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \ | |
449 | c4x_hard_regno_rename_ok((REGNO1), (REGNO2)) | |
cb0ca284 MH |
450 | |
451 | /* Determine which register classes are very likely used by spill registers. | |
452 | local-alloc.c won't allocate pseudos that have these classes as their | |
453 | preferred class unless they are "preferred or nothing". */ | |
454 | ||
4e6de5a9 | 455 | #define CLASS_LIKELY_SPILLED_P(CLASS) ((CLASS) == INDEX_REGS) |
cb0ca284 | 456 | |
d0550d07 HB |
457 | /* CCmode is wrongly defined in machmode.def. It should have a size |
458 | of UNITS_PER_WORD. HFmode is 40-bits and thus fits within a single | |
459 | extended precision register. Similarly, HCmode fits within two | |
460 | extended precision registers. */ | |
cb0ca284 MH |
461 | |
462 | #define HARD_REGNO_NREGS(REGNO, MODE) \ | |
d0550d07 HB |
463 | (((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : \ |
464 | ((MODE) == HFmode) ? 1 : \ | |
465 | ((MODE) == HCmode) ? 2 : \ | |
466 | ((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) | |
cb0ca284 MH |
467 | |
468 | ||
469 | /* A C expression that is nonzero if the hard register REGNO is preserved | |
470 | across a call in mode MODE. This does not have to include the call used | |
471 | registers. */ | |
472 | ||
2e3e9ead | 473 | #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ |
0b53f039 | 474 | ((IS_FLOAT_CALL_SAVED_REGNO (REGNO) && ! ((MODE) == QFmode)) \ |
c98f0cdb | 475 | || (IS_INT_CALL_SAVED_REGNO (REGNO) \ |
2e3e9ead | 476 | && ! ((MODE) == QImode || (MODE) == HImode || (MODE) == Pmode))) |
cb0ca284 MH |
477 | |
478 | /* Specify the modes required to caller save a given hard regno. */ | |
479 | ||
787dc842 | 480 | #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) (c4x_caller_save_map[REGNO]) |
cb0ca284 | 481 | |
4e6de5a9 | 482 | #define HARD_REGNO_MODE_OK(REGNO, MODE) c4x_hard_regno_mode_ok(REGNO, MODE) |
cb0ca284 MH |
483 | |
484 | /* A C expression that is nonzero if it is desirable to choose | |
485 | register allocation so as to avoid move instructions between a | |
486 | value of mode MODE1 and a value of mode MODE2. | |
487 | ||
488 | Value is 1 if it is a good idea to tie two pseudo registers | |
489 | when one has mode MODE1 and one has mode MODE2. | |
490 | If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, | |
491 | for any hard reg, then this must be 0 for correct output. */ | |
492 | ||
4e6de5a9 | 493 | #define MODES_TIEABLE_P(MODE1, MODE2) 0 |
cb0ca284 MH |
494 | |
495 | ||
496 | /* Define the classes of registers for register constraints in the | |
497 | machine description. Also define ranges of constants. | |
498 | ||
499 | One of the classes must always be named ALL_REGS and include all hard regs. | |
500 | If there is more than one class, another class must be named NO_REGS | |
501 | and contain no registers. | |
502 | ||
503 | The name GENERAL_REGS must be the name of a class (or an alias for | |
504 | another name such as ALL_REGS). This is the class of registers | |
505 | that is allowed by "g" or "r" in a register constraint. | |
506 | Also, registers outside this class are allocated only when | |
507 | instructions express preferences for them. | |
508 | ||
509 | The classes must be numbered in nondecreasing order; that is, | |
510 | a larger-numbered class must never be contained completely | |
511 | in a smaller-numbered class. | |
512 | ||
513 | For any two classes, it is very desirable that there be another | |
514 | class that represents their union. */ | |
515 | ||
516 | enum reg_class | |
517 | { | |
518 | NO_REGS, | |
975ab131 MH |
519 | R0R1_REGS, /* 't'. */ |
520 | R2R3_REGS, /* 'u'. */ | |
521 | EXT_LOW_REGS, /* 'q'. */ | |
522 | EXT_REGS, /* 'f'. */ | |
523 | ADDR_REGS, /* 'a'. */ | |
524 | INDEX_REGS, /* 'x'. */ | |
525 | BK_REG, /* 'k'. */ | |
526 | SP_REG, /* 'b'. */ | |
527 | RC_REG, /* 'v'. */ | |
4a6330ac | 528 | COUNTER_REGS, /* */ |
975ab131 MH |
529 | INT_REGS, /* 'c'. */ |
530 | GENERAL_REGS, /* 'r'. */ | |
531 | DP_REG, /* 'z'. */ | |
532 | ST_REG, /* 'y'. */ | |
cb0ca284 MH |
533 | ALL_REGS, |
534 | LIM_REG_CLASSES | |
535 | }; | |
536 | ||
537 | #define N_REG_CLASSES (int) LIM_REG_CLASSES | |
538 | ||
539 | #define REG_CLASS_NAMES \ | |
540 | { \ | |
541 | "NO_REGS", \ | |
542 | "R0R1_REGS", \ | |
543 | "R2R3_REGS", \ | |
544 | "EXT_LOW_REGS", \ | |
545 | "EXT_REGS", \ | |
546 | "ADDR_REGS", \ | |
547 | "INDEX_REGS", \ | |
cb0ca284 | 548 | "BK_REG", \ |
d5e4ff48 MH |
549 | "SP_REG", \ |
550 | "RC_REG", \ | |
4a6330ac | 551 | "COUNTER_REGS", \ |
cb0ca284 MH |
552 | "INT_REGS", \ |
553 | "GENERAL_REGS", \ | |
554 | "DP_REG", \ | |
555 | "ST_REG", \ | |
556 | "ALL_REGS" \ | |
d5e4ff48 | 557 | } |
cb0ca284 MH |
558 | |
559 | /* Define which registers fit in which classes. | |
560 | This is an initializer for a vector of HARD_REG_SET | |
2e3e9ead MH |
561 | of length N_REG_CLASSES. RC is not included in GENERAL_REGS |
562 | since the register allocator will often choose a general register | |
563 | in preference to RC for the decrement_and_branch_on_count pattern. */ | |
cb0ca284 MH |
564 | |
565 | #define REG_CLASS_CONTENTS \ | |
566 | { \ | |
975ab131 MH |
567 | {0x00000000}, /* No registers. */ \ |
568 | {0x00000003}, /* 't' R0-R1 . */ \ | |
569 | {0x0000000c}, /* 'u' R2-R3 . */ \ | |
570 | {0x000000ff}, /* 'q' R0-R7 . */ \ | |
2e3e9ead | 571 | {0xf00000ff}, /* 'f' R0-R11 */ \ |
975ab131 MH |
572 | {0x0000ff00}, /* 'a' AR0-AR7. */ \ |
573 | {0x00060000}, /* 'x' IR0-IR1. */ \ | |
574 | {0x00080000}, /* 'k' BK. */ \ | |
575 | {0x00100000}, /* 'b' SP. */ \ | |
576 | {0x08000000}, /* 'v' RC. */ \ | |
577 | {0x0800ff00}, /* RC,AR0-AR7. */ \ | |
578 | {0x0e1eff00}, /* 'c' AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */ \ | |
579 | {0xfe1effff}, /* 'r' R0-R11, AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */\ | |
580 | {0x00010000}, /* 'z' DP. */ \ | |
581 | {0x00200000}, /* 'y' ST. */ \ | |
582 | {0xffffffff}, /* All registers. */ \ | |
cb0ca284 MH |
583 | } |
584 | ||
585 | /* The same information, inverted: | |
586 | Return the class number of the smallest class containing | |
587 | reg number REGNO. This could be a conditional expression | |
588 | or could index an array. */ | |
589 | ||
590 | #define REGNO_REG_CLASS(REGNO) (c4x_regclass_map[REGNO]) | |
591 | ||
2e3e9ead MH |
592 | /* When SMALL_REGISTER_CLASSES is defined, the lifetime of registers |
593 | explicitly used in the rtl is kept as short as possible. | |
594 | ||
595 | We only need to define SMALL_REGISTER_CLASSES if TARGET_PARALLEL_MPY | |
596 | is defined since the MPY|ADD insns require the classes R0R1_REGS and | |
597 | R2R3_REGS which are used by the function return registers (R0,R1) and | |
598 | the register arguments (R2,R3), respectively. I'm reluctant to define | |
f1ba665b | 599 | this macro since it stomps on many potential optimizations. Ideally |
2e3e9ead | 600 | it should have a register class argument so that not all the register |
368ebcd6 | 601 | classes gets penalized for the sake of a naughty few... For long |
2e3e9ead MH |
602 | double arithmetic we need two additional registers that we can use as |
603 | spill registers. */ | |
cb0ca284 MH |
604 | |
605 | #define SMALL_REGISTER_CLASSES (TARGET_SMALL_REG_CLASS && TARGET_PARALLEL_MPY) | |
606 | ||
607 | #define BASE_REG_CLASS ADDR_REGS | |
608 | #define INDEX_REG_CLASS INDEX_REGS | |
609 | ||
610 | /* | |
2e3e9ead | 611 | Register constraints for the C4x |
cb0ca284 MH |
612 | |
613 | a - address reg (ar0-ar7) | |
614 | b - stack reg (sp) | |
615 | c - other gp int-only reg | |
616 | d - data/int reg (equiv. to f) | |
617 | f - data/float reg | |
618 | h - data/long double reg (equiv. to f) | |
619 | k - block count (bk) | |
620 | q - r0-r7 | |
621 | t - r0-r1 | |
622 | u - r2-r3 | |
d5e4ff48 | 623 | v - repeat count (rc) |
cb0ca284 MH |
624 | x - index register (ir0-ir1) |
625 | y - status register (st) | |
626 | z - dp reg (dp) | |
627 | ||
2e3e9ead MH |
628 | Memory/constant constraints for the C4x |
629 | ||
cb0ca284 MH |
630 | G - short float 16-bit |
631 | I - signed 16-bit constant (sign extended) | |
632 | J - signed 8-bit constant (sign extended) (C4x only) | |
633 | K - signed 5-bit constant (sign extended) (C4x only for stik) | |
634 | L - unsigned 16-bit constant | |
635 | M - unsigned 8-bit constant (C4x only) | |
636 | N - ones complement of unsigned 16-bit constant | |
637 | Q - indirect arx + 9-bit signed displacement | |
638 | (a *-arx(n) or *+arx(n) is used to account for the sign bit) | |
639 | R - indirect arx + 5-bit unsigned displacement (C4x only) | |
640 | S - indirect arx + 0, 1, or irn displacement | |
641 | T - direct symbol ref | |
642 | > - indirect with autoincrement | |
643 | < - indirect with autodecrement | |
644 | } - indirect with post-modify | |
645 | { - indirect with pre-modify | |
646 | */ | |
647 | ||
648 | #define REG_CLASS_FROM_LETTER(CC) \ | |
649 | ( ((CC) == 'a') ? ADDR_REGS \ | |
650 | : ((CC) == 'b') ? SP_REG \ | |
651 | : ((CC) == 'c') ? INT_REGS \ | |
652 | : ((CC) == 'd') ? EXT_REGS \ | |
653 | : ((CC) == 'f') ? EXT_REGS \ | |
654 | : ((CC) == 'h') ? EXT_REGS \ | |
655 | : ((CC) == 'k') ? BK_REG \ | |
656 | : ((CC) == 'q') ? EXT_LOW_REGS \ | |
657 | : ((CC) == 't') ? R0R1_REGS \ | |
658 | : ((CC) == 'u') ? R2R3_REGS \ | |
d5e4ff48 | 659 | : ((CC) == 'v') ? RC_REG \ |
cb0ca284 MH |
660 | : ((CC) == 'x') ? INDEX_REGS \ |
661 | : ((CC) == 'y') ? ST_REG \ | |
662 | : ((CC) == 'z') ? DP_REG \ | |
663 | : NO_REGS ) | |
664 | ||
665 | /* These assume that REGNO is a hard or pseudo reg number. | |
666 | They give nonzero only if REGNO is a hard reg of the suitable class | |
667 | or a pseudo reg currently allocated to a suitable hard reg. | |
668 | Since they use reg_renumber, they are safe only once reg_renumber | |
669 | has been allocated, which happens in local-alloc.c. */ | |
670 | ||
671 | #define REGNO_OK_FOR_BASE_P(REGNO) \ | |
bc46716b | 672 | (IS_ADDR_REGNO(REGNO) || IS_ADDR_REGNO((unsigned)reg_renumber[REGNO])) |
cb0ca284 MH |
673 | |
674 | #define REGNO_OK_FOR_INDEX_P(REGNO) \ | |
bc46716b | 675 | (IS_INDEX_REGNO(REGNO) || IS_INDEX_REGNO((unsigned)reg_renumber[REGNO])) |
cb0ca284 | 676 | |
ed3614cd | 677 | /* If we have to generate framepointer + constant prefer an ADDR_REGS |
31113446 | 678 | register. This avoids using EXT_REGS in addqi3_noclobber_reload. */ |
ed3614cd HB |
679 | |
680 | #define PREFERRED_RELOAD_CLASS(X, CLASS) \ | |
681 | (GET_CODE (X) == PLUS \ | |
682 | && GET_MODE (X) == Pmode \ | |
683 | && GET_CODE (XEXP ((X), 0)) == REG \ | |
684 | && GET_MODE (XEXP ((X), 0)) == Pmode \ | |
685 | && REGNO (XEXP ((X), 0)) == FRAME_POINTER_REGNUM \ | |
686 | && GET_CODE (XEXP ((X), 1)) == CONST_INT \ | |
687 | ? ADDR_REGS : (CLASS)) | |
cb0ca284 | 688 | |
798f6e6f | 689 | #define LIMIT_RELOAD_CLASS(X, CLASS) (CLASS) |
cb0ca284 | 690 | |
798f6e6f | 691 | #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) 0 |
cb0ca284 MH |
692 | |
693 | #define CLASS_MAX_NREGS(CLASS, MODE) \ | |
694 | (((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : ((MODE) == HFmode) ? 1 : \ | |
695 | ((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) | |
696 | ||
975ab131 | 697 | #define IS_INT5_CONST(VAL) (((VAL) <= 15) && ((VAL) >= -16)) /* 'K'. */ |
cb0ca284 | 698 | |
975ab131 | 699 | #define IS_UINT5_CONST(VAL) (((VAL) <= 31) && ((VAL) >= 0)) /* 'R'. */ |
cb0ca284 | 700 | |
975ab131 | 701 | #define IS_INT8_CONST(VAL) (((VAL) <= 127) && ((VAL) >= -128)) /* 'J'. */ |
cb0ca284 | 702 | |
975ab131 | 703 | #define IS_UINT8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= 0)) /* 'M'. */ |
cb0ca284 | 704 | |
975ab131 | 705 | #define IS_INT16_CONST(VAL) (((VAL) <= 32767) && ((VAL) >= -32768)) /* 'I'. */ |
cb0ca284 | 706 | |
975ab131 | 707 | #define IS_UINT16_CONST(VAL) (((VAL) <= 65535) && ((VAL) >= 0)) /* 'L'. */ |
cb0ca284 | 708 | |
975ab131 | 709 | #define IS_NOT_UINT16_CONST(VAL) IS_UINT16_CONST(~(VAL)) /* 'N'. */ |
cb0ca284 | 710 | |
975ab131 MH |
711 | #define IS_HIGH_CONST(VAL) \ |
712 | (! TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O'. */ | |
cb0ca284 MH |
713 | |
714 | ||
975ab131 | 715 | #define IS_DISP1_CONST(VAL) (((VAL) <= 1) && ((VAL) >= -1)) /* 'S'. */ |
cb0ca284 | 716 | |
975ab131 | 717 | #define IS_DISP8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= -255)) /* 'Q'. */ |
cb0ca284 MH |
718 | |
719 | #define IS_DISP1_OFF_CONST(VAL) (IS_DISP1_CONST (VAL) \ | |
720 | && IS_DISP1_CONST (VAL + 1)) | |
721 | ||
722 | #define IS_DISP8_OFF_CONST(VAL) (IS_DISP8_CONST (VAL) \ | |
723 | && IS_DISP8_CONST (VAL + 1)) | |
724 | ||
725 | #define CONST_OK_FOR_LETTER_P(VAL, C) \ | |
726 | ( ((C) == 'I') ? (IS_INT16_CONST (VAL)) \ | |
4ddb3ea6 MH |
727 | : ((C) == 'J') ? (! TARGET_C3X && IS_INT8_CONST (VAL)) \ |
728 | : ((C) == 'K') ? (! TARGET_C3X && IS_INT5_CONST (VAL)) \ | |
cb0ca284 | 729 | : ((C) == 'L') ? (IS_UINT16_CONST (VAL)) \ |
4ddb3ea6 | 730 | : ((C) == 'M') ? (! TARGET_C3X && IS_UINT8_CONST (VAL)) \ |
cb0ca284 MH |
731 | : ((C) == 'N') ? (IS_NOT_UINT16_CONST (VAL)) \ |
732 | : ((C) == 'O') ? (IS_HIGH_CONST (VAL)) \ | |
733 | : 0 ) | |
734 | ||
50c33087 | 735 | #define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \ |
798f6e6f | 736 | ( ((C) == 'G') ? (fp_zero_operand (OP, QFmode)) \ |
50c33087 | 737 | : ((C) == 'H') ? (c4x_H_constant (OP)) \ |
cb0ca284 MH |
738 | : 0 ) |
739 | ||
50c33087 MH |
740 | #define EXTRA_CONSTRAINT(OP, C) \ |
741 | ( ((C) == 'Q') ? (c4x_Q_constraint (OP)) \ | |
742 | : ((C) == 'R') ? (c4x_R_constraint (OP)) \ | |
743 | : ((C) == 'S') ? (c4x_S_constraint (OP)) \ | |
744 | : ((C) == 'T') ? (c4x_T_constraint (OP)) \ | |
745 | : ((C) == 'U') ? (c4x_U_constraint (OP)) \ | |
cb0ca284 MH |
746 | : 0 ) |
747 | ||
748 | #define SMALL_CONST(VAL, insn) \ | |
749 | ( ((insn == NULL_RTX) || (get_attr_data (insn) == DATA_INT16)) \ | |
750 | ? IS_INT16_CONST (VAL) \ | |
751 | : ( (get_attr_data (insn) == DATA_NOT_UINT16) \ | |
752 | ? IS_NOT_UINT16_CONST (VAL) \ | |
753 | : ( (get_attr_data (insn) == DATA_HIGH_16) \ | |
754 | ? IS_HIGH_CONST (VAL) \ | |
755 | : IS_UINT16_CONST (VAL) \ | |
756 | ) \ | |
757 | ) \ | |
758 | ) | |
759 | ||
760 | /* | |
761 | I. Routine calling with arguments in registers | |
762 | ---------------------------------------------- | |
763 | ||
764 | The TI C3x compiler has a rather unusual register passing algorithm. | |
765 | Data is passed in the following registers (in order): | |
766 | ||
767 | AR2, R2, R3, RC, RS, RE | |
768 | ||
769 | However, the first and second floating point values are always in R2 | |
770 | and R3 (and all other floats are on the stack). Structs are always | |
771 | passed on the stack. If the last argument is an ellipsis, the | |
772 | previous argument is passed on the stack so that its address can be | |
773 | taken for the stdargs macros. | |
774 | ||
775 | Because of this, we have to pre-scan the list of arguments to figure | |
776 | out what goes where in the list. | |
777 | ||
778 | II. Routine calling with arguments on stack | |
779 | ------------------------------------------- | |
780 | ||
781 | Let the subroutine declared as "foo(arg0, arg1, arg2);" have local | |
782 | variables loc0, loc1, and loc2. After the function prologue has | |
783 | been executed, the stack frame will look like: | |
784 | ||
785 | [stack grows towards increasing addresses] | |
786 | I-------------I | |
787 | 5 I saved reg1 I <= SP points here | |
788 | I-------------I | |
789 | 4 I saved reg0 I | |
790 | I-------------I | |
791 | 3 I loc2 I | |
792 | I-------------I | |
793 | 2 I loc1 I | |
794 | I-------------I | |
795 | 1 I loc0 I | |
796 | I-------------I | |
797 | 0 I old FP I <= FP (AR3) points here | |
798 | I-------------I | |
799 | -1 I return PC I | |
800 | I-------------I | |
801 | -2 I arg0 I | |
802 | I-------------I | |
803 | -3 I arg1 I | |
804 | I-------------I | |
805 | -4 I arg2 I | |
806 | I-------------I | |
807 | ||
808 | All local variables (locn) are accessible by means of +FP(n+1) | |
809 | addressing, where n is the local variable number. | |
810 | ||
811 | All stack arguments (argn) are accessible by means of -FP(n-2). | |
812 | ||
813 | The stack pointer (SP) points to the last register saved in the | |
814 | prologue (regn). | |
815 | ||
816 | Note that a push instruction performs a preincrement of the stack | |
817 | pointer. (STACK_PUSH_CODE == PRE_INC) | |
818 | ||
819 | III. Registers used in function calling convention | |
820 | -------------------------------------------------- | |
821 | ||
822 | Preserved across calls: R4...R5 (only by PUSH, i.e. lower 32 bits) | |
823 | R6...R7 (only by PUSHF, i.e. upper 32 bits) | |
824 | AR3...AR7 | |
825 | ||
826 | (Because of this model, we only assign FP values in R6, R7 and | |
827 | only assign integer values in R4, R5.) | |
828 | ||
829 | These registers are saved at each function entry and restored at | |
830 | the exit. Also it is expected any of these not affected by any | |
831 | call to user-defined (not service) functions. | |
832 | ||
833 | Not preserved across calls: R0...R3 | |
834 | R4...R5 (upper 8 bits) | |
835 | R6...R7 (lower 8 bits) | |
836 | AR0...AR2, IR0, IR1, BK, ST, RS, RE, RC | |
837 | ||
838 | These registers are used arbitrary in a function without being preserved. | |
839 | It is also expected that any of these can be clobbered by any call. | |
840 | ||
841 | Not used by GCC (except for in user "asm" statements): | |
842 | IE (DIE), IF (IIE), IOF (IIF) | |
843 | ||
844 | These registers are never used by GCC for any data, but can be used | |
845 | with "asm" statements. */ | |
846 | ||
847 | #define C4X_ARG0 -2 | |
848 | #define C4X_LOC0 1 | |
849 | ||
975ab131 | 850 | /* Basic Stack Layout. */ |
cb0ca284 MH |
851 | |
852 | /* The stack grows upward, stack frame grows upward, and args grow | |
1ac7a7f5 | 853 | downward. */ |
cb0ca284 MH |
854 | |
855 | #define STARTING_FRAME_OFFSET C4X_LOC0 | |
856 | #define FIRST_PARM_OFFSET(FNDECL) (C4X_ARG0 + 1) | |
857 | #define ARGS_GROW_DOWNWARD | |
858 | #define STACK_POINTER_OFFSET 1 | |
859 | ||
860 | /* Define this if pushing a word on the stack | |
861 | makes the stack pointer a smaller address. */ | |
862 | ||
975ab131 MH |
863 | /* #define STACK_GROWS_DOWNWARD. */ |
864 | /* Like the dsp16xx, i370, i960, and we32k ports. */ | |
cb0ca284 | 865 | |
f62c8a5c | 866 | /* Define this to non-zero if the nominal address of the stack frame |
cb0ca284 MH |
867 | is at the high-address end of the local variables; |
868 | that is, each additional local variable allocated | |
869 | goes at a more negative offset in the frame. */ | |
870 | ||
f62c8a5c | 871 | #define FRAME_GROWS_DOWNWARD 0 |
cb0ca284 MH |
872 | |
873 | ||
975ab131 | 874 | /* Registers That Address the Stack Frame. */ |
cb0ca284 | 875 | |
975ab131 MH |
876 | #define STACK_POINTER_REGNUM SP_REGNO /* SP. */ |
877 | #define FRAME_POINTER_REGNUM AR3_REGNO /* AR3. */ | |
878 | #define ARG_POINTER_REGNUM AR3_REGNO /* AR3. */ | |
879 | #define STATIC_CHAIN_REGNUM AR0_REGNO /* AR0. */ | |
cb0ca284 | 880 | |
975ab131 | 881 | /* Eliminating Frame Pointer and Arg Pointer. */ |
cb0ca284 MH |
882 | |
883 | #define FRAME_POINTER_REQUIRED 0 | |
884 | ||
885 | #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ | |
886 | { \ | |
887 | int regno; \ | |
888 | int offset = 0; \ | |
889 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ | |
4ddb3ea6 | 890 | if (regs_ever_live[regno] && ! call_used_regs[regno]) \ |
cb0ca284 | 891 | offset += TARGET_PRESERVE_FLOAT \ |
0b53f039 | 892 | && IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1; \ |
cb0ca284 MH |
893 | (DEPTH) = -(offset + get_frame_size ()); \ |
894 | } | |
895 | ||
975ab131 | 896 | /* This is a hack... We need to specify a register. */ |
cb0ca284 MH |
897 | #define ELIMINABLE_REGS \ |
898 | {{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }} | |
899 | ||
900 | #define CAN_ELIMINATE(FROM, TO) \ | |
4ddb3ea6 | 901 | (! (((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ |
cb0ca284 MH |
902 | || ((FROM) == FRAME_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))) |
903 | ||
904 | #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ | |
905 | { \ | |
906 | int regno; \ | |
907 | int offset = 0; \ | |
908 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ | |
4ddb3ea6 | 909 | if (regs_ever_live[regno] && ! call_used_regs[regno]) \ |
cb0ca284 | 910 | offset += TARGET_PRESERVE_FLOAT \ |
0b53f039 | 911 | && IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1; \ |
cb0ca284 MH |
912 | (OFFSET) = -(offset + get_frame_size ()); \ |
913 | } | |
914 | ||
915 | ||
975ab131 | 916 | /* Passing Function Arguments on the Stack. */ |
cb0ca284 | 917 | |
fcd8fa8b | 918 | #define PUSH_ARGS 1 |
cb0ca284 | 919 | #define PUSH_ROUNDING(BYTES) (BYTES) |
cb0ca284 MH |
920 | #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 |
921 | ||
975ab131 | 922 | /* The following structure is used by calls.c, function.c, c4x.c. */ |
cb0ca284 MH |
923 | |
924 | typedef struct c4x_args | |
925 | { | |
926 | int floats; | |
927 | int ints; | |
928 | int maxfloats; | |
929 | int maxints; | |
930 | int init; | |
931 | int var; | |
932 | int prototype; | |
933 | int args; | |
934 | } | |
935 | CUMULATIVE_ARGS; | |
936 | ||
0f6937fe | 937 | #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ |
cb0ca284 MH |
938 | (c4x_init_cumulative_args (&CUM, FNTYPE, LIBNAME)) |
939 | ||
cb0ca284 MH |
940 | #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ |
941 | (c4x_function_arg_advance (&CUM, MODE, TYPE, NAMED)) | |
942 | ||
cb0ca284 MH |
943 | #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ |
944 | (c4x_function_arg(&CUM, MODE, TYPE, NAMED)) | |
945 | ||
946 | /* Define the profitability of saving registers around calls. | |
ad3781e1 MH |
947 | We disable caller save to avoid a bug in flow.c (this also affects |
948 | other targets such as m68k). Since we must use stf/sti, | |
949 | the profitability is marginal anyway. */ | |
cb0ca284 | 950 | |
6ee96de6 | 951 | #define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0 |
cb0ca284 | 952 | |
1ac7a7f5 | 953 | /* 1 if N is a possible register number for function argument passing. */ |
cb0ca284 MH |
954 | |
955 | #define FUNCTION_ARG_REGNO_P(REGNO) \ | |
975ab131 MH |
956 | ( ( ((REGNO) == AR2_REGNO) /* AR2. */ \ |
957 | || ((REGNO) == R2_REGNO) /* R2. */ \ | |
958 | || ((REGNO) == R3_REGNO) /* R3. */ \ | |
959 | || ((REGNO) == RC_REGNO) /* RC. */ \ | |
960 | || ((REGNO) == RS_REGNO) /* RS. */ \ | |
961 | || ((REGNO) == RE_REGNO)) /* RE. */ \ | |
cb0ca284 MH |
962 | ? 1 \ |
963 | : 0) | |
964 | ||
975ab131 | 965 | /* How Scalar Function Values Are Returned. */ |
cb0ca284 MH |
966 | |
967 | #define FUNCTION_VALUE(VALTYPE, FUNC) \ | |
a7a2225a | 968 | gen_rtx_REG (TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0. */ |
cb0ca284 MH |
969 | |
970 | #define LIBCALL_VALUE(MODE) \ | |
a7a2225a | 971 | gen_rtx_REG (MODE, R0_REGNO) /* Return in R0. */ |
cb0ca284 MH |
972 | |
973 | #define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO) | |
974 | ||
975ab131 | 975 | /* How Large Values Are Returned. */ |
cb0ca284 MH |
976 | |
977 | #define DEFAULT_PCC_STRUCT_RETURN 0 | |
cb0ca284 | 978 | |
975ab131 | 979 | /* Generating Code for Profiling. */ |
cb0ca284 MH |
980 | |
981 | /* Note that the generated assembly uses the ^ operator to load the 16 | |
ce577467 MH |
982 | MSBs of the address. This is not supported by the TI assembler. |
983 | The FUNCTION profiler needs a function mcount which gets passed | |
984 | a pointer to the LABELNO. */ | |
cb0ca284 MH |
985 | |
986 | #define FUNCTION_PROFILER(FILE, LABELNO) \ | |
4ddb3ea6 | 987 | if (! TARGET_C3X) \ |
cb0ca284 MH |
988 | { \ |
989 | fprintf (FILE, "\tpush\tar2\n"); \ | |
990 | fprintf (FILE, "\tldhi\t^LP%d,ar2\n", (LABELNO)); \ | |
991 | fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO)); \ | |
992 | fprintf (FILE, "\tcall\tmcount\n"); \ | |
993 | fprintf (FILE, "\tpop\tar2\n"); \ | |
994 | } \ | |
995 | else \ | |
996 | { \ | |
997 | fprintf (FILE, "\tpush\tar2\n"); \ | |
998 | fprintf (FILE, "\tldiu\t^LP%d,ar2\n", (LABELNO)); \ | |
999 | fprintf (FILE, "\tlsh\t16,ar2\n"); \ | |
1000 | fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO)); \ | |
1001 | fprintf (FILE, "\tcall\tmcount\n"); \ | |
1002 | fprintf (FILE, "\tpop\tar2\n"); \ | |
1003 | } | |
1004 | ||
cb0ca284 MH |
1005 | /* CC_NOOVmode should be used when the first operand is a PLUS, MINUS, NEG |
1006 | or MULT. | |
1ac7a7f5 | 1007 | CCmode should be used when no special processing is needed. */ |
cb0ca284 MH |
1008 | #define SELECT_CC_MODE(OP,X,Y) \ |
1009 | ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \ | |
1010 | || GET_CODE (X) == NEG || GET_CODE (X) == MULT \ | |
1011 | || GET_MODE (X) == ABS \ | |
1012 | || GET_CODE (Y) == PLUS || GET_CODE (Y) == MINUS \ | |
1013 | || GET_CODE (Y) == NEG || GET_CODE (Y) == MULT \ | |
1014 | || GET_MODE (Y) == ABS) \ | |
1015 | ? CC_NOOVmode : CCmode) | |
1016 | ||
975ab131 | 1017 | /* Addressing Modes. */ |
cb0ca284 | 1018 | |
940da324 JL |
1019 | #define HAVE_POST_INCREMENT 1 |
1020 | #define HAVE_PRE_INCREMENT 1 | |
1021 | #define HAVE_POST_DECREMENT 1 | |
1022 | #define HAVE_PRE_DECREMENT 1 | |
1023 | #define HAVE_PRE_MODIFY_REG 1 | |
1024 | #define HAVE_POST_MODIFY_REG 1 | |
1025 | #define HAVE_PRE_MODIFY_DISP 1 | |
1026 | #define HAVE_POST_MODIFY_DISP 1 | |
cb0ca284 | 1027 | |
4adf744b | 1028 | /* The number of insns that can be packed into a single opcode. */ |
ce577467 | 1029 | #define PACK_INSNS 2 |
4adf744b MH |
1030 | |
1031 | /* Recognize any constant value that is a valid address. | |
1032 | We could allow arbitrary constant addresses in the large memory | |
1033 | model but for the small memory model we can only accept addresses | |
1034 | within the data page. I suppose we could also allow | |
1035 | CONST PLUS SYMBOL_REF. */ | |
cb0ca284 MH |
1036 | #define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == SYMBOL_REF) |
1037 | ||
4adf744b MH |
1038 | /* Maximum number of registers that can appear in a valid memory |
1039 | address. */ | |
cb0ca284 MH |
1040 | #define MAX_REGS_PER_ADDRESS 2 |
1041 | ||
1042 | /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx | |
1043 | and check its validity for a certain class. | |
1044 | We have two alternate definitions for each of them. | |
1045 | The usual definition accepts all pseudo regs; the other rejects | |
1046 | them unless they have been allocated suitable hard regs. | |
1047 | The symbol REG_OK_STRICT causes the latter definition to be used. | |
1048 | ||
1049 | Most source files want to accept pseudo regs in the hope that | |
1050 | they will get allocated to the class that the insn wants them to be in. | |
1051 | Source files for reload pass need to be strict. | |
1052 | After reload, it makes no difference, since pseudo regs have | |
1053 | been eliminated by then. */ | |
1054 | ||
cb0ca284 MH |
1055 | #ifndef REG_OK_STRICT |
1056 | ||
5bdc5878 | 1057 | /* Nonzero if X is a hard or pseudo reg that can be used as a base. */ |
cb0ca284 | 1058 | |
bc46716b | 1059 | #define REG_OK_FOR_BASE_P(X) IS_ADDR_OR_PSEUDO_REG(X) |
cb0ca284 MH |
1060 | |
1061 | /* Nonzero if X is a hard or pseudo reg that can be used as an index. */ | |
1062 | ||
bc46716b | 1063 | #define REG_OK_FOR_INDEX_P(X) IS_INDEX_OR_PSEUDO_REG(X) |
cb0ca284 MH |
1064 | |
1065 | #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ | |
1066 | { \ | |
1e903c61 | 1067 | if (c4x_legitimate_address_p (MODE, X, 0)) \ |
cb0ca284 MH |
1068 | goto ADDR; \ |
1069 | } | |
1070 | ||
1071 | #else | |
1072 | ||
1073 | /* Nonzero if X is a hard reg that can be used as an index. */ | |
1074 | ||
1075 | #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) | |
1076 | ||
1077 | /* Nonzero if X is a hard reg that can be used as a base reg. */ | |
1078 | ||
1079 | #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) | |
1080 | ||
1081 | #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ | |
1082 | { \ | |
1e903c61 | 1083 | if (c4x_legitimate_address_p (MODE, X, 1)) \ |
cb0ca284 MH |
1084 | goto ADDR; \ |
1085 | } | |
1086 | ||
1087 | #endif | |
1088 | ||
cb0ca284 MH |
1089 | #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ |
1090 | { \ | |
1091 | rtx new; \ | |
8f422192 | 1092 | \ |
cb0ca284 MH |
1093 | new = c4x_legitimize_address (X, MODE); \ |
1094 | if (new != NULL_RTX) \ | |
1095 | { \ | |
1096 | (X) = new; \ | |
1097 | goto WIN; \ | |
1098 | } \ | |
1099 | } | |
1100 | ||
31445126 MH |
1101 | #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ |
1102 | { \ | |
eb253d90 HB |
1103 | if (MODE != HImode \ |
1104 | && MODE != HFmode \ | |
1105 | && GET_MODE (X) != HImode \ | |
1106 | && GET_MODE (X) != HFmode \ | |
1107 | && (GET_CODE (X) == CONST \ | |
1108 | || GET_CODE (X) == SYMBOL_REF \ | |
1109 | || GET_CODE (X) == LABEL_REF)) \ | |
1110 | { \ | |
1111 | if (! TARGET_SMALL) \ | |
1112 | { \ | |
1113 | int i; \ | |
12fb52cf | 1114 | (X) = gen_rtx_LO_SUM (GET_MODE (X), \ |
eb253d90 HB |
1115 | gen_rtx_HIGH (GET_MODE (X), X), X); \ |
1116 | i = push_reload (XEXP (X, 0), NULL_RTX, \ | |
df4ae160 | 1117 | &XEXP (X, 0), NULL, \ |
eb253d90 HB |
1118 | DP_REG, GET_MODE (X), VOIDmode, 0, 0, \ |
1119 | OPNUM, TYPE); \ | |
1120 | /* The only valid reg is DP. This is a fixed reg and will \ | |
1121 | normally not be used so force it. */ \ | |
1122 | rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); \ | |
1123 | rld[i].nocombine = 1; \ | |
1124 | } \ | |
12fb52cf MH |
1125 | else \ |
1126 | { \ | |
1127 | /* make_memloc in reload will substitute invalid memory \ | |
1128 | references. We need to fix them up. */ \ | |
1129 | (X) = gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, DP_REGNO), (X)); \ | |
1130 | } \ | |
eb253d90 HB |
1131 | goto WIN; \ |
1132 | } \ | |
1133 | else if (MODE != HImode \ | |
1134 | && MODE != HFmode \ | |
1135 | && GET_MODE (X) != HImode \ | |
1136 | && GET_MODE (X) != HFmode \ | |
1137 | && GET_CODE (X) == LO_SUM \ | |
1138 | && GET_CODE (XEXP (X,0)) == HIGH \ | |
1139 | && (GET_CODE (XEXP (XEXP (X,0),0)) == CONST \ | |
1140 | || GET_CODE (XEXP (XEXP (X,0),0)) == SYMBOL_REF \ | |
1141 | || GET_CODE (XEXP (XEXP (X,0),0)) == LABEL_REF)) \ | |
1142 | { \ | |
1143 | if (! TARGET_SMALL) \ | |
1144 | { \ | |
1145 | int i = push_reload (XEXP (X, 0), NULL_RTX, \ | |
df4ae160 | 1146 | &XEXP (X, 0), NULL, \ |
eb253d90 HB |
1147 | DP_REG, GET_MODE (X), VOIDmode, 0, 0, \ |
1148 | OPNUM, TYPE); \ | |
1149 | /* The only valid reg is DP. This is a fixed reg and will \ | |
1150 | normally not be used so force it. */ \ | |
1151 | rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); \ | |
1152 | rld[i].nocombine = 1; \ | |
1153 | } \ | |
1154 | goto WIN; \ | |
1155 | } \ | |
31445126 MH |
1156 | } |
1157 | ||
cb0ca284 MH |
1158 | /* No mode-dependent addresses on the C4x are autoincrements. */ |
1159 | ||
1160 | #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ | |
1161 | if (GET_CODE (ADDR) == PRE_DEC \ | |
1162 | || GET_CODE (ADDR) == POST_DEC \ | |
1163 | || GET_CODE (ADDR) == PRE_INC \ | |
1164 | || GET_CODE (ADDR) == POST_INC \ | |
1165 | || GET_CODE (ADDR) == POST_MODIFY \ | |
1166 | || GET_CODE (ADDR) == PRE_MODIFY) \ | |
1167 | goto LABEL | |
1168 | ||
1169 | ||
1170 | /* Nonzero if the constant value X is a legitimate general operand. | |
1171 | It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. | |
1172 | ||
50c33087 MH |
1173 | The C4x can only load 16-bit immediate values, so we only allow a |
1174 | restricted subset of CONST_INT and CONST_DOUBLE. Disallow | |
1175 | LABEL_REF and SYMBOL_REF (except on the C40 with the big memory | |
1176 | model) so that the symbols will be forced into the constant pool. | |
31445126 MH |
1177 | On second thoughts, let's do this with the move expanders since |
1178 | the alias analysis has trouble if we force constant addresses | |
1179 | into memory. | |
50c33087 | 1180 | */ |
cb0ca284 MH |
1181 | |
1182 | #define LEGITIMATE_CONSTANT_P(X) \ | |
d5e4ff48 | 1183 | ((GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X)) \ |
483dd5be | 1184 | || (GET_CODE (X) == CONST_INT) \ |
50c33087 MH |
1185 | || (GET_CODE (X) == SYMBOL_REF) \ |
1186 | || (GET_CODE (X) == LABEL_REF) \ | |
1187 | || (GET_CODE (X) == CONST) \ | |
1188 | || (GET_CODE (X) == HIGH && ! TARGET_C3X) \ | |
1189 | || (GET_CODE (X) == LO_SUM && ! TARGET_C3X)) | |
cb0ca284 MH |
1190 | |
1191 | #define LEGITIMATE_DISPLACEMENT_P(X) IS_DISP8_CONST (INTVAL (X)) | |
1192 | ||
112cdef5 | 1193 | /* Describing Relative Cost of Operations. */ |
cb0ca284 | 1194 | |
cb0ca284 MH |
1195 | #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \ |
1196 | if (REG_P (OP1) && ! REG_P (OP0)) \ | |
1197 | { \ | |
1198 | rtx tmp = OP0; OP0 = OP1 ; OP1 = tmp; \ | |
1199 | CODE = swap_condition (CODE); \ | |
1200 | } | |
1201 | ||
1202 | #define EXT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, EXT_REGS)) | |
1203 | #define ADDR_CLASS_P(CLASS) (reg_class_subset_p (CLASS, ADDR_REGS)) | |
1204 | #define INDEX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, INDEX_REGS)) | |
1205 | #define EXPENSIVE_CLASS_P(CLASS) (ADDR_CLASS_P(CLASS) \ | |
1206 | || INDEX_CLASS_P(CLASS) || (CLASS) == SP_REG) | |
1207 | ||
5e6a42d9 MH |
1208 | /* Compute extra cost of moving data between one register class |
1209 | and another. */ | |
cb0ca284 | 1210 | |
cf011243 | 1211 | #define REGISTER_MOVE_COST(MODE, FROM, TO) 2 |
cb0ca284 MH |
1212 | |
1213 | /* Memory move cost is same as fast register move. Maybe this should | |
975ab131 | 1214 | be bumped up?. */ |
cb0ca284 MH |
1215 | |
1216 | #define MEMORY_MOVE_COST(M,C,I) 4 | |
1217 | ||
1218 | /* Branches are kind of expensive (even with delayed branching) so | |
1219 | make their cost higher. */ | |
1220 | ||
1221 | #define BRANCH_COST 8 | |
1222 | ||
cb0ca284 MH |
1223 | #define WORD_REGISTER_OPERATIONS |
1224 | ||
1ac7a7f5 | 1225 | /* Dividing the Output into Sections. */ |
cb0ca284 MH |
1226 | |
1227 | #define TEXT_SECTION_ASM_OP "\t.text" | |
1228 | ||
1229 | #define DATA_SECTION_ASM_OP "\t.data" | |
1230 | ||
d48bc59a | 1231 | #define READONLY_DATA_SECTION_ASM_OP "\t.sect\t\".const\"" |
cb0ca284 MH |
1232 | |
1233 | /* Do not use .init section so __main will be called on startup. This will | |
1ac7a7f5 | 1234 | call __do_global_ctors and prepare for __do_global_dtors on exit. */ |
cb0ca284 MH |
1235 | |
1236 | #if 0 | |
1237 | #define INIT_SECTION_ASM_OP "\t.sect\t\".init\"" | |
1238 | #endif | |
1239 | ||
1240 | #define FINI_SECTION_ASM_OP "\t.sect\t\".fini\"" | |
1241 | ||
cb0ca284 | 1242 | #undef EXTRA_SECTIONS |
d48bc59a | 1243 | #define EXTRA_SECTIONS in_init, in_fini |
cb0ca284 MH |
1244 | |
1245 | #undef EXTRA_SECTION_FUNCTIONS | |
1246 | #define EXTRA_SECTION_FUNCTIONS \ | |
cb0ca284 | 1247 | INIT_SECTION_FUNCTION \ |
2cc07db4 | 1248 | FINI_SECTION_FUNCTION |
cb0ca284 MH |
1249 | |
1250 | #define INIT_SECTION_FUNCTION \ | |
f12b3fc8 | 1251 | extern void init_section (void); \ |
cb0ca284 | 1252 | void \ |
f12b3fc8 | 1253 | init_section (void) \ |
cb0ca284 MH |
1254 | { \ |
1255 | if (in_section != in_init) \ | |
1256 | { \ | |
1257 | fprintf (asm_out_file, ";\t.init\n"); \ | |
1258 | in_section = in_init; \ | |
1259 | } \ | |
1260 | } | |
1261 | ||
1262 | #define FINI_SECTION_FUNCTION \ | |
1263 | void \ | |
1264 | fini_section () \ | |
1265 | { \ | |
1266 | if (in_section != in_fini) \ | |
1267 | { \ | |
8802136f | 1268 | fprintf (asm_out_file, "%s\n", FINI_SECTION_ASM_OP); \ |
cb0ca284 MH |
1269 | in_section = in_fini; \ |
1270 | } \ | |
1271 | } | |
1272 | ||
7c262518 RH |
1273 | /* Switch into a generic section. */ |
1274 | #define TARGET_ASM_NAMED_SECTION c4x_asm_named_section | |
cb0ca284 | 1275 | |
dfafcb4d | 1276 | |
975ab131 | 1277 | /* Overall Framework of an Assembler File. */ |
cb0ca284 | 1278 | |
31445126 | 1279 | #define ASM_COMMENT_START ";" |
cb0ca284 MH |
1280 | |
1281 | #define ASM_APP_ON "" | |
1282 | #define ASM_APP_OFF "" | |
1283 | ||
cb0ca284 MH |
1284 | #define ASM_OUTPUT_ASCII(FILE, PTR, LEN) c4x_output_ascii (FILE, PTR, LEN) |
1285 | ||
975ab131 | 1286 | /* Output and Generation of Labels. */ |
cb0ca284 | 1287 | |
975ab131 | 1288 | #define NO_DOT_IN_LABEL /* Only required for TI format. */ |
cb0ca284 | 1289 | |
5eb99654 KG |
1290 | /* Globalizing directive for a label. */ |
1291 | #define GLOBAL_ASM_OP "\t.global\t" | |
cb0ca284 | 1292 | |
eff784fe MH |
1293 | #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ |
1294 | c4x_external_ref (NAME) | |
cb0ca284 | 1295 | |
cb0ca284 MH |
1296 | /* The prefix to add to user-visible assembler symbols. */ |
1297 | ||
1298 | #define USER_LABEL_PREFIX "_" | |
1299 | ||
cb0ca284 MH |
1300 | /* This is how to store into the string LABEL |
1301 | the symbol_ref name of an internal numbered label where | |
1302 | PREFIX is the class of label and NUM is the number within the class. | |
1303 | This is suitable for output with `assemble_name'. */ | |
1304 | ||
1305 | #define ASM_GENERATE_INTERNAL_LABEL(BUFFER, PREFIX, NUM) \ | |
74eda121 | 1306 | sprintf (BUFFER, "*%s%lu", PREFIX, (unsigned long)(NUM)) |
cb0ca284 | 1307 | |
8e0ed3b5 HB |
1308 | /* A C statement to output to the stdio stream STREAM assembler code which |
1309 | defines (equates) the symbol NAME to have the value VALUE. */ | |
1310 | ||
1311 | #define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) \ | |
1312 | do { \ | |
1313 | assemble_name (STREAM, NAME); \ | |
1314 | fprintf (STREAM, "\t.set\t%s\n", VALUE); \ | |
1315 | } while (0) | |
cb0ca284 | 1316 | |
975ab131 | 1317 | /* Output of Dispatch Tables. */ |
cb0ca284 MH |
1318 | |
1319 | /* This is how to output an element of a case-vector that is absolute. */ | |
1320 | ||
1321 | #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ | |
1322 | fprintf (FILE, "\t.long\tL%d\n", VALUE); | |
1323 | ||
1324 | /* This is how to output an element of a case-vector that is relative. */ | |
1325 | ||
1326 | #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ | |
1327 | fprintf (FILE, "\t.long\tL%d-L%d\n", VALUE, REL); | |
1328 | ||
1329 | #undef SIZE_TYPE | |
1330 | #define SIZE_TYPE "unsigned int" | |
1331 | ||
1332 | #undef PTRDIFF_TYPE | |
1333 | #define PTRDIFF_TYPE "int" | |
1334 | ||
1335 | #undef WCHAR_TYPE | |
1336 | #define WCHAR_TYPE "long int" | |
1337 | ||
1338 | #undef WCHAR_TYPE_SIZE | |
1339 | #define WCHAR_TYPE_SIZE 32 | |
1340 | ||
1341 | #define INT_TYPE_SIZE 32 | |
1342 | #define LONG_LONG_TYPE_SIZE 64 | |
1343 | #define FLOAT_TYPE_SIZE 32 | |
1344 | #define DOUBLE_TYPE_SIZE 32 | |
975ab131 | 1345 | #define LONG_DOUBLE_TYPE_SIZE 64 /* Actually only 40. */ |
cb0ca284 | 1346 | |
cb0ca284 MH |
1347 | /* Output #ident as a .ident. */ |
1348 | ||
1349 | #define ASM_OUTPUT_IDENT(FILE, NAME) \ | |
1350 | fprintf (FILE, "\t.ident \"%s\"\n", NAME); | |
1351 | ||
975ab131 | 1352 | /* Output of Uninitialized Variables. */ |
31445126 MH |
1353 | |
1354 | /* This says how to output an assembler line to define a local | |
1355 | uninitialized variable. */ | |
cb0ca284 MH |
1356 | |
1357 | #undef ASM_OUTPUT_LOCAL | |
1358 | #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ | |
1359 | ( fputs ("\t.bss\t", FILE), \ | |
1360 | assemble_name (FILE, (NAME)), \ | |
58e15542 | 1361 | fprintf (FILE, ",%u\n", (int)(ROUNDED))) |
cb0ca284 | 1362 | |
31445126 MH |
1363 | /* This says how to output an assembler line to define a global |
1364 | uninitialized variable. */ | |
cb0ca284 MH |
1365 | |
1366 | #undef ASM_OUTPUT_COMMON | |
1367 | #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ | |
1368 | ( fputs ("\t.globl\t", FILE), \ | |
1369 | assemble_name (FILE, (NAME)), \ | |
1370 | fputs ("\n\t.bss\t", FILE), \ | |
1371 | assemble_name (FILE, (NAME)), \ | |
58e15542 | 1372 | fprintf (FILE, ",%u\n", (int)(ROUNDED))) |
cb0ca284 | 1373 | |
7bea4e7a MH |
1374 | #undef ASM_OUTPUT_BSS |
1375 | #define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ | |
1376 | ( fputs ("\t.globl\t", FILE), \ | |
1377 | assemble_name (FILE, (NAME)), \ | |
1378 | fputs ("\n\t.bss\t", FILE), \ | |
1379 | assemble_name (FILE, (NAME)), \ | |
58e15542 | 1380 | fprintf (FILE, ",%u\n", (int)(SIZE))) |
7bea4e7a | 1381 | |
975ab131 | 1382 | /* Macros Controlling Initialization Routines. */ |
cb0ca284 MH |
1383 | |
1384 | #define OBJECT_FORMAT_COFF | |
1385 | #define REAL_NM_FILE_NAME "c4x-nm" | |
1386 | ||
975ab131 | 1387 | /* Output of Assembler Instructions. */ |
cb0ca284 MH |
1388 | |
1389 | /* Register names when used for integer modes. */ | |
1390 | ||
1391 | #define REGISTER_NAMES \ | |
1392 | { \ | |
1393 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ | |
1394 | "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", \ | |
1395 | "dp", "ir0", "ir1", "bk", "sp", "st", "die", "iie", \ | |
1396 | "iif", "rs", "re", "rc", "r8", "r9", "r10", "r11" \ | |
1397 | } | |
1398 | ||
1399 | /* Alternate register names when used for floating point modes. */ | |
1400 | ||
1401 | #define FLOAT_REGISTER_NAMES \ | |
1402 | { \ | |
1403 | "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ | |
1404 | "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", \ | |
1405 | "dp", "ir0", "ir1", "bk", "sp", "st", "die", "iie", \ | |
1406 | "iif", "rs", "re", "rc", "f8", "f9", "f10", "f11" \ | |
1407 | } | |
1408 | ||
cb0ca284 MH |
1409 | #define PRINT_OPERAND(FILE, X, CODE) c4x_print_operand(FILE, X, CODE) |
1410 | ||
1411 | /* Determine which codes are valid without a following integer. These must | |
1ac7a7f5 | 1412 | not be alphabetic. */ |
cb0ca284 MH |
1413 | |
1414 | #define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '#') | |
1415 | ||
cb0ca284 MH |
1416 | #define PRINT_OPERAND_ADDRESS(FILE, X) c4x_print_operand_address(FILE, X) |
1417 | ||
8b97c5f8 | 1418 | /* C4x specific pragmas. */ |
c58b209a NB |
1419 | #define REGISTER_TARGET_PRAGMAS() do { \ |
1420 | c_register_pragma (0, "CODE_SECTION", c4x_pr_CODE_SECTION); \ | |
1421 | c_register_pragma (0, "DATA_SECTION", c4x_pr_DATA_SECTION); \ | |
1422 | c_register_pragma (0, "FUNC_CANNOT_INLINE", c4x_pr_ignored); \ | |
1423 | c_register_pragma (0, "FUNC_EXT_CALLED", c4x_pr_ignored); \ | |
1424 | c_register_pragma (0, "FUNC_IS_PURE", c4x_pr_FUNC_IS_PURE); \ | |
1425 | c_register_pragma (0, "FUNC_IS_SYSTEM", c4x_pr_ignored); \ | |
1426 | c_register_pragma (0, "FUNC_NEVER_RETURNS", c4x_pr_FUNC_NEVER_RETURNS); \ | |
1427 | c_register_pragma (0, "FUNC_NO_GLOBAL_ASG", c4x_pr_ignored); \ | |
1428 | c_register_pragma (0, "FUNC_NO_IND_ASG", c4x_pr_ignored); \ | |
1429 | c_register_pragma (0, "INTERRUPT", c4x_pr_INTERRUPT); \ | |
8b97c5f8 | 1430 | } while (0) |
cb0ca284 | 1431 | |
975ab131 | 1432 | /* Assembler Commands for Alignment. */ |
cb0ca284 MH |
1433 | |
1434 | #define ASM_OUTPUT_SKIP(FILE, SIZE) \ | |
1435 | { int c = SIZE; \ | |
1436 | for (; c > 0; --c) \ | |
1437 | fprintf (FILE,"\t.word\t0\n"); \ | |
1438 | } | |
1439 | ||
1440 | #define ASM_NO_SKIP_IN_TEXT 1 | |
1441 | ||
1ac7a7f5 | 1442 | /* I'm not sure about this one. FIXME. */ |
cb0ca284 MH |
1443 | |
1444 | #define ASM_OUTPUT_ALIGN(FILE, LOG) \ | |
1445 | if ((LOG) != 0) \ | |
1446 | fprintf (FILE, "\t.align\t%d\n", (1 << (LOG))) | |
1447 | ||
1448 | ||
1449 | /* Macros for SDB and DWARF Output (use .sdef instead of .def | |
975ab131 | 1450 | to avoid conflict with TI's use of .def). */ |
cb0ca284 MH |
1451 | |
1452 | #define SDB_DELIM "\n" | |
23532de9 | 1453 | #define SDB_DEBUGGING_INFO 1 |
cb0ca284 | 1454 | |
db14c6a0 MH |
1455 | /* Don't use octal since this can confuse gas for the c4x. */ |
1456 | #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0x%x%s", a, SDB_DELIM) | |
1457 | ||
cb0ca284 MH |
1458 | #define PUT_SDB_DEF(A) \ |
1459 | do { fprintf (asm_out_file, "\t.sdef\t"); \ | |
1460 | ASM_OUTPUT_LABELREF (asm_out_file, A); \ | |
1461 | fprintf (asm_out_file, SDB_DELIM); } while (0) | |
1462 | ||
1463 | #define PUT_SDB_PLAIN_DEF(A) \ | |
1464 | fprintf (asm_out_file,"\t.sdef\t.%s%s", A, SDB_DELIM) | |
1465 | ||
1466 | #define PUT_SDB_BLOCK_START(LINE) \ | |
1467 | fprintf (asm_out_file, \ | |
1468 | "\t.sdef\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ | |
1469 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
1470 | ||
1471 | #define PUT_SDB_BLOCK_END(LINE) \ | |
1472 | fprintf (asm_out_file, \ | |
1473 | "\t.sdef\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ | |
1474 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
1475 | ||
1476 | #define PUT_SDB_FUNCTION_START(LINE) \ | |
1477 | fprintf (asm_out_file, \ | |
1478 | "\t.sdef\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ | |
1479 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
1480 | ||
01dc05dd MH |
1481 | /* Note we output relative line numbers for .ef which gas converts |
1482 | to absolute line numbers. The TI compiler outputs absolute line numbers | |
1483 | in the .sym directive which gas does not support. */ | |
cb0ca284 MH |
1484 | #define PUT_SDB_FUNCTION_END(LINE) \ |
1485 | fprintf (asm_out_file, \ | |
1486 | "\t.sdef\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ | |
01dc05dd MH |
1487 | SDB_DELIM, SDB_DELIM, SDB_DELIM, \ |
1488 | (LINE), SDB_DELIM) | |
cb0ca284 MH |
1489 | |
1490 | #define PUT_SDB_EPILOGUE_END(NAME) \ | |
1491 | do { fprintf (asm_out_file, "\t.sdef\t"); \ | |
1492 | ASM_OUTPUT_LABELREF (asm_out_file, NAME); \ | |
1493 | fprintf (asm_out_file, \ | |
1494 | "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \ | |
1495 | SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0) | |
1496 | ||
cb0ca284 MH |
1497 | /* Define this as 1 if `char' should by default be signed; else as 0. */ |
1498 | ||
1499 | #define DEFAULT_SIGNED_CHAR 1 | |
1500 | ||
1501 | /* A function address in a call instruction is a byte address (for | |
1502 | indexing purposes) so give the MEM rtx a byte's mode. */ | |
1503 | ||
1504 | #define FUNCTION_MODE QImode | |
1505 | ||
1506 | #define SLOW_BYTE_ACCESS 0 | |
1507 | ||
1508 | /* Specify the machine mode that pointers have. After generation of | |
1509 | RTL, the compiler makes no further distinction between pointers and | |
1510 | any other objects of this machine mode. */ | |
1511 | ||
1512 | #define Pmode QImode | |
1513 | ||
1514 | /* On the C4x we can write the following code. We have to clear the cache | |
1515 | every time we execute it because the data in the stack could change. | |
1516 | ||
1517 | laj $+4 | |
1518 | addi3 4,r11,ar0 | |
1519 | lda *ar0,ar1 | |
1520 | lda *+ar0(1),ar0 | |
1521 | bud ar1 | |
1522 | nop | |
1523 | nop | |
1524 | or 1000h,st | |
1525 | .word FNADDR | |
1526 | .word CXT | |
1527 | ||
1528 | On the c3x this is a bit more difficult. We have to write self | |
1529 | modifying code here. So we have to clear the cache every time | |
1530 | we execute it because the data in the stack could change. | |
1531 | ||
1532 | ldiu TOP_OF_FUNCTION,ar1 | |
1533 | lsh 16,ar1 | |
1534 | or BOTTOM_OF_FUNCTION,ar1 | |
1535 | ldiu TOP_OF_STATIC,ar0 | |
1536 | bud ar1 | |
1537 | lsh 16,ar0 | |
1538 | or BOTTOM_OF_STATIC,ar0 | |
1539 | or 1000h,st | |
1540 | ||
1541 | */ | |
1542 | ||
1543 | #define TRAMPOLINE_SIZE (TARGET_C3X ? 8 : 10) | |
1544 | ||
1545 | #define TRAMPOLINE_TEMPLATE(FILE) \ | |
1546 | { \ | |
1547 | if (TARGET_C3X) \ | |
1548 | { \ | |
761c70aa KG |
1549 | fprintf (FILE, "\tldiu\t0,ar1\n"); \ |
1550 | fprintf (FILE, "\tlsh\t16,ar1\n"); \ | |
1551 | fprintf (FILE, "\tor\t0,ar1\n"); \ | |
1552 | fprintf (FILE, "\tldiu\t0,ar0\n"); \ | |
1553 | fprintf (FILE, "\tbud\tar1\n"); \ | |
1554 | fprintf (FILE, "\tlsh\t16,ar0\n"); \ | |
1555 | fprintf (FILE, "\tor\t0,ar0\n"); \ | |
1556 | fprintf (FILE, "\tor\t1000h,st\n"); \ | |
cb0ca284 MH |
1557 | } \ |
1558 | else \ | |
1559 | { \ | |
761c70aa KG |
1560 | fprintf (FILE, "\tlaj\t$+4\n"); \ |
1561 | fprintf (FILE, "\taddi3\t4,r11,ar0\n"); \ | |
1562 | fprintf (FILE, "\tlda\t*ar0,ar1\n"); \ | |
1563 | fprintf (FILE, "\tlda\t*+ar0(1),ar0\n"); \ | |
1564 | fprintf (FILE, "\tbud\tar1\n"); \ | |
1565 | fprintf (FILE, "\tnop\n"); \ | |
1566 | fprintf (FILE, "\tnop\n"); \ | |
1567 | fprintf (FILE, "\tor\t1000h,st\n"); \ | |
1568 | fprintf (FILE, "\t.word\t0\n"); \ | |
1569 | fprintf (FILE, "\t.word\t0\n"); \ | |
cb0ca284 MH |
1570 | } \ |
1571 | } | |
1572 | ||
1573 | #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ | |
1574 | { \ | |
1575 | if (TARGET_C3X) \ | |
1576 | { \ | |
1577 | rtx tmp1, tmp2; \ | |
1578 | tmp1 = expand_shift (RSHIFT_EXPR, QImode, FNADDR, \ | |
1579 | size_int (16), 0, 1); \ | |
1580 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ | |
22273300 | 1581 | GEN_INT (0x5069), size_int (16), 0, 1); \ |
cb0ca284 | 1582 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
f1c25d3b | 1583 | emit_move_insn (gen_rtx_MEM (QImode, \ |
db7b4701 | 1584 | plus_constant (TRAMP, 0)), tmp1); \ |
22273300 | 1585 | tmp1 = expand_and (QImode, FNADDR, GEN_INT (0xffff), 0); \ |
cb0ca284 | 1586 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ |
22273300 | 1587 | GEN_INT (0x1069), size_int (16), 0, 1); \ |
cb0ca284 | 1588 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
f1c25d3b | 1589 | emit_move_insn (gen_rtx_MEM (QImode, \ |
db7b4701 | 1590 | plus_constant (TRAMP, 2)), tmp1); \ |
cb0ca284 MH |
1591 | tmp1 = expand_shift (RSHIFT_EXPR, QImode, CXT, \ |
1592 | size_int (16), 0, 1); \ | |
1593 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ | |
22273300 | 1594 | GEN_INT (0x5068), size_int (16), 0, 1); \ |
cb0ca284 | 1595 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
f1c25d3b | 1596 | emit_move_insn (gen_rtx_MEM (QImode, \ |
db7b4701 | 1597 | plus_constant (TRAMP, 3)), tmp1); \ |
22273300 | 1598 | tmp1 = expand_and (QImode, CXT, GEN_INT (0xffff), 0); \ |
cb0ca284 | 1599 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ |
22273300 | 1600 | GEN_INT (0x1068), size_int (16), 0, 1); \ |
cb0ca284 | 1601 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
f1c25d3b | 1602 | emit_move_insn (gen_rtx_MEM (QImode, \ |
db7b4701 | 1603 | plus_constant (TRAMP, 6)), tmp1); \ |
cb0ca284 MH |
1604 | } \ |
1605 | else \ | |
1606 | { \ | |
f1c25d3b | 1607 | emit_move_insn (gen_rtx_MEM (QImode, \ |
cb0ca284 | 1608 | plus_constant (TRAMP, 8)), FNADDR); \ |
f1c25d3b | 1609 | emit_move_insn (gen_rtx_MEM (QImode, \ |
cb0ca284 MH |
1610 | plus_constant (TRAMP, 9)), CXT); \ |
1611 | } \ | |
1612 | } | |
1613 | ||
1614 | /* Specify the machine mode that this machine uses for the index in | |
1615 | the tablejump instruction. */ | |
1616 | ||
1617 | #define CASE_VECTOR_MODE Pmode | |
1618 | ||
1619 | /* Max number of (32-bit) bytes we can move from memory to memory | |
1620 | in one reasonably fast instruction. */ | |
1621 | ||
1622 | #define MOVE_MAX 1 | |
1623 | ||
1624 | /* MOVE_RATIO is the number of move instructions that is better than a | |
1ac7a7f5 | 1625 | block move. */ |
cb0ca284 | 1626 | |
8a119a7d | 1627 | #define MOVE_RATIO 3 |
cb0ca284 | 1628 | |
4e8aa65c | 1629 | #define BSS_SECTION_ASM_OP "\t.bss" |
cb0ca284 MH |
1630 | |
1631 | #define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ | |
761c70aa | 1632 | fprintf (FILE, "\tpush\t%s\n", reg_names[REGNO]) |
cb0ca284 MH |
1633 | |
1634 | /* This is how to output an insn to pop a register from the stack. | |
1635 | It need not be very fast code. */ | |
1636 | ||
1637 | #define ASM_OUTPUT_REG_POP(FILE, REGNO) \ | |
761c70aa | 1638 | fprintf (FILE, "\tpop\t%s\n", reg_names[REGNO]) |
cb0ca284 MH |
1639 | |
1640 | /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits | |
1641 | is done just by pretending it is already truncated. */ | |
1642 | ||
1643 | #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 | |
1644 | ||
8a119a7d MH |
1645 | #define DBR_OUTPUT_SEQEND(FILE) \ |
1646 | if (final_sequence != NULL_RTX) \ | |
1647 | { \ | |
1648 | int count; \ | |
1649 | rtx insn = XVECEXP (final_sequence, 0, 0); \ | |
1650 | int laj = GET_CODE (insn) == CALL_INSN \ | |
1651 | || (GET_CODE (insn) == INSN \ | |
1652 | && GET_CODE (PATTERN (insn)) == TRAP_IF);\ | |
1653 | \ | |
1654 | count = dbr_sequence_length(); \ | |
1655 | while (count < (laj ? 2 : 3)) \ | |
1656 | { \ | |
1657 | fputs("\tnop\n", FILE); \ | |
1658 | count++; \ | |
1659 | } \ | |
1660 | if (laj) \ | |
1661 | fputs("\tpush\tr11\n", FILE); \ | |
cb0ca284 MH |
1662 | } |
1663 | ||
1664 | #define NO_FUNCTION_CSE | |
1665 | ||
cb0ca284 MH |
1666 | /* We don't want a leading tab. */ |
1667 | ||
1668 | #define ASM_OUTPUT_ASM(FILE, STRING) fprintf (FILE, "%s\n", STRING) | |
1669 | ||
1670 | /* Define the codes that are matched by predicates in c4x.c. */ | |
1671 | ||
1672 | #define PREDICATE_CODES \ | |
1673 | {"fp_zero_operand", {CONST_DOUBLE}}, \ | |
1674 | {"const_operand", {CONST_INT, CONST_DOUBLE}}, \ | |
1675 | {"stik_const_operand", {CONST_INT}}, \ | |
1676 | {"not_const_operand", {CONST_INT}}, \ | |
1677 | {"reg_operand", {REG, SUBREG}}, \ | |
1678 | {"reg_or_const_operand", {REG, SUBREG, CONST_INT, CONST_DOUBLE}},\ | |
1679 | {"r0r1_reg_operand", {REG, SUBREG}}, \ | |
1680 | {"r2r3_reg_operand", {REG, SUBREG}}, \ | |
1681 | {"ext_low_reg_operand", {REG, SUBREG}}, \ | |
1682 | {"ext_reg_operand", {REG, SUBREG}}, \ | |
1683 | {"std_reg_operand", {REG, SUBREG}}, \ | |
ed3614cd | 1684 | {"std_or_reg_operand", {REG, SUBREG}}, \ |
cb0ca284 MH |
1685 | {"addr_reg_operand", {REG, SUBREG}}, \ |
1686 | {"index_reg_operand", {REG, SUBREG}}, \ | |
1687 | {"dp_reg_operand", {REG}}, \ | |
1688 | {"sp_reg_operand", {REG}}, \ | |
1689 | {"st_reg_operand", {REG}}, \ | |
d5e4ff48 | 1690 | {"rc_reg_operand", {REG}}, \ |
55310df7 | 1691 | {"call_address_operand", {REG, SYMBOL_REF, LABEL_REF, CONST}}, \ |
f416f18c | 1692 | {"dst_operand", {SUBREG, REG, MEM}}, \ |
cb0ca284 MH |
1693 | {"src_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ |
1694 | {"src_hi_operand", {SUBREG, REG, MEM, CONST_DOUBLE}}, \ | |
1695 | {"lsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ | |
1696 | {"tsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ | |
65f2f288 HB |
1697 | {"nonimmediate_src_operand", {SUBREG, REG, MEM}}, \ |
1698 | {"nonimmediate_lsrc_operand", {SUBREG, REG, MEM}}, \ | |
cb0ca284 MH |
1699 | {"any_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ |
1700 | {"par_ind_operand", {MEM}}, \ | |
1701 | {"parallel_operand", {SUBREG, REG, MEM}}, \ | |
e79df5ce | 1702 | {"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}}, |
8a119a7d MH |
1703 | |
1704 | ||
1705 | /* Define the intrinsic functions for the c3x/c4x. */ | |
1706 | ||
1707 | enum c4x_builtins | |
1708 | { | |
1709 | /* intrinsic name */ | |
8a119a7d MH |
1710 | C4X_BUILTIN_FIX, /* fast_ftoi */ |
1711 | C4X_BUILTIN_FIX_ANSI, /* ansi_ftoi */ | |
1712 | C4X_BUILTIN_MPYI, /* fast_imult (only C3x) */ | |
1713 | C4X_BUILTIN_TOIEEE, /* toieee (only C4x) */ | |
1714 | C4X_BUILTIN_FRIEEE, /* frieee (only C4x) */ | |
1715 | C4X_BUILTIN_RCPF /* fast_invf (only C4x) */ | |
1716 | }; | |
8f422192 MH |
1717 | |
1718 | ||
1719 | /* Hack to overcome use of libgcc2.c using auto-host.h to determine | |
1720 | HAVE_GAS_HIDDEN. */ | |
1721 | #undef HAVE_GAS_HIDDEN |