]>
Commit | Line | Data |
---|---|---|
cb0ca284 | 1 | /* Definitions of target machine for GNU compiler. TMS320C[34]x |
ae1f640f | 2 | Copyright (C) 1994, 1995, 1996, 1997, 1998, |
16c484c7 | 3 | 1999, 2000, 2001, 2002 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 | ||
8 | This file is part of GNU CC. | |
9 | ||
10 | GNU CC is free software; you can redistribute it and/or modify | |
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 | ||
15 | GNU CC is distributed in the hope that it will be useful, | |
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 | |
21 | along with GNU CC; see the file COPYING. If not, write to | |
22 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
23 | Boston, MA 02111-1307, USA. */ | |
24 | ||
dfafcb4d HB |
25 | #include "hwint.h" |
26 | ||
975ab131 | 27 | /* RUN-TIME TARGET SPECIFICATION. */ |
cb0ca284 MH |
28 | |
29 | #define C4x 1 | |
30 | ||
975ab131 | 31 | /* Name of the c4x assembler. */ |
cb0ca284 MH |
32 | |
33 | #define ASM_PROG "c4x-as" | |
34 | ||
975ab131 | 35 | /* Name of the c4x linker. */ |
cb0ca284 MH |
36 | |
37 | #define LD_PROG "c4x-ld" | |
38 | ||
ad69db4a | 39 | /* Define assembler options. */ |
cb0ca284 MH |
40 | |
41 | #define ASM_SPEC "\ | |
eda45b64 MH |
42 | %{!mcpu=30:%{!mcpu=31:%{!mcpu=32:%{!mcpu=33:%{!mcpu=40:%{!mcpu=44:\ |
43 | %{!m30:%{!m40:-m40}}}}}}}} \ | |
cb0ca284 MH |
44 | %{mcpu=30:-m30} \ |
45 | %{mcpu=31:-m31} \ | |
46 | %{mcpu=32:-m32} \ | |
eda45b64 | 47 | %{mcpu=33:-m33} \ |
cb0ca284 MH |
48 | %{mcpu=40:-m40} \ |
49 | %{mcpu=44:-m44} \ | |
50 | %{m30:-m30} \ | |
51 | %{m31:-m31} \ | |
52 | %{m32:-m32} \ | |
eda45b64 | 53 | %{m33:-m33} \ |
cb0ca284 MH |
54 | %{m40:-m40} \ |
55 | %{m44:-m44} \ | |
56 | %{mmemparm:-p} %{mregparm:-r} \ | |
57 | %{!mmemparm:%{!mregparm:-r}} \ | |
58 | %{mbig:-b} %{msmall:-s} \ | |
59 | %{!msmall:%{!mbig:-b}}" | |
60 | ||
ad69db4a | 61 | /* Define linker options. */ |
cb0ca284 MH |
62 | |
63 | #define LINK_SPEC "\ | |
64 | %{m30:--architecture c3x} \ | |
65 | %{m31:--architecture c3x} \ | |
66 | %{m32:--architecture c3x} \ | |
eda45b64 | 67 | %{m33:--architecture c3x} \ |
cb0ca284 MH |
68 | %{mcpu=30:--architecture c3x} \ |
69 | %{mcpu=31:--architecture c3x} \ | |
eda45b64 MH |
70 | %{mcpu=32:--architecture c3x} \ |
71 | %{mcpu=33:--architecture c3x}" | |
cb0ca284 | 72 | |
1ac7a7f5 | 73 | /* Define C preprocessor options. */ |
cb0ca284 MH |
74 | |
75 | #define CPP_SPEC "\ | |
eda45b64 MH |
76 | %{!m30:%{!m31:%{!m32:%{!m33:%{!mcpu=30:%{!mcpu=31:%{!mcpu=32:%{!mcpu=33:\ |
77 | %{!mcpu=40:%{!mcpu=44:%{\ | |
0d74d20f | 78 | !m40:%{!m44:-D_TMS320C4x -D_C4x -D_TMS320C40 -D_C40}}}}}}}}}}}} \ |
cb0ca284 MH |
79 | %{mcpu=30:-D_TMS320C3x -D_C3x -D_TMS320C30 -D_C30 } \ |
80 | %{m30:-D_TMS320C3x -D_C3x -D_TMS320C30 -D_C30 } \ | |
81 | %{mcpu=31:-D_TMS320C3x -D_C3x -D_TMS320C31 -D_C31 } \ | |
82 | %{m31:-D_TMS320C3x -D_C3x -D_TMS320C31 -D_C31 } \ | |
83 | %{mcpu=32:-D_TMS320C3x -D_C3x -D_TMS320C32 -D_C32 } \ | |
84 | %{m32:-D_TMS320C3x -D_C3x -D_TMS320C32 -D_C32 } \ | |
eda45b64 MH |
85 | %{mcpu=33:-D_TMS320C3x -D_C3x -D_TMS320C33 -D_C33 } \ |
86 | %{m33:-D_TMS320C3x -D_C3x -D_TMS320C33 -D_C33 } \ | |
cb0ca284 MH |
87 | %{mcpu=40:-D_TMS320C4x -D_C4x -D_TMS320C40 -D_C40 } \ |
88 | %{m40:-D_TMS320C4x -D_C4x -D_TMS320C40 -D_C40 } \ | |
89 | %{mcpu=44:-D_TMS320C4x -D_C4x -D_TMS320C44 -D_C44 } \ | |
90 | %{m44:-D_TMS320C4x -D_C4x -D_TMS320C44 -D_C44 } \ | |
91 | %{mmemparm:-U_REGPARM }%{mregparm:-D_REGPARM } \ | |
92 | %{!mmemparm:%{!mregparm:-D_REGPARM }} \ | |
93 | %{msmall:-U_BIGMODEL } %{mbig:-D_BIGMODEL } \ | |
94 | %{!msmall:%{!mbig:-D_BIGMODEL }} \ | |
95 | %{finline-functions:-D_INLINE }" | |
96 | ||
ad69db4a | 97 | /* Specify the end file to link with. */ |
cb0ca284 MH |
98 | |
99 | #define ENDFILE_SPEC "" | |
100 | ||
ad69db4a | 101 | /* Target compilation option flags. */ |
cb0ca284 | 102 | |
975ab131 MH |
103 | #define SMALL_MEMORY_FLAG 0x0000001 /* Small memory model. */ |
104 | #define MPYI_FLAG 0x0000002 /* Use 24-bit MPYI for C3x. */ | |
105 | #define FAST_FIX_FLAG 0x0000004 /* Fast fixing of floats. */ | |
106 | #define RPTS_FLAG 0x0000008 /* Allow use of RPTS. */ | |
107 | #define C3X_FLAG 0x0000010 /* Emit C3x code. */ | |
108 | #define TI_FLAG 0x0000020 /* Be compatible with TI assembler. */ | |
109 | #define PARANOID_FLAG 0x0000040 /* Be paranoid about DP reg. in ISRs. */ | |
110 | #define MEMPARM_FLAG 0x0000080 /* Pass arguments on stack. */ | |
111 | #define DEVEL_FLAG 0x0000100 /* Enable features under development. */ | |
112 | #define RPTB_FLAG 0x0000200 /* Enable repeat block. */ | |
113 | #define BK_FLAG 0x0000400 /* Use BK as general register. */ | |
114 | #define DB_FLAG 0x0000800 /* Use decrement and branch for C3x. */ | |
115 | #define DEBUG_FLAG 0x0001000 /* Enable debugging of GCC. */ | |
116 | #define HOIST_FLAG 0x0002000 /* Force constants into registers. */ | |
117 | #define LOOP_UNSIGNED_FLAG 0x0004000 /* Allow unsigned loop counters. */ | |
118 | #define FORCE_FLAG 0x0008000 /* Force op0 and op1 to be same. */ | |
119 | #define PRESERVE_FLOAT_FLAG 0x0010000 /* Save all 40 bits for floats. */ | |
01dc05dd | 120 | #define PARALLEL_INSN_FLAG 0x0020000 /* Allow parallel insns. */ |
975ab131 MH |
121 | #define PARALLEL_MPY_FLAG 0x0040000 /* Allow MPY||ADD, MPY||SUB insns. */ |
122 | #define ALIASES_FLAG 0x0080000 /* Assume mem refs possibly aliased. */ | |
123 | ||
124 | #define C30_FLAG 0x0100000 /* Emit C30 code. */ | |
125 | #define C31_FLAG 0x0200000 /* Emit C31 code. */ | |
126 | #define C32_FLAG 0x0400000 /* Emit C32 code. */ | |
eda45b64 | 127 | #define C33_FLAG 0x0400000 /* Emit C33 code. */ |
975ab131 MH |
128 | #define C40_FLAG 0x1000000 /* Emit C40 code. */ |
129 | #define C44_FLAG 0x2000000 /* Emit C44 code. */ | |
cb0ca284 MH |
130 | |
131 | /* Run-time compilation parameters selecting different hardware subsets. | |
132 | ||
133 | Macro to define tables used to set the flags. | |
4bca1429 MH |
134 | This is a list in braces of triplets in braces, |
135 | each pair being { "NAME", VALUE, "DESCRIPTION" } | |
cb0ca284 MH |
136 | where VALUE is the bits to set or minus the bits to clear. |
137 | An empty string NAME is used to identify the default VALUE. */ | |
138 | ||
047142d3 PT |
139 | #define TARGET_SWITCHES \ |
140 | { { "small", SMALL_MEMORY_FLAG, \ | |
141 | N_("Small memory model") }, \ | |
142 | { "big", -SMALL_MEMORY_FLAG, \ | |
143 | N_("Big memory model") }, \ | |
144 | { "mpyi", MPYI_FLAG, \ | |
145 | N_("Use MPYI instruction for C3x") }, \ | |
146 | { "no-mpyi", -MPYI_FLAG, \ | |
147 | N_("Do not use MPYI instruction for C3x") }, \ | |
148 | { "fast-fix", FAST_FIX_FLAG, \ | |
149 | N_("Use fast but approximate float to integer conversion") }, \ | |
150 | { "no-fast-fix", -FAST_FIX_FLAG, \ | |
151 | N_("Use slow but accurate float to integer conversion") }, \ | |
152 | { "rpts", RPTS_FLAG, \ | |
153 | N_("Enable use of RTPS instruction") }, \ | |
154 | { "no-rpts", -RPTS_FLAG, \ | |
155 | N_("Disable use of RTPS instruction") }, \ | |
156 | { "rptb", RPTB_FLAG, \ | |
157 | N_("Enable use of RTPB instruction") }, \ | |
158 | { "no-rptb", -RPTB_FLAG, \ | |
159 | N_("Disable use of RTPB instruction") }, \ | |
160 | { "30", C30_FLAG, \ | |
161 | N_("Generate code for C30 CPU")}, \ | |
162 | { "31", C31_FLAG, \ | |
163 | N_("Generate code for C31 CPU")}, \ | |
164 | { "32", C32_FLAG, \ | |
165 | N_("Generate code for C32 CPU")}, \ | |
166 | { "33", C33_FLAG, \ | |
167 | N_("Generate code for C33 CPU")}, \ | |
168 | { "40", C40_FLAG, \ | |
169 | N_("Generate code for C40 CPU")}, \ | |
170 | { "44", C44_FLAG, \ | |
171 | N_("Generate code for C44 CPU")}, \ | |
172 | { "ti", TI_FLAG, \ | |
173 | N_("Emit code compatible with TI tools")}, \ | |
174 | { "no-ti", -TI_FLAG, \ | |
175 | N_("Emit code to use GAS extensions")}, \ | |
176 | { "paranoid", PARANOID_FLAG, \ | |
177 | N_("Save DP across ISR in small memory model") }, \ | |
178 | { "no-paranoid", -PARANOID_FLAG, \ | |
179 | N_("Don't save DP across ISR in small memory model") }, \ | |
180 | { "isr-dp-reload", PARANOID_FLAG, \ | |
181 | N_("Save DP across ISR in small memory model") }, \ | |
182 | { "no-isr-dp-reload", -PARANOID_FLAG, \ | |
183 | N_("Don't save DP across ISR in small memory model") }, \ | |
184 | { "memparm", MEMPARM_FLAG, \ | |
185 | N_("Pass arguments on the stack") }, \ | |
186 | { "regparm", -MEMPARM_FLAG, \ | |
187 | N_("Pass arguments in registers") }, \ | |
188 | { "devel", DEVEL_FLAG, \ | |
189 | N_("Enable new features under development") }, \ | |
190 | { "no-devel", -DEVEL_FLAG, \ | |
191 | N_("Disable new features under development") }, \ | |
192 | { "bk", BK_FLAG, \ | |
193 | N_("Use the BK register as a general purpose register") }, \ | |
194 | { "no-bk", -BK_FLAG, \ | |
195 | N_("Do not allocate BK register") }, \ | |
196 | { "db", DB_FLAG, \ | |
197 | N_("Enable use of DB instruction") }, \ | |
198 | { "no-db", -DB_FLAG, \ | |
199 | N_("Disable use of DB instruction") }, \ | |
200 | { "debug", DEBUG_FLAG, \ | |
201 | N_("Enable debugging") }, \ | |
202 | { "no-debug", -DEBUG_FLAG, \ | |
203 | N_("Disable debugging") }, \ | |
204 | { "hoist", HOIST_FLAG, \ | |
205 | N_("Force constants into registers to improve hoisting") }, \ | |
206 | { "no-hoist", -HOIST_FLAG, \ | |
207 | N_("Don't force constants into registers") }, \ | |
208 | { "force", FORCE_FLAG, \ | |
209 | N_("Force RTL generation to emit valid 3 operand insns") }, \ | |
210 | { "no-force", -FORCE_FLAG, \ | |
211 | N_("Allow RTL generation to emit invalid 3 operand insns") }, \ | |
212 | { "loop-unsigned", LOOP_UNSIGNED_FLAG, \ | |
213 | N_("Allow unsigned interation counts for RPTB/DB") }, \ | |
214 | { "no-loop-unsigned", -LOOP_UNSIGNED_FLAG, \ | |
215 | N_("Disallow unsigned iteration counts for RPTB/DB") }, \ | |
216 | { "preserve-float", PRESERVE_FLOAT_FLAG, \ | |
217 | N_("Preserve all 40 bits of FP reg across call") }, \ | |
218 | { "no-preserve-float", -PRESERVE_FLOAT_FLAG, \ | |
219 | N_("Only preserve 32 bits of FP reg across call") }, \ | |
220 | { "parallel-insns", PARALLEL_INSN_FLAG, \ | |
221 | N_("Enable parallel instructions") }, \ | |
222 | { "no-parallel-insns", -PARALLEL_INSN_FLAG, \ | |
223 | N_("Disable parallel instructions") }, \ | |
224 | { "parallel-mpy", PARALLEL_MPY_FLAG, \ | |
225 | N_("Enable MPY||ADD and MPY||SUB instructions") }, \ | |
226 | { "no-parallel-mpy", -PARALLEL_MPY_FLAG, \ | |
227 | N_("Disable MPY||ADD and MPY||SUB instructions") }, \ | |
228 | { "aliases", ALIASES_FLAG, \ | |
229 | N_("Assume that pointers may be aliased") }, \ | |
230 | { "no-aliases", -ALIASES_FLAG, \ | |
231 | N_("Assume that pointers not aliased") }, \ | |
4bca1429 | 232 | { "", TARGET_DEFAULT, ""} } |
cb0ca284 | 233 | |
975ab131 | 234 | /* Default target switches. */ |
cb0ca284 | 235 | |
1ac7a7f5 | 236 | /* Play safe, not the fastest code. */ |
01dc05dd | 237 | #define TARGET_DEFAULT ALIASES_FLAG | PARALLEL_INSN_FLAG \ |
d97860ae | 238 | | PARALLEL_MPY_FLAG | RPTB_FLAG |
cb0ca284 MH |
239 | |
240 | /* Caveats: | |
241 | Max iteration count for RPTB/RPTS is 2^31 + 1. | |
242 | Max iteration count for DB is 2^31 + 1 for C40, but 2^23 + 1 for C30. | |
243 | RPTS blocks interrupts. */ | |
244 | ||
245 | ||
246 | extern int target_flags; | |
247 | ||
f42850b9 | 248 | #define TARGET_INLINE (! optimize_size) /* Inline MPYI. */ |
2e3e9ead | 249 | #define TARGET_SMALL_REG_CLASS 0 |
cb0ca284 MH |
250 | |
251 | #define TARGET_SMALL (target_flags & SMALL_MEMORY_FLAG) | |
252 | #define TARGET_MPYI (!TARGET_C3X || (target_flags & MPYI_FLAG)) | |
253 | #define TARGET_FAST_FIX (target_flags & FAST_FIX_FLAG) | |
254 | #define TARGET_RPTS (target_flags & RPTS_FLAG) | |
255 | #define TARGET_TI (target_flags & TI_FLAG) | |
256 | #define TARGET_PARANOID (target_flags & PARANOID_FLAG) | |
257 | #define TARGET_MEMPARM (target_flags & MEMPARM_FLAG) | |
258 | #define TARGET_DEVEL (target_flags & DEVEL_FLAG) | |
259 | #define TARGET_RPTB (target_flags & RPTB_FLAG \ | |
260 | && optimize >= 2) | |
261 | #define TARGET_BK (target_flags & BK_FLAG) | |
4ddb3ea6 | 262 | #define TARGET_DB (! TARGET_C3X || (target_flags & DB_FLAG)) |
cb0ca284 MH |
263 | #define TARGET_DEBUG (target_flags & DEBUG_FLAG) |
264 | #define TARGET_HOIST (target_flags & HOIST_FLAG) | |
265 | #define TARGET_LOOP_UNSIGNED (target_flags & LOOP_UNSIGNED_FLAG) | |
266 | #define TARGET_FORCE (target_flags & FORCE_FLAG) | |
267 | #define TARGET_PRESERVE_FLOAT (target_flags & PRESERVE_FLOAT_FLAG) | |
01dc05dd | 268 | #define TARGET_PARALLEL ((target_flags & PARALLEL_INSN_FLAG) \ |
cb0ca284 | 269 | && optimize >= 2) |
01dc05dd | 270 | #define TARGET_PARALLEL_MPY (TARGET_PARALLEL \ |
cb0ca284 MH |
271 | && (target_flags & PARALLEL_MPY_FLAG)) |
272 | #define TARGET_ALIASES (target_flags & ALIASES_FLAG) | |
273 | ||
274 | #define TARGET_C3X (target_flags & C3X_FLAG) | |
275 | #define TARGET_C30 (target_flags & C30_FLAG) | |
276 | #define TARGET_C31 (target_flags & C31_FLAG) | |
277 | #define TARGET_C32 (target_flags & C32_FLAG) | |
eda45b64 | 278 | #define TARGET_C33 (target_flags & C33_FLAG) |
cb0ca284 MH |
279 | #define TARGET_C40 (target_flags & C40_FLAG) |
280 | #define TARGET_C44 (target_flags & C44_FLAG) | |
281 | ||
31445126 | 282 | /* Define some options to control code generation. */ |
50c33087 | 283 | #define TARGET_LOAD_ADDRESS (1 || (! TARGET_C3X && ! TARGET_SMALL)) |
860b3499 MH |
284 | /* Nonzero to convert direct memory references into HIGH/LO_SUM pairs |
285 | during RTL generation. */ | |
31445126 | 286 | #define TARGET_EXPOSE_LDP 0 |
860b3499 MH |
287 | /* Nonzero to force loading of direct memory references into a register. */ |
288 | #define TARGET_LOAD_DIRECT_MEMS 0 | |
50c33087 | 289 | |
cb0ca284 MH |
290 | /* -mrpts allows the use of the RPTS instruction irregardless. |
291 | -mrpts=max-cycles will use RPTS if the number of cycles is constant | |
1ac7a7f5 | 292 | and less than max-cycles. */ |
cb0ca284 MH |
293 | |
294 | #define TARGET_RPTS_CYCLES(CYCLES) (TARGET_RPTS || (CYCLES) < c4x_rpts_cycles) | |
295 | ||
50c33087 MH |
296 | #define BCT_CHECK_LOOP_ITERATIONS !(TARGET_LOOP_UNSIGNED) |
297 | ||
975ab131 | 298 | /* -mcpu=XX with XX = target DSP version number. */ |
cb0ca284 | 299 | |
ddf16f18 | 300 | extern const char *c4x_rpts_cycles_string, *c4x_cpu_version_string; |
cb0ca284 | 301 | |
047142d3 PT |
302 | #define TARGET_OPTIONS \ |
303 | { {"rpts=", &c4x_rpts_cycles_string, \ | |
304 | N_("Specify maximum number of iterations for RPTS") }, \ | |
305 | {"cpu=", &c4x_cpu_version_string, \ | |
306 | N_("Select CPU to generate code for") } } | |
cb0ca284 MH |
307 | |
308 | /* Sometimes certain combinations of command options do not make sense | |
309 | on a particular target machine. You can define a macro | |
310 | `OVERRIDE_OPTIONS' to take account of this. This macro, if | |
311 | defined, is executed once just after all the command options have | |
1ac7a7f5 | 312 | been parsed. */ |
cb0ca284 | 313 | |
cb0ca284 MH |
314 | #define OVERRIDE_OPTIONS c4x_override_options () |
315 | ||
d5e4ff48 | 316 | /* Define this to change the optimizations performed by default. */ |
798f6e6f | 317 | |
4e6de5a9 | 318 | #define OPTIMIZATION_OPTIONS(LEVEL,SIZE) c4x_optimization_options(LEVEL, SIZE) |
cb0ca284 | 319 | |
975ab131 | 320 | /* Run Time Target Specification. */ |
cb0ca284 | 321 | |
4e6de5a9 | 322 | #define TARGET_VERSION fprintf (stderr, " (TMS320C[34]x, TI syntax)"); |
cb0ca284 | 323 | |
975ab131 | 324 | /* Storage Layout. */ |
cb0ca284 MH |
325 | |
326 | #define BITS_BIG_ENDIAN 0 | |
327 | #define BYTES_BIG_ENDIAN 0 | |
328 | #define WORDS_BIG_ENDIAN 0 | |
329 | ||
330 | /* Technically, we are little endian, but we put the floats out as | |
1ac7a7f5 | 331 | whole longs and this makes GCC put them out in the right order. */ |
cb0ca284 MH |
332 | |
333 | #define FLOAT_WORDS_BIG_ENDIAN 1 | |
334 | ||
335 | /* Note the ANSI C standard requires sizeof(char) = 1. On the C[34]x | |
336 | all integral and floating point data types are stored in memory as | |
337 | 32-bits (floating point types can be stored as 40-bits in the | |
338 | extended precision registers), so sizeof(char) = sizeof(short) = | |
1ac7a7f5 | 339 | sizeof(int) = sizeof(long) = sizeof(float) = sizeof(double) = 1. */ |
cb0ca284 MH |
340 | |
341 | #define BITS_PER_UNIT 32 | |
cb0ca284 | 342 | #define UNITS_PER_WORD 1 |
cb0ca284 MH |
343 | #define PARM_BOUNDARY 32 |
344 | #define STACK_BOUNDARY 32 | |
345 | #define FUNCTION_BOUNDARY 32 | |
346 | #define BIGGEST_ALIGNMENT 32 | |
347 | #define EMPTY_FIELD_BOUNDARY 32 | |
348 | #define STRICT_ALIGNMENT 0 | |
349 | #define TARGET_FLOAT_FORMAT C4X_FLOAT_FORMAT | |
975ab131 | 350 | #define MAX_FIXED_MODE_SIZE 64 /* HImode. */ |
cb0ca284 | 351 | |
7f7680a9 MH |
352 | /* If a structure has a floating point field then force structure |
353 | to have BLKMODE. */ | |
31a02448 R |
354 | #define MEMBER_TYPE_FORCES_BLK(FIELD) \ |
355 | (TREE_CODE (TREE_TYPE (FIELD)) == REAL_TYPE) | |
7f7680a9 | 356 | |
55310df7 MH |
357 | /* Number of bits in the high and low parts of a two stage |
358 | load of an immediate constant. */ | |
359 | #define BITS_PER_HIGH 16 | |
360 | #define BITS_PER_LO_SUM 16 | |
361 | ||
bc46716b | 362 | /* Define register numbers. */ |
cb0ca284 | 363 | |
bc46716b | 364 | /* Extended-precision registers. */ |
cb0ca284 MH |
365 | |
366 | #define R0_REGNO 0 | |
367 | #define R1_REGNO 1 | |
368 | #define R2_REGNO 2 | |
369 | #define R3_REGNO 3 | |
370 | #define R4_REGNO 4 | |
371 | #define R5_REGNO 5 | |
372 | #define R6_REGNO 6 | |
373 | #define R7_REGNO 7 | |
374 | ||
bc46716b | 375 | /* Auxiliary (address) registers. */ |
cb0ca284 MH |
376 | |
377 | #define AR0_REGNO 8 | |
378 | #define AR1_REGNO 9 | |
379 | #define AR2_REGNO 10 | |
380 | #define AR3_REGNO 11 | |
381 | #define AR4_REGNO 12 | |
382 | #define AR5_REGNO 13 | |
383 | #define AR6_REGNO 14 | |
384 | #define AR7_REGNO 15 | |
385 | ||
bc46716b | 386 | /* Data page register. */ |
cb0ca284 MH |
387 | |
388 | #define DP_REGNO 16 | |
389 | ||
bc46716b | 390 | /* Index registers. */ |
cb0ca284 MH |
391 | |
392 | #define IR0_REGNO 17 | |
393 | #define IR1_REGNO 18 | |
394 | ||
bc46716b | 395 | /* Block size register. */ |
cb0ca284 MH |
396 | |
397 | #define BK_REGNO 19 | |
398 | ||
bc46716b | 399 | /* Stack pointer. */ |
cb0ca284 MH |
400 | |
401 | #define SP_REGNO 20 | |
402 | ||
bc46716b | 403 | /* Status register. */ |
cb0ca284 MH |
404 | |
405 | #define ST_REGNO 21 | |
406 | ||
bc46716b | 407 | /* Misc. interrupt registers. */ |
cb0ca284 | 408 | |
bc46716b MH |
409 | #define DIE_REGNO 22 /* C4x only. */ |
410 | #define IE_REGNO 22 /* C3x only. */ | |
411 | #define IIE_REGNO 23 /* C4x only. */ | |
412 | #define IF_REGNO 23 /* C3x only. */ | |
413 | #define IIF_REGNO 24 /* C4x only. */ | |
414 | #define IOF_REGNO 24 /* C3x only. */ | |
cb0ca284 | 415 | |
bc46716b | 416 | /* Repeat block registers. */ |
cb0ca284 MH |
417 | |
418 | #define RS_REGNO 25 | |
419 | #define RE_REGNO 26 | |
420 | #define RC_REGNO 27 | |
421 | ||
bc46716b | 422 | /* Additional extended-precision registers. */ |
cb0ca284 | 423 | |
bc46716b MH |
424 | #define R8_REGNO 28 /* C4x only. */ |
425 | #define R9_REGNO 29 /* C4x only. */ | |
426 | #define R10_REGNO 30 /* C4x only. */ | |
427 | #define R11_REGNO 31 /* C4x only. */ | |
cb0ca284 MH |
428 | |
429 | #define FIRST_PSEUDO_REGISTER 32 | |
430 | ||
bc46716b | 431 | /* Extended precision registers (low set). */ |
cb0ca284 | 432 | |
25cd0db1 MH |
433 | #define IS_R0R1_REGNO(r) \ |
434 | ((unsigned int)((r) - R0_REGNO) <= (R1_REGNO - R0_REGNO)) | |
435 | #define IS_R2R3_REGNO(r) \ | |
436 | ((unsigned int)((r) - R2_REGNO) <= (R3_REGNO - R2_REGNO)) | |
437 | #define IS_EXT_LOW_REGNO(r) \ | |
438 | ((unsigned int)((r) - R0_REGNO) <= (R7_REGNO - R0_REGNO)) | |
cb0ca284 | 439 | |
bc46716b | 440 | /* Extended precision registers (high set). */ |
cb0ca284 | 441 | |
25cd0db1 MH |
442 | #define IS_EXT_HIGH_REGNO(r) \ |
443 | (! TARGET_C3X \ | |
444 | && ((unsigned int) ((r) - R8_REGNO) <= (R11_REGNO - R8_REGNO))) | |
445 | ||
bc46716b MH |
446 | /* Address registers. */ |
447 | ||
25cd0db1 MH |
448 | #define IS_AUX_REGNO(r) \ |
449 | ((unsigned int)((r) - AR0_REGNO) <= (AR7_REGNO - AR0_REGNO)) | |
bc46716b MH |
450 | #define IS_ADDR_REGNO(r) IS_AUX_REGNO(r) |
451 | #define IS_DP_REGNO(r) ((r) == DP_REGNO) | |
452 | #define IS_INDEX_REGNO(r) (((r) == IR0_REGNO) || ((r) == IR1_REGNO)) | |
453 | #define IS_SP_REGNO(r) ((r) == SP_REGNO) | |
454 | #define IS_BK_REGNO(r) (TARGET_BK && (r) == BK_REGNO) | |
455 | ||
456 | /* Misc registers. */ | |
457 | ||
458 | #define IS_ST_REGNO(r) ((r) == ST_REGNO) | |
459 | #define IS_RC_REGNO(r) ((r) == RC_REGNO) | |
460 | #define IS_REPEAT_REGNO(r) (((r) >= RS_REGNO) && ((r) <= RC_REGNO)) | |
461 | ||
462 | /* Composite register sets. */ | |
463 | ||
464 | #define IS_ADDR_OR_INDEX_REGNO(r) (IS_ADDR_REGNO(r) || IS_INDEX_REGNO(r)) | |
465 | #define IS_EXT_REGNO(r) (IS_EXT_LOW_REGNO(r) || IS_EXT_HIGH_REGNO(r)) | |
466 | #define IS_STD_REGNO(r) (IS_ADDR_OR_INDEX_REGNO(r) \ | |
467 | || IS_REPEAT_REGNO(r) \ | |
468 | || IS_SP_REGNO(r) \ | |
469 | || IS_BK_REGNO(r)) | |
470 | #define IS_INT_REGNO(r) (IS_EXT_REGNO(r) || IS_STD_REGNO(r)) | |
471 | #define IS_GROUP1_REGNO(r) (IS_ADDR_OR_INDEX_REGNO(r) || IS_BK_REGNO(r)) | |
0b53f039 MH |
472 | #define IS_INT_CALL_SAVED_REGNO(r) (((r) == R4_REGNO) || ((r) == R5_REGNO) \ |
473 | || ((r) == R8_REGNO)) | |
474 | #define IS_FLOAT_CALL_SAVED_REGNO(r) (((r) == R6_REGNO) || ((r) == R7_REGNO)) | |
bc46716b MH |
475 | |
476 | #define IS_PSEUDO_REGNO(r) ((r) >= FIRST_PSEUDO_REGISTER) | |
477 | #define IS_R0R1_OR_PSEUDO_REGNO(r) (IS_R0R1_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
478 | #define IS_R2R3_OR_PSEUDO_REGNO(r) (IS_R2R3_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
479 | #define IS_EXT_OR_PSEUDO_REGNO(r) (IS_EXT_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
480 | #define IS_STD_OR_PSEUDO_REGNO(r) (IS_STD_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
481 | #define IS_INT_OR_PSEUDO_REGNO(r) (IS_INT_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
482 | #define IS_ADDR_OR_PSEUDO_REGNO(r) (IS_ADDR_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
483 | #define IS_INDEX_OR_PSEUDO_REGNO(r) (IS_INDEX_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
484 | #define IS_EXT_LOW_OR_PSEUDO_REGNO(r) (IS_EXT_LOW_REGNO(r) \ | |
485 | || IS_PSEUDO_REGNO(r)) | |
486 | #define IS_DP_OR_PSEUDO_REGNO(r) (IS_DP_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
487 | #define IS_SP_OR_PSEUDO_REGNO(r) (IS_SP_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
488 | #define IS_ST_OR_PSEUDO_REGNO(r) (IS_ST_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
489 | #define IS_RC_OR_PSEUDO_REGNO(r) (IS_RC_REGNO(r) || IS_PSEUDO_REGNO(r)) | |
490 | ||
491 | #define IS_PSEUDO_REG(op) (IS_PSEUDO_REGNO(REGNO(op))) | |
492 | #define IS_ADDR_REG(op) (IS_ADDR_REGNO(REGNO(op))) | |
493 | #define IS_INDEX_REG(op) (IS_INDEX_REGNO(REGNO(op))) | |
494 | #define IS_GROUP1_REG(r) (IS_GROUP1_REGNO(REGNO(op))) | |
495 | #define IS_SP_REG(op) (IS_SP_REGNO(REGNO(op))) | |
496 | #define IS_STD_REG(op) (IS_STD_REGNO(REGNO(op))) | |
497 | #define IS_EXT_REG(op) (IS_EXT_REGNO(REGNO(op))) | |
498 | ||
499 | #define IS_R0R1_OR_PSEUDO_REG(op) (IS_R0R1_OR_PSEUDO_REGNO(REGNO(op))) | |
500 | #define IS_R2R3_OR_PSEUDO_REG(op) (IS_R2R3_OR_PSEUDO_REGNO(REGNO(op))) | |
501 | #define IS_EXT_OR_PSEUDO_REG(op) (IS_EXT_OR_PSEUDO_REGNO(REGNO(op))) | |
502 | #define IS_STD_OR_PSEUDO_REG(op) (IS_STD_OR_PSEUDO_REGNO(REGNO(op))) | |
503 | #define IS_EXT_LOW_OR_PSEUDO_REG(op) (IS_EXT_LOW_OR_PSEUDO_REGNO(REGNO(op))) | |
504 | #define IS_INT_OR_PSEUDO_REG(op) (IS_INT_OR_PSEUDO_REGNO(REGNO(op))) | |
505 | ||
506 | #define IS_ADDR_OR_PSEUDO_REG(op) (IS_ADDR_OR_PSEUDO_REGNO(REGNO(op))) | |
507 | #define IS_INDEX_OR_PSEUDO_REG(op) (IS_INDEX_OR_PSEUDO_REGNO(REGNO(op))) | |
508 | #define IS_DP_OR_PSEUDO_REG(op) (IS_DP_OR_PSEUDO_REGNO(REGNO(op))) | |
509 | #define IS_SP_OR_PSEUDO_REG(op) (IS_SP_OR_PSEUDO_REGNO(REGNO(op))) | |
510 | #define IS_ST_OR_PSEUDO_REG(op) (IS_ST_OR_PSEUDO_REGNO(REGNO(op))) | |
511 | #define IS_RC_OR_PSEUDO_REG(op) (IS_RC_OR_PSEUDO_REGNO(REGNO(op))) | |
cb0ca284 MH |
512 | |
513 | /* 1 for registers that have pervasive standard uses | |
1ac7a7f5 | 514 | and are not available for the register allocator. */ |
cb0ca284 MH |
515 | |
516 | #define FIXED_REGISTERS \ | |
517 | { \ | |
975ab131 | 518 | /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \ |
cb0ca284 | 519 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ |
975ab131 | 520 | /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \ |
cb0ca284 MH |
521 | 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 \ |
522 | } | |
523 | ||
524 | /* 1 for registers not available across function calls. | |
525 | These must include the FIXED_REGISTERS and also any | |
526 | registers that can be used without being saved. | |
527 | The latter must include the registers where values are returned | |
528 | and the register where structure-value addresses are passed. | |
529 | Aside from that, you can include as many other registers as you like. | |
530 | ||
531 | Note that the extended precision registers are only saved in some | |
532 | modes. The macro HARD_REGNO_CALL_CLOBBERED specifies which modes | |
533 | get clobbered for a given regno. */ | |
534 | ||
535 | #define CALL_USED_REGISTERS \ | |
536 | { \ | |
975ab131 | 537 | /* R0 R1 R2 R3 R4 R5 R6 R7 AR0 AR1 AR2 AR3 AR4 AR5 AR6 AR7. */ \ |
cb0ca284 | 538 | 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, \ |
975ab131 | 539 | /* DP IR0 IR1 BK SP ST DIE IIE IIF RS RE RC R8 R9 R10 R11. */ \ |
cb0ca284 MH |
540 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 \ |
541 | } | |
542 | ||
1ac7a7f5 | 543 | /* Macro to conditionally modify fixed_regs/call_used_regs. */ |
cb0ca284 MH |
544 | |
545 | #define CONDITIONAL_REGISTER_USAGE \ | |
546 | { \ | |
4ddb3ea6 | 547 | if (! TARGET_BK) \ |
cb0ca284 MH |
548 | { \ |
549 | fixed_regs[BK_REGNO] = 1; \ | |
550 | call_used_regs[BK_REGNO] = 1; \ | |
551 | c4x_regclass_map[BK_REGNO] = NO_REGS; \ | |
552 | } \ | |
553 | if (TARGET_C3X) \ | |
554 | { \ | |
555 | int i; \ | |
556 | \ | |
975ab131 MH |
557 | reg_names[DIE_REGNO] = "ie"; /* Clobber die. */ \ |
558 | reg_names[IF_REGNO] = "if"; /* Clobber iie. */ \ | |
559 | reg_names[IOF_REGNO] = "iof"; /* Clobber iif. */ \ | |
cb0ca284 MH |
560 | \ |
561 | for (i = R8_REGNO; i <= R11_REGNO; i++) \ | |
562 | { \ | |
563 | fixed_regs[i] = call_used_regs[i] = 1; \ | |
564 | c4x_regclass_map[i] = NO_REGS; \ | |
565 | } \ | |
566 | } \ | |
2e3e9ead MH |
567 | if (TARGET_PRESERVE_FLOAT) \ |
568 | { \ | |
569 | c4x_caller_save_map[R6_REGNO] = HFmode; \ | |
570 | c4x_caller_save_map[R7_REGNO] = HFmode; \ | |
571 | } \ | |
cb0ca284 MH |
572 | } |
573 | ||
975ab131 | 574 | /* Order of Allocation of Registers. */ |
cb0ca284 MH |
575 | |
576 | /* List the order in which to allocate registers. Each register must be | |
577 | listed once, even those in FIXED_REGISTERS. | |
578 | ||
579 | First allocate registers that don't need preservation across calls, | |
580 | except index and address registers. Then allocate data registers | |
581 | that require preservation across calls (even though this invokes an | |
582 | extra overhead of having to save/restore these registers). Next | |
583 | allocate the address and index registers, since using these | |
584 | registers for arithmetic can cause pipeline stalls. Finally | |
585 | allocated the fixed registers which won't be allocated anyhow. */ | |
586 | ||
587 | #define REG_ALLOC_ORDER \ | |
588 | {R0_REGNO, R1_REGNO, R2_REGNO, R3_REGNO, \ | |
589 | R9_REGNO, R10_REGNO, R11_REGNO, \ | |
590 | RS_REGNO, RE_REGNO, RC_REGNO, BK_REGNO, \ | |
591 | R4_REGNO, R5_REGNO, R6_REGNO, R7_REGNO, R8_REGNO, \ | |
592 | AR0_REGNO, AR1_REGNO, AR2_REGNO, AR3_REGNO, \ | |
593 | AR4_REGNO, AR5_REGNO, AR6_REGNO, AR7_REGNO, \ | |
594 | IR0_REGNO, IR1_REGNO, \ | |
595 | SP_REGNO, DP_REGNO, ST_REGNO, IE_REGNO, IF_REGNO, IOF_REGNO} | |
596 | ||
40eef757 HB |
597 | /* A C expression that is nonzero if hard register number REGNO2 can be |
598 | considered for use as a rename register for REGNO1 */ | |
599 | ||
600 | #define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \ | |
601 | c4x_hard_regno_rename_ok((REGNO1), (REGNO2)) | |
cb0ca284 MH |
602 | |
603 | /* Determine which register classes are very likely used by spill registers. | |
604 | local-alloc.c won't allocate pseudos that have these classes as their | |
605 | preferred class unless they are "preferred or nothing". */ | |
606 | ||
4e6de5a9 | 607 | #define CLASS_LIKELY_SPILLED_P(CLASS) ((CLASS) == INDEX_REGS) |
cb0ca284 | 608 | |
d0550d07 HB |
609 | /* CCmode is wrongly defined in machmode.def. It should have a size |
610 | of UNITS_PER_WORD. HFmode is 40-bits and thus fits within a single | |
611 | extended precision register. Similarly, HCmode fits within two | |
612 | extended precision registers. */ | |
cb0ca284 MH |
613 | |
614 | #define HARD_REGNO_NREGS(REGNO, MODE) \ | |
d0550d07 HB |
615 | (((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : \ |
616 | ((MODE) == HFmode) ? 1 : \ | |
617 | ((MODE) == HCmode) ? 2 : \ | |
618 | ((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) | |
cb0ca284 MH |
619 | |
620 | ||
621 | /* A C expression that is nonzero if the hard register REGNO is preserved | |
622 | across a call in mode MODE. This does not have to include the call used | |
623 | registers. */ | |
624 | ||
2e3e9ead | 625 | #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ |
0b53f039 | 626 | ((IS_FLOAT_CALL_SAVED_REGNO (REGNO) && ! ((MODE) == QFmode)) \ |
c98f0cdb | 627 | || (IS_INT_CALL_SAVED_REGNO (REGNO) \ |
2e3e9ead | 628 | && ! ((MODE) == QImode || (MODE) == HImode || (MODE) == Pmode))) |
cb0ca284 MH |
629 | |
630 | /* Specify the modes required to caller save a given hard regno. */ | |
631 | ||
787dc842 | 632 | #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) (c4x_caller_save_map[REGNO]) |
cb0ca284 | 633 | |
4e6de5a9 | 634 | #define HARD_REGNO_MODE_OK(REGNO, MODE) c4x_hard_regno_mode_ok(REGNO, MODE) |
cb0ca284 MH |
635 | |
636 | /* A C expression that is nonzero if it is desirable to choose | |
637 | register allocation so as to avoid move instructions between a | |
638 | value of mode MODE1 and a value of mode MODE2. | |
639 | ||
640 | Value is 1 if it is a good idea to tie two pseudo registers | |
641 | when one has mode MODE1 and one has mode MODE2. | |
642 | If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, | |
643 | for any hard reg, then this must be 0 for correct output. */ | |
644 | ||
4e6de5a9 | 645 | #define MODES_TIEABLE_P(MODE1, MODE2) 0 |
cb0ca284 MH |
646 | |
647 | ||
648 | /* Define the classes of registers for register constraints in the | |
649 | machine description. Also define ranges of constants. | |
650 | ||
651 | One of the classes must always be named ALL_REGS and include all hard regs. | |
652 | If there is more than one class, another class must be named NO_REGS | |
653 | and contain no registers. | |
654 | ||
655 | The name GENERAL_REGS must be the name of a class (or an alias for | |
656 | another name such as ALL_REGS). This is the class of registers | |
657 | that is allowed by "g" or "r" in a register constraint. | |
658 | Also, registers outside this class are allocated only when | |
659 | instructions express preferences for them. | |
660 | ||
661 | The classes must be numbered in nondecreasing order; that is, | |
662 | a larger-numbered class must never be contained completely | |
663 | in a smaller-numbered class. | |
664 | ||
665 | For any two classes, it is very desirable that there be another | |
666 | class that represents their union. */ | |
667 | ||
668 | enum reg_class | |
669 | { | |
670 | NO_REGS, | |
975ab131 MH |
671 | R0R1_REGS, /* 't'. */ |
672 | R2R3_REGS, /* 'u'. */ | |
673 | EXT_LOW_REGS, /* 'q'. */ | |
674 | EXT_REGS, /* 'f'. */ | |
675 | ADDR_REGS, /* 'a'. */ | |
676 | INDEX_REGS, /* 'x'. */ | |
677 | BK_REG, /* 'k'. */ | |
678 | SP_REG, /* 'b'. */ | |
679 | RC_REG, /* 'v'. */ | |
4a6330ac | 680 | COUNTER_REGS, /* */ |
975ab131 MH |
681 | INT_REGS, /* 'c'. */ |
682 | GENERAL_REGS, /* 'r'. */ | |
683 | DP_REG, /* 'z'. */ | |
684 | ST_REG, /* 'y'. */ | |
cb0ca284 MH |
685 | ALL_REGS, |
686 | LIM_REG_CLASSES | |
687 | }; | |
688 | ||
689 | #define N_REG_CLASSES (int) LIM_REG_CLASSES | |
690 | ||
691 | #define REG_CLASS_NAMES \ | |
692 | { \ | |
693 | "NO_REGS", \ | |
694 | "R0R1_REGS", \ | |
695 | "R2R3_REGS", \ | |
696 | "EXT_LOW_REGS", \ | |
697 | "EXT_REGS", \ | |
698 | "ADDR_REGS", \ | |
699 | "INDEX_REGS", \ | |
cb0ca284 | 700 | "BK_REG", \ |
d5e4ff48 MH |
701 | "SP_REG", \ |
702 | "RC_REG", \ | |
4a6330ac | 703 | "COUNTER_REGS", \ |
cb0ca284 MH |
704 | "INT_REGS", \ |
705 | "GENERAL_REGS", \ | |
706 | "DP_REG", \ | |
707 | "ST_REG", \ | |
708 | "ALL_REGS" \ | |
d5e4ff48 | 709 | } |
cb0ca284 MH |
710 | |
711 | /* Define which registers fit in which classes. | |
712 | This is an initializer for a vector of HARD_REG_SET | |
2e3e9ead MH |
713 | of length N_REG_CLASSES. RC is not included in GENERAL_REGS |
714 | since the register allocator will often choose a general register | |
715 | in preference to RC for the decrement_and_branch_on_count pattern. */ | |
cb0ca284 MH |
716 | |
717 | #define REG_CLASS_CONTENTS \ | |
718 | { \ | |
975ab131 MH |
719 | {0x00000000}, /* No registers. */ \ |
720 | {0x00000003}, /* 't' R0-R1 . */ \ | |
721 | {0x0000000c}, /* 'u' R2-R3 . */ \ | |
722 | {0x000000ff}, /* 'q' R0-R7 . */ \ | |
2e3e9ead | 723 | {0xf00000ff}, /* 'f' R0-R11 */ \ |
975ab131 MH |
724 | {0x0000ff00}, /* 'a' AR0-AR7. */ \ |
725 | {0x00060000}, /* 'x' IR0-IR1. */ \ | |
726 | {0x00080000}, /* 'k' BK. */ \ | |
727 | {0x00100000}, /* 'b' SP. */ \ | |
728 | {0x08000000}, /* 'v' RC. */ \ | |
729 | {0x0800ff00}, /* RC,AR0-AR7. */ \ | |
730 | {0x0e1eff00}, /* 'c' AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */ \ | |
731 | {0xfe1effff}, /* 'r' R0-R11, AR0-AR7, IR0-IR1, BK, SP, RS, RE, RC. */\ | |
732 | {0x00010000}, /* 'z' DP. */ \ | |
733 | {0x00200000}, /* 'y' ST. */ \ | |
734 | {0xffffffff}, /* All registers. */ \ | |
cb0ca284 MH |
735 | } |
736 | ||
737 | /* The same information, inverted: | |
738 | Return the class number of the smallest class containing | |
739 | reg number REGNO. This could be a conditional expression | |
740 | or could index an array. */ | |
741 | ||
742 | #define REGNO_REG_CLASS(REGNO) (c4x_regclass_map[REGNO]) | |
743 | ||
2e3e9ead MH |
744 | /* When SMALL_REGISTER_CLASSES is defined, the lifetime of registers |
745 | explicitly used in the rtl is kept as short as possible. | |
746 | ||
747 | We only need to define SMALL_REGISTER_CLASSES if TARGET_PARALLEL_MPY | |
748 | is defined since the MPY|ADD insns require the classes R0R1_REGS and | |
749 | R2R3_REGS which are used by the function return registers (R0,R1) and | |
750 | the register arguments (R2,R3), respectively. I'm reluctant to define | |
751 | this macro since it stomps on many potential optimisations. Ideally | |
752 | it should have a register class argument so that not all the register | |
753 | classes gets penalised for the sake of a naughty few... For long | |
754 | double arithmetic we need two additional registers that we can use as | |
755 | spill registers. */ | |
cb0ca284 MH |
756 | |
757 | #define SMALL_REGISTER_CLASSES (TARGET_SMALL_REG_CLASS && TARGET_PARALLEL_MPY) | |
758 | ||
759 | #define BASE_REG_CLASS ADDR_REGS | |
760 | #define INDEX_REG_CLASS INDEX_REGS | |
761 | ||
762 | /* | |
2e3e9ead | 763 | Register constraints for the C4x |
cb0ca284 MH |
764 | |
765 | a - address reg (ar0-ar7) | |
766 | b - stack reg (sp) | |
767 | c - other gp int-only reg | |
768 | d - data/int reg (equiv. to f) | |
769 | f - data/float reg | |
770 | h - data/long double reg (equiv. to f) | |
771 | k - block count (bk) | |
772 | q - r0-r7 | |
773 | t - r0-r1 | |
774 | u - r2-r3 | |
d5e4ff48 | 775 | v - repeat count (rc) |
cb0ca284 MH |
776 | x - index register (ir0-ir1) |
777 | y - status register (st) | |
778 | z - dp reg (dp) | |
779 | ||
2e3e9ead MH |
780 | Memory/constant constraints for the C4x |
781 | ||
cb0ca284 MH |
782 | G - short float 16-bit |
783 | I - signed 16-bit constant (sign extended) | |
784 | J - signed 8-bit constant (sign extended) (C4x only) | |
785 | K - signed 5-bit constant (sign extended) (C4x only for stik) | |
786 | L - unsigned 16-bit constant | |
787 | M - unsigned 8-bit constant (C4x only) | |
788 | N - ones complement of unsigned 16-bit constant | |
789 | Q - indirect arx + 9-bit signed displacement | |
790 | (a *-arx(n) or *+arx(n) is used to account for the sign bit) | |
791 | R - indirect arx + 5-bit unsigned displacement (C4x only) | |
792 | S - indirect arx + 0, 1, or irn displacement | |
793 | T - direct symbol ref | |
794 | > - indirect with autoincrement | |
795 | < - indirect with autodecrement | |
796 | } - indirect with post-modify | |
797 | { - indirect with pre-modify | |
798 | */ | |
799 | ||
800 | #define REG_CLASS_FROM_LETTER(CC) \ | |
801 | ( ((CC) == 'a') ? ADDR_REGS \ | |
802 | : ((CC) == 'b') ? SP_REG \ | |
803 | : ((CC) == 'c') ? INT_REGS \ | |
804 | : ((CC) == 'd') ? EXT_REGS \ | |
805 | : ((CC) == 'f') ? EXT_REGS \ | |
806 | : ((CC) == 'h') ? EXT_REGS \ | |
807 | : ((CC) == 'k') ? BK_REG \ | |
808 | : ((CC) == 'q') ? EXT_LOW_REGS \ | |
809 | : ((CC) == 't') ? R0R1_REGS \ | |
810 | : ((CC) == 'u') ? R2R3_REGS \ | |
d5e4ff48 | 811 | : ((CC) == 'v') ? RC_REG \ |
cb0ca284 MH |
812 | : ((CC) == 'x') ? INDEX_REGS \ |
813 | : ((CC) == 'y') ? ST_REG \ | |
814 | : ((CC) == 'z') ? DP_REG \ | |
815 | : NO_REGS ) | |
816 | ||
817 | /* These assume that REGNO is a hard or pseudo reg number. | |
818 | They give nonzero only if REGNO is a hard reg of the suitable class | |
819 | or a pseudo reg currently allocated to a suitable hard reg. | |
820 | Since they use reg_renumber, they are safe only once reg_renumber | |
821 | has been allocated, which happens in local-alloc.c. */ | |
822 | ||
823 | #define REGNO_OK_FOR_BASE_P(REGNO) \ | |
bc46716b | 824 | (IS_ADDR_REGNO(REGNO) || IS_ADDR_REGNO((unsigned)reg_renumber[REGNO])) |
cb0ca284 MH |
825 | |
826 | #define REGNO_OK_FOR_INDEX_P(REGNO) \ | |
bc46716b | 827 | (IS_INDEX_REGNO(REGNO) || IS_INDEX_REGNO((unsigned)reg_renumber[REGNO])) |
cb0ca284 | 828 | |
ed3614cd | 829 | /* If we have to generate framepointer + constant prefer an ADDR_REGS |
31113446 | 830 | register. This avoids using EXT_REGS in addqi3_noclobber_reload. */ |
ed3614cd HB |
831 | |
832 | #define PREFERRED_RELOAD_CLASS(X, CLASS) \ | |
833 | (GET_CODE (X) == PLUS \ | |
834 | && GET_MODE (X) == Pmode \ | |
835 | && GET_CODE (XEXP ((X), 0)) == REG \ | |
836 | && GET_MODE (XEXP ((X), 0)) == Pmode \ | |
837 | && REGNO (XEXP ((X), 0)) == FRAME_POINTER_REGNUM \ | |
838 | && GET_CODE (XEXP ((X), 1)) == CONST_INT \ | |
839 | ? ADDR_REGS : (CLASS)) | |
cb0ca284 | 840 | |
798f6e6f | 841 | #define LIMIT_RELOAD_CLASS(X, CLASS) (CLASS) |
cb0ca284 | 842 | |
798f6e6f | 843 | #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) 0 |
cb0ca284 MH |
844 | |
845 | #define CLASS_MAX_NREGS(CLASS, MODE) \ | |
846 | (((MODE) == CCmode || (MODE) == CC_NOOVmode) ? 1 : ((MODE) == HFmode) ? 1 : \ | |
847 | ((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) | |
848 | ||
975ab131 | 849 | #define IS_INT5_CONST(VAL) (((VAL) <= 15) && ((VAL) >= -16)) /* 'K'. */ |
cb0ca284 | 850 | |
975ab131 | 851 | #define IS_UINT5_CONST(VAL) (((VAL) <= 31) && ((VAL) >= 0)) /* 'R'. */ |
cb0ca284 | 852 | |
975ab131 | 853 | #define IS_INT8_CONST(VAL) (((VAL) <= 127) && ((VAL) >= -128)) /* 'J'. */ |
cb0ca284 | 854 | |
975ab131 | 855 | #define IS_UINT8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= 0)) /* 'M'. */ |
cb0ca284 | 856 | |
975ab131 | 857 | #define IS_INT16_CONST(VAL) (((VAL) <= 32767) && ((VAL) >= -32768)) /* 'I'. */ |
cb0ca284 | 858 | |
975ab131 | 859 | #define IS_UINT16_CONST(VAL) (((VAL) <= 65535) && ((VAL) >= 0)) /* 'L'. */ |
cb0ca284 | 860 | |
975ab131 | 861 | #define IS_NOT_UINT16_CONST(VAL) IS_UINT16_CONST(~(VAL)) /* 'N'. */ |
cb0ca284 | 862 | |
975ab131 MH |
863 | #define IS_HIGH_CONST(VAL) \ |
864 | (! TARGET_C3X && (((VAL) & 0xffff) == 0)) /* 'O'. */ | |
cb0ca284 MH |
865 | |
866 | ||
975ab131 | 867 | #define IS_DISP1_CONST(VAL) (((VAL) <= 1) && ((VAL) >= -1)) /* 'S'. */ |
cb0ca284 | 868 | |
975ab131 | 869 | #define IS_DISP8_CONST(VAL) (((VAL) <= 255) && ((VAL) >= -255)) /* 'Q'. */ |
cb0ca284 MH |
870 | |
871 | #define IS_DISP1_OFF_CONST(VAL) (IS_DISP1_CONST (VAL) \ | |
872 | && IS_DISP1_CONST (VAL + 1)) | |
873 | ||
874 | #define IS_DISP8_OFF_CONST(VAL) (IS_DISP8_CONST (VAL) \ | |
875 | && IS_DISP8_CONST (VAL + 1)) | |
876 | ||
877 | #define CONST_OK_FOR_LETTER_P(VAL, C) \ | |
878 | ( ((C) == 'I') ? (IS_INT16_CONST (VAL)) \ | |
4ddb3ea6 MH |
879 | : ((C) == 'J') ? (! TARGET_C3X && IS_INT8_CONST (VAL)) \ |
880 | : ((C) == 'K') ? (! TARGET_C3X && IS_INT5_CONST (VAL)) \ | |
cb0ca284 | 881 | : ((C) == 'L') ? (IS_UINT16_CONST (VAL)) \ |
4ddb3ea6 | 882 | : ((C) == 'M') ? (! TARGET_C3X && IS_UINT8_CONST (VAL)) \ |
cb0ca284 MH |
883 | : ((C) == 'N') ? (IS_NOT_UINT16_CONST (VAL)) \ |
884 | : ((C) == 'O') ? (IS_HIGH_CONST (VAL)) \ | |
885 | : 0 ) | |
886 | ||
50c33087 | 887 | #define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \ |
798f6e6f | 888 | ( ((C) == 'G') ? (fp_zero_operand (OP, QFmode)) \ |
50c33087 | 889 | : ((C) == 'H') ? (c4x_H_constant (OP)) \ |
cb0ca284 MH |
890 | : 0 ) |
891 | ||
50c33087 MH |
892 | #define EXTRA_CONSTRAINT(OP, C) \ |
893 | ( ((C) == 'Q') ? (c4x_Q_constraint (OP)) \ | |
894 | : ((C) == 'R') ? (c4x_R_constraint (OP)) \ | |
895 | : ((C) == 'S') ? (c4x_S_constraint (OP)) \ | |
896 | : ((C) == 'T') ? (c4x_T_constraint (OP)) \ | |
897 | : ((C) == 'U') ? (c4x_U_constraint (OP)) \ | |
cb0ca284 MH |
898 | : 0 ) |
899 | ||
900 | #define SMALL_CONST(VAL, insn) \ | |
901 | ( ((insn == NULL_RTX) || (get_attr_data (insn) == DATA_INT16)) \ | |
902 | ? IS_INT16_CONST (VAL) \ | |
903 | : ( (get_attr_data (insn) == DATA_NOT_UINT16) \ | |
904 | ? IS_NOT_UINT16_CONST (VAL) \ | |
905 | : ( (get_attr_data (insn) == DATA_HIGH_16) \ | |
906 | ? IS_HIGH_CONST (VAL) \ | |
907 | : IS_UINT16_CONST (VAL) \ | |
908 | ) \ | |
909 | ) \ | |
910 | ) | |
911 | ||
912 | /* | |
913 | I. Routine calling with arguments in registers | |
914 | ---------------------------------------------- | |
915 | ||
916 | The TI C3x compiler has a rather unusual register passing algorithm. | |
917 | Data is passed in the following registers (in order): | |
918 | ||
919 | AR2, R2, R3, RC, RS, RE | |
920 | ||
921 | However, the first and second floating point values are always in R2 | |
922 | and R3 (and all other floats are on the stack). Structs are always | |
923 | passed on the stack. If the last argument is an ellipsis, the | |
924 | previous argument is passed on the stack so that its address can be | |
925 | taken for the stdargs macros. | |
926 | ||
927 | Because of this, we have to pre-scan the list of arguments to figure | |
928 | out what goes where in the list. | |
929 | ||
930 | II. Routine calling with arguments on stack | |
931 | ------------------------------------------- | |
932 | ||
933 | Let the subroutine declared as "foo(arg0, arg1, arg2);" have local | |
934 | variables loc0, loc1, and loc2. After the function prologue has | |
935 | been executed, the stack frame will look like: | |
936 | ||
937 | [stack grows towards increasing addresses] | |
938 | I-------------I | |
939 | 5 I saved reg1 I <= SP points here | |
940 | I-------------I | |
941 | 4 I saved reg0 I | |
942 | I-------------I | |
943 | 3 I loc2 I | |
944 | I-------------I | |
945 | 2 I loc1 I | |
946 | I-------------I | |
947 | 1 I loc0 I | |
948 | I-------------I | |
949 | 0 I old FP I <= FP (AR3) points here | |
950 | I-------------I | |
951 | -1 I return PC I | |
952 | I-------------I | |
953 | -2 I arg0 I | |
954 | I-------------I | |
955 | -3 I arg1 I | |
956 | I-------------I | |
957 | -4 I arg2 I | |
958 | I-------------I | |
959 | ||
960 | All local variables (locn) are accessible by means of +FP(n+1) | |
961 | addressing, where n is the local variable number. | |
962 | ||
963 | All stack arguments (argn) are accessible by means of -FP(n-2). | |
964 | ||
965 | The stack pointer (SP) points to the last register saved in the | |
966 | prologue (regn). | |
967 | ||
968 | Note that a push instruction performs a preincrement of the stack | |
969 | pointer. (STACK_PUSH_CODE == PRE_INC) | |
970 | ||
971 | III. Registers used in function calling convention | |
972 | -------------------------------------------------- | |
973 | ||
974 | Preserved across calls: R4...R5 (only by PUSH, i.e. lower 32 bits) | |
975 | R6...R7 (only by PUSHF, i.e. upper 32 bits) | |
976 | AR3...AR7 | |
977 | ||
978 | (Because of this model, we only assign FP values in R6, R7 and | |
979 | only assign integer values in R4, R5.) | |
980 | ||
981 | These registers are saved at each function entry and restored at | |
982 | the exit. Also it is expected any of these not affected by any | |
983 | call to user-defined (not service) functions. | |
984 | ||
985 | Not preserved across calls: R0...R3 | |
986 | R4...R5 (upper 8 bits) | |
987 | R6...R7 (lower 8 bits) | |
988 | AR0...AR2, IR0, IR1, BK, ST, RS, RE, RC | |
989 | ||
990 | These registers are used arbitrary in a function without being preserved. | |
991 | It is also expected that any of these can be clobbered by any call. | |
992 | ||
993 | Not used by GCC (except for in user "asm" statements): | |
994 | IE (DIE), IF (IIE), IOF (IIF) | |
995 | ||
996 | These registers are never used by GCC for any data, but can be used | |
997 | with "asm" statements. */ | |
998 | ||
999 | #define C4X_ARG0 -2 | |
1000 | #define C4X_LOC0 1 | |
1001 | ||
975ab131 | 1002 | /* Basic Stack Layout. */ |
cb0ca284 MH |
1003 | |
1004 | /* The stack grows upward, stack frame grows upward, and args grow | |
1ac7a7f5 | 1005 | downward. */ |
cb0ca284 MH |
1006 | |
1007 | #define STARTING_FRAME_OFFSET C4X_LOC0 | |
1008 | #define FIRST_PARM_OFFSET(FNDECL) (C4X_ARG0 + 1) | |
1009 | #define ARGS_GROW_DOWNWARD | |
1010 | #define STACK_POINTER_OFFSET 1 | |
1011 | ||
1012 | /* Define this if pushing a word on the stack | |
1013 | makes the stack pointer a smaller address. */ | |
1014 | ||
975ab131 MH |
1015 | /* #define STACK_GROWS_DOWNWARD. */ |
1016 | /* Like the dsp16xx, i370, i960, and we32k ports. */ | |
cb0ca284 MH |
1017 | |
1018 | /* Define this if the nominal address of the stack frame | |
1019 | is at the high-address end of the local variables; | |
1020 | that is, each additional local variable allocated | |
1021 | goes at a more negative offset in the frame. */ | |
1022 | ||
975ab131 | 1023 | /* #define FRAME_GROWS_DOWNWARD. */ |
cb0ca284 MH |
1024 | |
1025 | ||
975ab131 | 1026 | /* Registers That Address the Stack Frame. */ |
cb0ca284 | 1027 | |
975ab131 MH |
1028 | #define STACK_POINTER_REGNUM SP_REGNO /* SP. */ |
1029 | #define FRAME_POINTER_REGNUM AR3_REGNO /* AR3. */ | |
1030 | #define ARG_POINTER_REGNUM AR3_REGNO /* AR3. */ | |
1031 | #define STATIC_CHAIN_REGNUM AR0_REGNO /* AR0. */ | |
cb0ca284 | 1032 | |
975ab131 | 1033 | /* Eliminating Frame Pointer and Arg Pointer. */ |
cb0ca284 MH |
1034 | |
1035 | #define FRAME_POINTER_REQUIRED 0 | |
1036 | ||
1037 | #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ | |
1038 | { \ | |
1039 | int regno; \ | |
1040 | int offset = 0; \ | |
1041 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ | |
4ddb3ea6 | 1042 | if (regs_ever_live[regno] && ! call_used_regs[regno]) \ |
cb0ca284 | 1043 | offset += TARGET_PRESERVE_FLOAT \ |
0b53f039 | 1044 | && IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1; \ |
cb0ca284 MH |
1045 | (DEPTH) = -(offset + get_frame_size ()); \ |
1046 | } | |
1047 | ||
975ab131 | 1048 | /* This is a hack... We need to specify a register. */ |
cb0ca284 MH |
1049 | #define ELIMINABLE_REGS \ |
1050 | {{ FRAME_POINTER_REGNUM, FRAME_POINTER_REGNUM }} | |
1051 | ||
1052 | #define CAN_ELIMINATE(FROM, TO) \ | |
4ddb3ea6 | 1053 | (! (((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ |
cb0ca284 MH |
1054 | || ((FROM) == FRAME_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))) |
1055 | ||
1056 | #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ | |
1057 | { \ | |
1058 | int regno; \ | |
1059 | int offset = 0; \ | |
1060 | for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ | |
4ddb3ea6 | 1061 | if (regs_ever_live[regno] && ! call_used_regs[regno]) \ |
cb0ca284 | 1062 | offset += TARGET_PRESERVE_FLOAT \ |
0b53f039 | 1063 | && IS_FLOAT_CALL_SAVED_REGNO (regno) ? 2 : 1; \ |
cb0ca284 MH |
1064 | (OFFSET) = -(offset + get_frame_size ()); \ |
1065 | } | |
1066 | ||
1067 | ||
975ab131 | 1068 | /* Passing Function Arguments on the Stack. */ |
cb0ca284 | 1069 | |
fcd8fa8b | 1070 | #define PUSH_ARGS 1 |
cb0ca284 | 1071 | #define PUSH_ROUNDING(BYTES) (BYTES) |
cb0ca284 MH |
1072 | #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0 |
1073 | ||
975ab131 | 1074 | /* The following structure is used by calls.c, function.c, c4x.c. */ |
cb0ca284 MH |
1075 | |
1076 | typedef struct c4x_args | |
1077 | { | |
1078 | int floats; | |
1079 | int ints; | |
1080 | int maxfloats; | |
1081 | int maxints; | |
1082 | int init; | |
1083 | int var; | |
1084 | int prototype; | |
1085 | int args; | |
1086 | } | |
1087 | CUMULATIVE_ARGS; | |
1088 | ||
cb0ca284 MH |
1089 | #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ |
1090 | (c4x_init_cumulative_args (&CUM, FNTYPE, LIBNAME)) | |
1091 | ||
cb0ca284 MH |
1092 | #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ |
1093 | (c4x_function_arg_advance (&CUM, MODE, TYPE, NAMED)) | |
1094 | ||
cb0ca284 MH |
1095 | #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ |
1096 | (c4x_function_arg(&CUM, MODE, TYPE, NAMED)) | |
1097 | ||
1098 | /* Define the profitability of saving registers around calls. | |
ad3781e1 MH |
1099 | We disable caller save to avoid a bug in flow.c (this also affects |
1100 | other targets such as m68k). Since we must use stf/sti, | |
1101 | the profitability is marginal anyway. */ | |
cb0ca284 | 1102 | |
6ee96de6 | 1103 | #define CALLER_SAVE_PROFITABLE(REFS,CALLS) 0 |
cb0ca284 MH |
1104 | |
1105 | /* Never pass data by reference. */ | |
1106 | ||
1107 | #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) 0 | |
1108 | ||
1109 | #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0 | |
1110 | ||
1ac7a7f5 | 1111 | /* 1 if N is a possible register number for function argument passing. */ |
cb0ca284 MH |
1112 | |
1113 | #define FUNCTION_ARG_REGNO_P(REGNO) \ | |
975ab131 MH |
1114 | ( ( ((REGNO) == AR2_REGNO) /* AR2. */ \ |
1115 | || ((REGNO) == R2_REGNO) /* R2. */ \ | |
1116 | || ((REGNO) == R3_REGNO) /* R3. */ \ | |
1117 | || ((REGNO) == RC_REGNO) /* RC. */ \ | |
1118 | || ((REGNO) == RS_REGNO) /* RS. */ \ | |
1119 | || ((REGNO) == RE_REGNO)) /* RE. */ \ | |
cb0ca284 MH |
1120 | ? 1 \ |
1121 | : 0) | |
1122 | ||
975ab131 | 1123 | /* How Scalar Function Values Are Returned. */ |
cb0ca284 MH |
1124 | |
1125 | #define FUNCTION_VALUE(VALTYPE, FUNC) \ | |
975ab131 | 1126 | gen_rtx(REG, TYPE_MODE(VALTYPE), R0_REGNO) /* Return in R0. */ |
cb0ca284 MH |
1127 | |
1128 | #define LIBCALL_VALUE(MODE) \ | |
975ab131 | 1129 | gen_rtx(REG, MODE, R0_REGNO) /* Return in R0. */ |
cb0ca284 MH |
1130 | |
1131 | #define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == R0_REGNO) | |
1132 | ||
975ab131 | 1133 | /* How Large Values Are Returned. */ |
cb0ca284 MH |
1134 | |
1135 | #define DEFAULT_PCC_STRUCT_RETURN 0 | |
975ab131 | 1136 | #define STRUCT_VALUE_REGNUM AR0_REGNO /* AR0. */ |
cb0ca284 | 1137 | |
cc7fd398 RH |
1138 | /* Varargs handling. */ |
1139 | ||
634f1f20 MH |
1140 | #define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \ |
1141 | c4x_va_start (stdarg, valist, nextarg) | |
1142 | ||
cc7fd398 RH |
1143 | #define EXPAND_BUILTIN_VA_ARG(valist, type) \ |
1144 | c4x_va_arg (valist, type) | |
cb0ca284 | 1145 | |
975ab131 | 1146 | /* Generating Code for Profiling. */ |
cb0ca284 MH |
1147 | |
1148 | /* Note that the generated assembly uses the ^ operator to load the 16 | |
ce577467 MH |
1149 | MSBs of the address. This is not supported by the TI assembler. |
1150 | The FUNCTION profiler needs a function mcount which gets passed | |
1151 | a pointer to the LABELNO. */ | |
cb0ca284 MH |
1152 | |
1153 | #define FUNCTION_PROFILER(FILE, LABELNO) \ | |
4ddb3ea6 | 1154 | if (! TARGET_C3X) \ |
cb0ca284 MH |
1155 | { \ |
1156 | fprintf (FILE, "\tpush\tar2\n"); \ | |
1157 | fprintf (FILE, "\tldhi\t^LP%d,ar2\n", (LABELNO)); \ | |
1158 | fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO)); \ | |
1159 | fprintf (FILE, "\tcall\tmcount\n"); \ | |
1160 | fprintf (FILE, "\tpop\tar2\n"); \ | |
1161 | } \ | |
1162 | else \ | |
1163 | { \ | |
1164 | fprintf (FILE, "\tpush\tar2\n"); \ | |
1165 | fprintf (FILE, "\tldiu\t^LP%d,ar2\n", (LABELNO)); \ | |
1166 | fprintf (FILE, "\tlsh\t16,ar2\n"); \ | |
1167 | fprintf (FILE, "\tor\t#LP%d,ar2\n", (LABELNO)); \ | |
1168 | fprintf (FILE, "\tcall\tmcount\n"); \ | |
1169 | fprintf (FILE, "\tpop\tar2\n"); \ | |
1170 | } | |
1171 | ||
975ab131 | 1172 | /* Implicit Calls to Library Routines. */ |
cb0ca284 MH |
1173 | |
1174 | #define MULQI3_LIBCALL "__mulqi3" | |
1175 | #define DIVQI3_LIBCALL "__divqi3" | |
1176 | #define UDIVQI3_LIBCALL "__udivqi3" | |
1177 | #define MODQI3_LIBCALL "__modqi3" | |
1178 | #define UMODQI3_LIBCALL "__umodqi3" | |
1179 | ||
1180 | #define DIVQF3_LIBCALL "__divqf3" | |
1181 | ||
1182 | #define MULHF3_LIBCALL "__mulhf3" | |
1183 | #define DIVHF3_LIBCALL "__divhf3" | |
1184 | ||
1185 | #define MULHI3_LIBCALL "__mulhi3" | |
1186 | #define SMULHI3_LIBCALL "__smulhi3_high" | |
1187 | #define UMULHI3_LIBCALL "__umulhi3_high" | |
1188 | #define DIVHI3_LIBCALL "__divhi3" | |
1189 | #define UDIVHI3_LIBCALL "__udivhi3" | |
1190 | #define MODHI3_LIBCALL "__modhi3" | |
1191 | #define UMODHI3_LIBCALL "__umodhi3" | |
1192 | ||
1193 | #define FLOATHIQF2_LIBCALL "__floathiqf2" | |
1194 | #define FLOATUNSHIQF2_LIBCALL "__ufloathiqf2" | |
1195 | #define FIX_TRUNCQFHI2_LIBCALL "__fix_truncqfhi2" | |
1196 | #define FIXUNS_TRUNCQFHI2_LIBCALL "__ufix_truncqfhi2" | |
1197 | ||
1198 | #define FLOATHIHF2_LIBCALL "__floathihf2" | |
1199 | #define FLOATUNSHIHF2_LIBCALL "__ufloathihf2" | |
1200 | #define FIX_TRUNCHFHI2_LIBCALL "__fix_trunchfhi2" | |
1201 | #define FIXUNS_TRUNCHFHI2_LIBCALL "__ufix_trunchfhi2" | |
1202 | ||
1203 | #define FFS_LIBCALL "__ffs" | |
1204 | ||
f42850b9 MH |
1205 | #define INIT_TARGET_OPTABS \ |
1206 | do { \ | |
1207 | smul_optab->handlers[(int) QImode].libfunc \ | |
1208 | = init_one_libfunc (MULQI3_LIBCALL); \ | |
1209 | sdiv_optab->handlers[(int) QImode].libfunc \ | |
1210 | = init_one_libfunc (DIVQI3_LIBCALL); \ | |
1211 | udiv_optab->handlers[(int) QImode].libfunc \ | |
1212 | = init_one_libfunc (UDIVQI3_LIBCALL); \ | |
1213 | smod_optab->handlers[(int) QImode].libfunc \ | |
1214 | = init_one_libfunc (MODQI3_LIBCALL); \ | |
1215 | umod_optab->handlers[(int) QImode].libfunc \ | |
1216 | = init_one_libfunc (UMODQI3_LIBCALL); \ | |
ef89d648 | 1217 | sdiv_optab->handlers[(int) QFmode].libfunc \ |
f42850b9 MH |
1218 | = init_one_libfunc (DIVQF3_LIBCALL); \ |
1219 | smul_optab->handlers[(int) HFmode].libfunc \ | |
1220 | = init_one_libfunc (MULHF3_LIBCALL); \ | |
ef89d648 | 1221 | sdiv_optab->handlers[(int) HFmode].libfunc \ |
f42850b9 MH |
1222 | = init_one_libfunc (DIVHF3_LIBCALL); \ |
1223 | smul_optab->handlers[(int) HImode].libfunc \ | |
1224 | = init_one_libfunc (MULHI3_LIBCALL); \ | |
1225 | sdiv_optab->handlers[(int) HImode].libfunc \ | |
1226 | = init_one_libfunc (DIVHI3_LIBCALL); \ | |
1227 | udiv_optab->handlers[(int) HImode].libfunc \ | |
1228 | = init_one_libfunc (UDIVHI3_LIBCALL); \ | |
1229 | smod_optab->handlers[(int) HImode].libfunc \ | |
1230 | = init_one_libfunc (MODHI3_LIBCALL); \ | |
1231 | umod_optab->handlers[(int) HImode].libfunc \ | |
1232 | = init_one_libfunc (UMODHI3_LIBCALL); \ | |
1233 | ffs_optab->handlers[(int) QImode].libfunc \ | |
1234 | = init_one_libfunc (FFS_LIBCALL); \ | |
4fda2521 HB |
1235 | smulhi3_libfunc \ |
1236 | = init_one_libfunc(SMULHI3_LIBCALL); \ | |
1237 | umulhi3_libfunc \ | |
1238 | = init_one_libfunc(UMULHI3_LIBCALL); \ | |
1239 | fix_truncqfhi2_libfunc \ | |
1240 | = init_one_libfunc(FIX_TRUNCQFHI2_LIBCALL); \ | |
1241 | fixuns_truncqfhi2_libfunc \ | |
1242 | = init_one_libfunc(FIXUNS_TRUNCQFHI2_LIBCALL); \ | |
1243 | fix_trunchfhi2_libfunc \ | |
1244 | = init_one_libfunc(FIX_TRUNCHFHI2_LIBCALL); \ | |
1245 | fixuns_trunchfhi2_libfunc \ | |
1246 | = init_one_libfunc(FIXUNS_TRUNCHFHI2_LIBCALL); \ | |
1247 | floathiqf2_libfunc \ | |
1248 | = init_one_libfunc(FLOATHIQF2_LIBCALL); \ | |
1249 | floatunshiqf2_libfunc \ | |
1250 | = init_one_libfunc(FLOATUNSHIQF2_LIBCALL); \ | |
1251 | floathihf2_libfunc \ | |
1252 | = init_one_libfunc(FLOATHIHF2_LIBCALL); \ | |
1253 | floatunshihf2_libfunc \ | |
1254 | = init_one_libfunc(FLOATUNSHIHF2_LIBCALL); \ | |
f42850b9 MH |
1255 | } while (0) |
1256 | ||
cb0ca284 MH |
1257 | #define TARGET_MEM_FUNCTIONS |
1258 | ||
1259 | /* Add any extra modes needed to represent the condition code. | |
1260 | ||
1261 | On the C4x, we have a "no-overflow" mode which is used when an ADD, | |
1262 | SUB, NEG, or MPY insn is used to set the condition code. This is | |
1263 | to prevent the combiner from optimising away a following CMP of the | |
1264 | result with zero when a signed conditional branch or load insn | |
1265 | follows. | |
1266 | ||
1267 | The problem is a subtle one and deals with the manner in which the | |
1268 | negative condition (N) flag is used on the C4x. This flag does not | |
1269 | reflect the status of the actual result but of the ideal result had | |
f5143c46 | 1270 | no overflow occurred (when considering signed operands). |
cb0ca284 MH |
1271 | |
1272 | For example, 0x7fffffff + 1 => 0x80000000 Z=0 V=1 N=0 C=0. Here | |
1273 | the flags reflect the untruncated result, not the actual result. | |
1274 | While the actual result is less than zero, the N flag is not set | |
1275 | since the ideal result of the addition without truncation would | |
1276 | have been positive. | |
1277 | ||
1278 | Note that the while the N flag is handled differently to most other | |
1279 | architectures, the use of it is self consistent and is not the | |
1280 | cause of the problem. | |
1281 | ||
1282 | Logical operations set the N flag to the MSB of the result so if | |
1283 | the result is negative, N is 1. However, integer and floating | |
1284 | point operations set the N flag to be the MSB of the result | |
1285 | exclusive ored with the overflow (V) flag. Thus if an overflow | |
1286 | occurs and the result does not have the MSB set (i.e., the result | |
1287 | looks like a positive number), the N flag is set. Conversely, if | |
1288 | an overflow occurs and the MSB of the result is set, N is set to 0. | |
1289 | Thus the N flag represents the sign of the result if it could have | |
1290 | been stored without overflow but does not represent the apparent | |
1291 | sign of the result. Note that most architectures set the N flag to | |
1292 | be the MSB of the result. | |
1293 | ||
1294 | The C4x approach to setting the N flag simplifies signed | |
1295 | conditional branches and loads which only have to test the state of | |
1296 | the N flag, whereas most architectures have to look at both the N | |
1297 | and V flags. The disadvantage is that there is no flag giving the | |
1298 | status of the sign bit of the operation. However, there are no | |
1299 | conditional load or branch instructions that make use of this | |
1300 | feature (e.g., BMI---branch minus) instruction. Note that BN and | |
1301 | BLT are identical in the C4x. | |
1302 | ||
1303 | To handle the problem where the N flag is set differently whenever | |
1304 | there is an overflow we use a different CC mode, CC_NOOVmode which | |
1305 | says that the CC reflects the comparison of the result against zero | |
f5143c46 | 1306 | if no overflow occurred. |
cb0ca284 MH |
1307 | |
1308 | For example, | |
1309 | ||
1310 | [(set (reg:CC_NOOV 21) | |
1311 | (compare:CC_NOOV (minus:QI (match_operand:QI 1 "src_operand" "") | |
1312 | (match_operand:QI 2 "src_operand" "")) | |
1313 | (const_int 0))) | |
1314 | (set (match_operand:QI 0 "ext_reg_operand" "") | |
1315 | (minus:QI (match_dup 1) | |
1316 | (match_dup 2)))] | |
1317 | ||
1318 | Note that there is no problem for insns that don't return a result | |
1319 | like CMP, since the CC reflects the effect of operation. | |
1320 | ||
1321 | An example of a potential problem is when GCC | |
1322 | converts (LTU (MINUS (0x80000000) (0x7fffffff) (0x80000000))) | |
1323 | to (LEU (MINUS (0x80000000) (0x7fffffff) (0x7fffffff))) | |
1324 | to (GE (MINUS (0x80000000) (0x7fffffff) (0x00000000))) | |
1325 | ||
1326 | Now (MINUS (0x80000000) (0x7fffffff)) returns 0x00000001 but the | |
1327 | C4x sets the N flag since the result without overflow would have | |
1328 | been 0xffffffff when treating the operands as signed integers. | |
1329 | Thus (GE (MINUS (0x80000000) (0x7fffffff) (0x00000000))) sets the N | |
1330 | flag but (GE (0x00000001)) does not set the N flag. | |
1331 | ||
1332 | The upshot is that we can not use signed branch and conditional | |
1333 | load instructions after an add, subtract, neg, abs or multiply. | |
1334 | We must emit a compare insn to check the result against 0. */ | |
1335 | ||
aa0b4465 | 1336 | #define EXTRA_CC_MODES CC(CC_NOOVmode, "CC_NOOV") |
cb0ca284 MH |
1337 | |
1338 | /* CC_NOOVmode should be used when the first operand is a PLUS, MINUS, NEG | |
1339 | or MULT. | |
1ac7a7f5 | 1340 | CCmode should be used when no special processing is needed. */ |
cb0ca284 MH |
1341 | #define SELECT_CC_MODE(OP,X,Y) \ |
1342 | ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \ | |
1343 | || GET_CODE (X) == NEG || GET_CODE (X) == MULT \ | |
1344 | || GET_MODE (X) == ABS \ | |
1345 | || GET_CODE (Y) == PLUS || GET_CODE (Y) == MINUS \ | |
1346 | || GET_CODE (Y) == NEG || GET_CODE (Y) == MULT \ | |
1347 | || GET_MODE (Y) == ABS) \ | |
1348 | ? CC_NOOVmode : CCmode) | |
1349 | ||
975ab131 | 1350 | /* Addressing Modes. */ |
cb0ca284 | 1351 | |
940da324 JL |
1352 | #define HAVE_POST_INCREMENT 1 |
1353 | #define HAVE_PRE_INCREMENT 1 | |
1354 | #define HAVE_POST_DECREMENT 1 | |
1355 | #define HAVE_PRE_DECREMENT 1 | |
1356 | #define HAVE_PRE_MODIFY_REG 1 | |
1357 | #define HAVE_POST_MODIFY_REG 1 | |
1358 | #define HAVE_PRE_MODIFY_DISP 1 | |
1359 | #define HAVE_POST_MODIFY_DISP 1 | |
cb0ca284 | 1360 | |
4adf744b | 1361 | /* The number of insns that can be packed into a single opcode. */ |
ce577467 | 1362 | #define PACK_INSNS 2 |
4adf744b MH |
1363 | |
1364 | /* Recognize any constant value that is a valid address. | |
1365 | We could allow arbitrary constant addresses in the large memory | |
1366 | model but for the small memory model we can only accept addresses | |
1367 | within the data page. I suppose we could also allow | |
1368 | CONST PLUS SYMBOL_REF. */ | |
cb0ca284 MH |
1369 | #define CONSTANT_ADDRESS_P(X) (GET_CODE (X) == SYMBOL_REF) |
1370 | ||
4adf744b MH |
1371 | /* Maximum number of registers that can appear in a valid memory |
1372 | address. */ | |
cb0ca284 MH |
1373 | #define MAX_REGS_PER_ADDRESS 2 |
1374 | ||
1375 | /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx | |
1376 | and check its validity for a certain class. | |
1377 | We have two alternate definitions for each of them. | |
1378 | The usual definition accepts all pseudo regs; the other rejects | |
1379 | them unless they have been allocated suitable hard regs. | |
1380 | The symbol REG_OK_STRICT causes the latter definition to be used. | |
1381 | ||
1382 | Most source files want to accept pseudo regs in the hope that | |
1383 | they will get allocated to the class that the insn wants them to be in. | |
1384 | Source files for reload pass need to be strict. | |
1385 | After reload, it makes no difference, since pseudo regs have | |
1386 | been eliminated by then. */ | |
1387 | ||
cb0ca284 MH |
1388 | #ifndef REG_OK_STRICT |
1389 | ||
1390 | /* Nonzero if X is a hard or pseudo reg that can be used as an base. */ | |
1391 | ||
bc46716b | 1392 | #define REG_OK_FOR_BASE_P(X) IS_ADDR_OR_PSEUDO_REG(X) |
cb0ca284 MH |
1393 | |
1394 | /* Nonzero if X is a hard or pseudo reg that can be used as an index. */ | |
1395 | ||
bc46716b | 1396 | #define REG_OK_FOR_INDEX_P(X) IS_INDEX_OR_PSEUDO_REG(X) |
cb0ca284 MH |
1397 | |
1398 | #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ | |
1399 | { \ | |
1400 | if (c4x_check_legit_addr (MODE, X, 0)) \ | |
1401 | goto ADDR; \ | |
1402 | } | |
1403 | ||
1404 | #else | |
1405 | ||
1406 | /* Nonzero if X is a hard reg that can be used as an index. */ | |
1407 | ||
1408 | #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) | |
1409 | ||
1410 | /* Nonzero if X is a hard reg that can be used as a base reg. */ | |
1411 | ||
1412 | #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) | |
1413 | ||
1414 | #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ | |
1415 | { \ | |
1416 | if (c4x_check_legit_addr (MODE, X, 1)) \ | |
1417 | goto ADDR; \ | |
1418 | } | |
1419 | ||
1420 | #endif | |
1421 | ||
cb0ca284 MH |
1422 | #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ |
1423 | { \ | |
1424 | rtx new; \ | |
1425 | new = c4x_legitimize_address (X, MODE); \ | |
1426 | if (new != NULL_RTX) \ | |
1427 | { \ | |
1428 | (X) = new; \ | |
1429 | goto WIN; \ | |
1430 | } \ | |
1431 | } | |
1432 | ||
31445126 MH |
1433 | #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ |
1434 | { \ | |
eb253d90 HB |
1435 | if (MODE != HImode \ |
1436 | && MODE != HFmode \ | |
1437 | && GET_MODE (X) != HImode \ | |
1438 | && GET_MODE (X) != HFmode \ | |
1439 | && (GET_CODE (X) == CONST \ | |
1440 | || GET_CODE (X) == SYMBOL_REF \ | |
1441 | || GET_CODE (X) == LABEL_REF)) \ | |
1442 | { \ | |
1443 | if (! TARGET_SMALL) \ | |
1444 | { \ | |
1445 | int i; \ | |
1446 | X = gen_rtx_LO_SUM (GET_MODE (X), \ | |
1447 | gen_rtx_HIGH (GET_MODE (X), X), X); \ | |
1448 | i = push_reload (XEXP (X, 0), NULL_RTX, \ | |
df4ae160 | 1449 | &XEXP (X, 0), NULL, \ |
eb253d90 HB |
1450 | DP_REG, GET_MODE (X), VOIDmode, 0, 0, \ |
1451 | OPNUM, TYPE); \ | |
1452 | /* The only valid reg is DP. This is a fixed reg and will \ | |
1453 | normally not be used so force it. */ \ | |
1454 | rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); \ | |
1455 | rld[i].nocombine = 1; \ | |
1456 | } \ | |
1457 | goto WIN; \ | |
1458 | } \ | |
1459 | else if (MODE != HImode \ | |
1460 | && MODE != HFmode \ | |
1461 | && GET_MODE (X) != HImode \ | |
1462 | && GET_MODE (X) != HFmode \ | |
1463 | && GET_CODE (X) == LO_SUM \ | |
1464 | && GET_CODE (XEXP (X,0)) == HIGH \ | |
1465 | && (GET_CODE (XEXP (XEXP (X,0),0)) == CONST \ | |
1466 | || GET_CODE (XEXP (XEXP (X,0),0)) == SYMBOL_REF \ | |
1467 | || GET_CODE (XEXP (XEXP (X,0),0)) == LABEL_REF)) \ | |
1468 | { \ | |
1469 | if (! TARGET_SMALL) \ | |
1470 | { \ | |
1471 | int i = push_reload (XEXP (X, 0), NULL_RTX, \ | |
df4ae160 | 1472 | &XEXP (X, 0), NULL, \ |
eb253d90 HB |
1473 | DP_REG, GET_MODE (X), VOIDmode, 0, 0, \ |
1474 | OPNUM, TYPE); \ | |
1475 | /* The only valid reg is DP. This is a fixed reg and will \ | |
1476 | normally not be used so force it. */ \ | |
1477 | rld[i].reg_rtx = gen_rtx_REG (Pmode, DP_REGNO); \ | |
1478 | rld[i].nocombine = 1; \ | |
1479 | } \ | |
1480 | goto WIN; \ | |
1481 | } \ | |
31445126 MH |
1482 | } |
1483 | ||
cb0ca284 MH |
1484 | /* No mode-dependent addresses on the C4x are autoincrements. */ |
1485 | ||
1486 | #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ | |
1487 | if (GET_CODE (ADDR) == PRE_DEC \ | |
1488 | || GET_CODE (ADDR) == POST_DEC \ | |
1489 | || GET_CODE (ADDR) == PRE_INC \ | |
1490 | || GET_CODE (ADDR) == POST_INC \ | |
1491 | || GET_CODE (ADDR) == POST_MODIFY \ | |
1492 | || GET_CODE (ADDR) == PRE_MODIFY) \ | |
1493 | goto LABEL | |
1494 | ||
1495 | ||
1496 | /* Nonzero if the constant value X is a legitimate general operand. | |
1497 | It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. | |
1498 | ||
50c33087 MH |
1499 | The C4x can only load 16-bit immediate values, so we only allow a |
1500 | restricted subset of CONST_INT and CONST_DOUBLE. Disallow | |
1501 | LABEL_REF and SYMBOL_REF (except on the C40 with the big memory | |
1502 | model) so that the symbols will be forced into the constant pool. | |
31445126 MH |
1503 | On second thoughts, let's do this with the move expanders since |
1504 | the alias analysis has trouble if we force constant addresses | |
1505 | into memory. | |
50c33087 | 1506 | */ |
cb0ca284 MH |
1507 | |
1508 | #define LEGITIMATE_CONSTANT_P(X) \ | |
d5e4ff48 | 1509 | ((GET_CODE (X) == CONST_DOUBLE && c4x_H_constant (X)) \ |
483dd5be | 1510 | || (GET_CODE (X) == CONST_INT) \ |
50c33087 MH |
1511 | || (GET_CODE (X) == SYMBOL_REF) \ |
1512 | || (GET_CODE (X) == LABEL_REF) \ | |
1513 | || (GET_CODE (X) == CONST) \ | |
1514 | || (GET_CODE (X) == HIGH && ! TARGET_C3X) \ | |
1515 | || (GET_CODE (X) == LO_SUM && ! TARGET_C3X)) | |
cb0ca284 MH |
1516 | |
1517 | #define LEGITIMATE_DISPLACEMENT_P(X) IS_DISP8_CONST (INTVAL (X)) | |
1518 | ||
50c33087 MH |
1519 | /* Define this macro if references to a symbol must be treated |
1520 | differently depending on something about the variable or | |
1521 | function named by the symbol (such as what section it is in). | |
1522 | ||
1523 | The macro definition, if any, is executed immediately after the | |
1524 | rtl for DECL or other node is created. | |
1525 | The value of the rtl will be a `mem' whose address is a | |
1526 | `symbol_ref'. | |
1527 | ||
1528 | The usual thing for this macro to do is to a flag in the | |
1529 | `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified | |
1530 | name string in the `symbol_ref' (if one bit is not enough | |
1531 | information). | |
1532 | ||
1533 | On the C4x we use this to indicate if a symbol is in text or | |
1534 | data space. */ | |
1535 | ||
b2003250 | 1536 | #define ENCODE_SECTION_INFO(DECL, FIRST) c4x_encode_section_info (DECL, FIRST); |
50c33087 | 1537 | |
975ab131 | 1538 | /* Descripting Relative Cost of Operations. */ |
cb0ca284 MH |
1539 | |
1540 | /* Provide the costs of a rtl expression. This is in the body of a | |
1541 | switch on CODE. | |
1542 | ||
1543 | Note that we return, rather than break so that rtx_cost doesn't | |
1544 | include CONST_COSTS otherwise expand_mult will think that it is | |
1545 | cheaper to synthesise a multiply rather than to use a multiply | |
1546 | instruction. I think this is because the algorithm synth_mult | |
1547 | doesn't take into account the loading of the operands, whereas the | |
1548 | calculation of mult_cost does. | |
1549 | */ | |
1550 | ||
1551 | ||
1552 | #define RTX_COSTS(RTX, CODE, OUTER_CODE) \ | |
9acfe55c MH |
1553 | case PLUS: \ |
1554 | case MINUS: \ | |
1555 | case AND: \ | |
1556 | case IOR: \ | |
1557 | case XOR: \ | |
1558 | case ASHIFT: \ | |
1559 | case ASHIFTRT: \ | |
1560 | case LSHIFTRT: \ | |
1561 | return COSTS_N_INSNS (1); \ | |
cb0ca284 MH |
1562 | case MULT: \ |
1563 | return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \ | |
1564 | || TARGET_MPYI ? 1 : 14); \ | |
9acfe55c MH |
1565 | case DIV: \ |
1566 | case UDIV: \ | |
1567 | case MOD: \ | |
1568 | case UMOD: \ | |
cb0ca284 MH |
1569 | return COSTS_N_INSNS (GET_MODE_CLASS (GET_MODE (RTX)) == MODE_FLOAT \ |
1570 | ? 15 : 50); | |
1571 | ||
1572 | /* Compute the cost of computing a constant rtl expression RTX | |
1573 | whose rtx-code is CODE. The body of this macro is a portion | |
1574 | of a switch statement. If the code is computed here, | |
1575 | return it with a return statement. Otherwise, break from the switch. | |
1576 | ||
1577 | An insn is assumed to cost 4 units. | |
1578 | COSTS_N_INSNS (N) is defined as (N) * 4 - 2. | |
1579 | ||
1580 | Some small integers are effectively free for the C40. We should | |
1581 | also consider if we are using the small memory model. With | |
1582 | the big memory model we require an extra insn for a constant | |
87ba6944 MH |
1583 | loaded from memory. |
1584 | ||
1585 | This is used by expand_binop to decide whether to force a constant | |
1586 | into a register. If the cost is greater than 2 and the constant | |
1587 | is used within a short loop, it gets forced into a register. | |
1588 | Ideally, there should be some weighting as to how mnay times it is used | |
1589 | within the loop. */ | |
cb0ca284 MH |
1590 | |
1591 | #define SHIFT_CODE_P(C) ((C) == ASHIFT || (C) == ASHIFTRT || (C) == LSHIFTRT) | |
1592 | ||
1593 | #define LOGICAL_CODE_P(C) ((C) == NOT || (C) == AND \ | |
1594 | || (C) == IOR || (C) == XOR) | |
1595 | ||
1596 | #define NON_COMMUTATIVE_CODE_P ((C) == MINUS || (C) == COMPARE) | |
1597 | ||
1598 | #define CONST_COSTS(RTX,CODE,OUTER_CODE) \ | |
1599 | case CONST_INT: \ | |
1600 | if (c4x_J_constant (RTX)) \ | |
1601 | return 0; \ | |
87ba6944 MH |
1602 | if (! TARGET_C3X \ |
1603 | && OUTER_CODE == AND \ | |
1604 | && GET_CODE (RTX) == CONST_INT \ | |
1605 | && (INTVAL (RTX) == 255 || INTVAL (RTX) == 65535)) \ | |
1606 | return 0; \ | |
1607 | if (! TARGET_C3X \ | |
1608 | && (OUTER_CODE == ASHIFTRT || OUTER_CODE == LSHIFTRT) \ | |
1609 | && GET_CODE (RTX) == CONST_INT \ | |
1610 | && (INTVAL (RTX) == 16 || INTVAL (RTX) == 24)) \ | |
1611 | return 0; \ | |
cb0ca284 MH |
1612 | if (TARGET_C3X && SHIFT_CODE_P (OUTER_CODE)) \ |
1613 | return 3; \ | |
1614 | if (LOGICAL_CODE_P (OUTER_CODE) \ | |
1615 | ? c4x_L_constant (RTX) : c4x_I_constant (RTX)) \ | |
1616 | return 2; \ | |
1617 | case CONST: \ | |
1618 | case LABEL_REF: \ | |
1619 | case SYMBOL_REF: \ | |
1620 | return 4; \ | |
1621 | case CONST_DOUBLE: \ | |
1622 | if (c4x_H_constant (RTX)) \ | |
1623 | return 2; \ | |
1624 | if (GET_MODE (RTX) == QFmode) \ | |
1625 | return 4; \ | |
1626 | else \ | |
1627 | return 8; | |
1628 | ||
1629 | /* Compute the cost of an address. This is meant to approximate the size | |
1630 | and/or execution delay of an insn using that address. If the cost is | |
1631 | approximated by the RTL complexity, including CONST_COSTS above, as | |
1632 | is usually the case for CISC machines, this macro should not be defined. | |
1633 | For aggressively RISCy machines, only one insn format is allowed, so | |
1634 | this macro should be a constant. The value of this macro only matters | |
1635 | for valid addresses. We handle the most common address without | |
1636 | a call to c4x_address_cost. */ | |
1637 | ||
cb0ca284 MH |
1638 | #define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : c4x_address_cost (ADDR)) |
1639 | ||
1640 | #define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \ | |
1641 | if (REG_P (OP1) && ! REG_P (OP0)) \ | |
1642 | { \ | |
1643 | rtx tmp = OP0; OP0 = OP1 ; OP1 = tmp; \ | |
1644 | CODE = swap_condition (CODE); \ | |
1645 | } | |
1646 | ||
1647 | #define EXT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, EXT_REGS)) | |
1648 | #define ADDR_CLASS_P(CLASS) (reg_class_subset_p (CLASS, ADDR_REGS)) | |
1649 | #define INDEX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, INDEX_REGS)) | |
1650 | #define EXPENSIVE_CLASS_P(CLASS) (ADDR_CLASS_P(CLASS) \ | |
1651 | || INDEX_CLASS_P(CLASS) || (CLASS) == SP_REG) | |
1652 | ||
5e6a42d9 MH |
1653 | /* Compute extra cost of moving data between one register class |
1654 | and another. */ | |
cb0ca284 | 1655 | |
cf011243 | 1656 | #define REGISTER_MOVE_COST(MODE, FROM, TO) 2 |
cb0ca284 MH |
1657 | |
1658 | /* Memory move cost is same as fast register move. Maybe this should | |
975ab131 | 1659 | be bumped up?. */ |
cb0ca284 MH |
1660 | |
1661 | #define MEMORY_MOVE_COST(M,C,I) 4 | |
1662 | ||
1663 | /* Branches are kind of expensive (even with delayed branching) so | |
1664 | make their cost higher. */ | |
1665 | ||
1666 | #define BRANCH_COST 8 | |
1667 | ||
cb0ca284 MH |
1668 | #define WORD_REGISTER_OPERATIONS |
1669 | ||
1ac7a7f5 | 1670 | /* Dividing the Output into Sections. */ |
cb0ca284 MH |
1671 | |
1672 | #define TEXT_SECTION_ASM_OP "\t.text" | |
1673 | ||
1674 | #define DATA_SECTION_ASM_OP "\t.data" | |
1675 | ||
1676 | #define USE_CONST_SECTION 1 | |
1677 | ||
1678 | #define CONST_SECTION_ASM_OP "\t.sect\t\".const\"" | |
1679 | ||
1680 | /* Do not use .init section so __main will be called on startup. This will | |
1ac7a7f5 | 1681 | call __do_global_ctors and prepare for __do_global_dtors on exit. */ |
cb0ca284 MH |
1682 | |
1683 | #if 0 | |
1684 | #define INIT_SECTION_ASM_OP "\t.sect\t\".init\"" | |
1685 | #endif | |
1686 | ||
1687 | #define FINI_SECTION_ASM_OP "\t.sect\t\".fini\"" | |
1688 | ||
cb0ca284 | 1689 | #undef EXTRA_SECTIONS |
2cc07db4 | 1690 | #define EXTRA_SECTIONS in_const, in_init, in_fini |
cb0ca284 MH |
1691 | |
1692 | #undef EXTRA_SECTION_FUNCTIONS | |
1693 | #define EXTRA_SECTION_FUNCTIONS \ | |
1694 | CONST_SECTION_FUNCTION \ | |
1695 | INIT_SECTION_FUNCTION \ | |
2cc07db4 | 1696 | FINI_SECTION_FUNCTION |
cb0ca284 MH |
1697 | |
1698 | #define INIT_SECTION_FUNCTION \ | |
1943c2c1 | 1699 | extern void init_section PARAMS ((void)); \ |
cb0ca284 MH |
1700 | void \ |
1701 | init_section () \ | |
1702 | { \ | |
1703 | if (in_section != in_init) \ | |
1704 | { \ | |
1705 | fprintf (asm_out_file, ";\t.init\n"); \ | |
1706 | in_section = in_init; \ | |
1707 | } \ | |
1708 | } | |
1709 | ||
1710 | #define FINI_SECTION_FUNCTION \ | |
1711 | void \ | |
1712 | fini_section () \ | |
1713 | { \ | |
1714 | if (in_section != in_fini) \ | |
1715 | { \ | |
8802136f | 1716 | fprintf (asm_out_file, "%s\n", FINI_SECTION_ASM_OP); \ |
cb0ca284 MH |
1717 | in_section = in_fini; \ |
1718 | } \ | |
1719 | } | |
1720 | ||
1721 | #define READONLY_DATA_SECTION() const_section () | |
1722 | ||
1723 | #define CONST_SECTION_FUNCTION \ | |
1724 | void \ | |
1725 | const_section () \ | |
1726 | { \ | |
4ddb3ea6 | 1727 | if (! USE_CONST_SECTION) \ |
cb0ca284 MH |
1728 | text_section(); \ |
1729 | else if (in_section != in_const) \ | |
1730 | { \ | |
1731 | fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ | |
1732 | in_section = in_const; \ | |
1733 | } \ | |
1734 | } | |
1735 | ||
4e8aa65c | 1736 | #define ASM_STABS_OP "\t.stabs\t" |
cb0ca284 | 1737 | |
7c262518 RH |
1738 | /* Switch into a generic section. */ |
1739 | #define TARGET_ASM_NAMED_SECTION c4x_asm_named_section | |
cb0ca284 | 1740 | |
dfafcb4d HB |
1741 | /* The TI assembler wants to have hex numbers this way. */ |
1742 | ||
1743 | #undef HOST_WIDE_INT_PRINT_HEX | |
1744 | #ifndef HOST_WIDE_INT_PRINT_HEX | |
1745 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT | |
1746 | # define HOST_WIDE_INT_PRINT_HEX "0%xh" | |
1747 | # else | |
1748 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
1749 | # define HOST_WIDE_INT_PRINT_HEX "0%lxh" | |
1750 | # else | |
1751 | # define HOST_WIDE_INT_PRINT_HEX "0%llxh" | |
1752 | # endif | |
1753 | # endif | |
1754 | #endif /* ! HOST_WIDE_INT_PRINT_HEX */ | |
1755 | ||
cb0ca284 MH |
1756 | /* A C statement or statements to switch to the appropriate |
1757 | section for output of RTX in mode MODE. RTX is some kind | |
1758 | of constant in RTL. The argument MODE is redundant except | |
1759 | in the case of a `const_int' rtx. Currently, these always | |
1760 | go into the const section. */ | |
1761 | ||
201556f0 | 1762 | #define SELECT_RTX_SECTION(MODE, RTX, ALIGN) const_section() |
cb0ca284 MH |
1763 | |
1764 | ||
975ab131 | 1765 | /* Overall Framework of an Assembler File. */ |
acb0db7b ZW |
1766 | /* We need to have a data section we can identify so that we can set |
1767 | the DP register back to a data pointer in the small memory model. | |
1768 | This is only required for ISRs if we are paranoid that someone | |
1769 | may have quietly changed this register on the sly. */ | |
cb0ca284 MH |
1770 | |
1771 | #define ASM_FILE_START(FILE) \ | |
1772 | { \ | |
1773 | int dspversion = 0; \ | |
1774 | if (TARGET_C30) dspversion = 30; \ | |
1775 | if (TARGET_C31) dspversion = 31; \ | |
1776 | if (TARGET_C32) dspversion = 32; \ | |
1777 | if (TARGET_C40) dspversion = 40; \ | |
1778 | if (TARGET_C44) dspversion = 44; \ | |
1779 | fprintf (FILE, "\t.version\t%d\n", dspversion); \ | |
1780 | fprintf (FILE, "\t.file\t"); \ | |
1781 | if (TARGET_TI) \ | |
1782 | { \ | |
1943c2c1 KG |
1783 | const char *p; \ |
1784 | const char *after_dir = main_input_filename; \ | |
cb0ca284 MH |
1785 | for (p = main_input_filename; *p; p++) \ |
1786 | if (*p == '/') \ | |
1787 | after_dir = p + 1; \ | |
1788 | output_quoted_string (FILE, after_dir); \ | |
1789 | } \ | |
1790 | else \ | |
1791 | output_quoted_string (FILE, main_input_filename); \ | |
acb0db7b | 1792 | fputs ("\n\t.data\ndata_sec:\n", FILE); \ |
cb0ca284 MH |
1793 | } |
1794 | ||
31445126 | 1795 | #define ASM_COMMENT_START ";" |
cb0ca284 MH |
1796 | |
1797 | #define ASM_APP_ON "" | |
1798 | #define ASM_APP_OFF "" | |
1799 | ||
cb0ca284 MH |
1800 | #define ASM_OUTPUT_ASCII(FILE, PTR, LEN) c4x_output_ascii (FILE, PTR, LEN) |
1801 | ||
975ab131 | 1802 | /* Output and Generation of Labels. */ |
cb0ca284 | 1803 | |
975ab131 | 1804 | #define NO_DOT_IN_LABEL /* Only required for TI format. */ |
cb0ca284 MH |
1805 | |
1806 | #define ASM_OUTPUT_LABEL(FILE, NAME) \ | |
4e6de5a9 | 1807 | do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0); |
cb0ca284 MH |
1808 | |
1809 | #define ASM_GLOBALIZE_LABEL(FILE, NAME) \ | |
4e6de5a9 | 1810 | do { \ |
cb0ca284 MH |
1811 | fprintf (FILE, "\t.global\t"); \ |
1812 | assemble_name (FILE, NAME); \ | |
1813 | fputs ("\n", FILE); \ | |
eff784fe | 1814 | c4x_global_label (NAME); \ |
4e6de5a9 | 1815 | } while (0); |
cb0ca284 | 1816 | |
eff784fe MH |
1817 | #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ |
1818 | c4x_external_ref (NAME) | |
cb0ca284 MH |
1819 | |
1820 | /* A C statement to output on FILE an assembler pseudo-op to | |
1821 | declare a library function named external. | |
4e6de5a9 | 1822 | (Only needed to keep asm30 happy for ___divqf3 etc.) */ |
cb0ca284 | 1823 | |
eff784fe MH |
1824 | #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ |
1825 | c4x_external_ref (XSTR (FUN, 0)) | |
1826 | ||
1827 | #define ASM_FILE_END(FILE) \ | |
1828 | c4x_file_end (FILE) | |
cb0ca284 MH |
1829 | |
1830 | /* The prefix to add to user-visible assembler symbols. */ | |
1831 | ||
1832 | #define USER_LABEL_PREFIX "_" | |
1833 | ||
1834 | /* This is how to output an internal numbered label where | |
1835 | PREFIX is the class of label and NUM is the number within the class. */ | |
1836 | ||
1837 | #define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \ | |
1838 | asm_fprintf (FILE, "%s%d:\n", PREFIX, NUM) | |
1839 | ||
1840 | /* This is how to store into the string LABEL | |
1841 | the symbol_ref name of an internal numbered label where | |
1842 | PREFIX is the class of label and NUM is the number within the class. | |
1843 | This is suitable for output with `assemble_name'. */ | |
1844 | ||
1845 | #define ASM_GENERATE_INTERNAL_LABEL(BUFFER, PREFIX, NUM) \ | |
1846 | sprintf (BUFFER, "*%s%d", PREFIX, NUM) | |
1847 | ||
1848 | /* Store in OUTPUT a string (made with alloca) containing | |
1849 | an assembler-name for a local static variable named NAME. | |
1850 | LABELNO is an integer which is different for each call. */ | |
1851 | ||
1852 | #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ | |
1853 | ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ | |
b61ba1ef | 1854 | sprintf ((OUTPUT), "%s$%d", (NAME), (LABELNO))) |
cb0ca284 | 1855 | |
8e0ed3b5 HB |
1856 | /* A C statement to output to the stdio stream STREAM assembler code which |
1857 | defines (equates) the symbol NAME to have the value VALUE. */ | |
1858 | ||
1859 | #define ASM_OUTPUT_DEF(STREAM, NAME, VALUE) \ | |
1860 | do { \ | |
1861 | assemble_name (STREAM, NAME); \ | |
1862 | fprintf (STREAM, "\t.set\t%s\n", VALUE); \ | |
1863 | } while (0) | |
cb0ca284 | 1864 | |
975ab131 | 1865 | /* Output of Dispatch Tables. */ |
cb0ca284 MH |
1866 | |
1867 | /* This is how to output an element of a case-vector that is absolute. */ | |
1868 | ||
1869 | #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ | |
1870 | fprintf (FILE, "\t.long\tL%d\n", VALUE); | |
1871 | ||
1872 | /* This is how to output an element of a case-vector that is relative. */ | |
1873 | ||
1874 | #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ | |
1875 | fprintf (FILE, "\t.long\tL%d-L%d\n", VALUE, REL); | |
1876 | ||
1877 | #undef SIZE_TYPE | |
1878 | #define SIZE_TYPE "unsigned int" | |
1879 | ||
1880 | #undef PTRDIFF_TYPE | |
1881 | #define PTRDIFF_TYPE "int" | |
1882 | ||
1883 | #undef WCHAR_TYPE | |
1884 | #define WCHAR_TYPE "long int" | |
1885 | ||
1886 | #undef WCHAR_TYPE_SIZE | |
1887 | #define WCHAR_TYPE_SIZE 32 | |
1888 | ||
1889 | #define INT_TYPE_SIZE 32 | |
1890 | #define LONG_LONG_TYPE_SIZE 64 | |
1891 | #define FLOAT_TYPE_SIZE 32 | |
1892 | #define DOUBLE_TYPE_SIZE 32 | |
975ab131 | 1893 | #define LONG_DOUBLE_TYPE_SIZE 64 /* Actually only 40. */ |
cb0ca284 MH |
1894 | |
1895 | /* Allow #sccs in preprocessor. */ | |
1896 | ||
1897 | #define SCCS_DIRECTIVE | |
1898 | ||
1899 | /* Output #ident as a .ident. */ | |
1900 | ||
1901 | #define ASM_OUTPUT_IDENT(FILE, NAME) \ | |
1902 | fprintf (FILE, "\t.ident \"%s\"\n", NAME); | |
1903 | ||
1904 | #define CPP_PREDEFINES "" | |
1905 | ||
975ab131 | 1906 | /* Output of Uninitialized Variables. */ |
31445126 MH |
1907 | |
1908 | /* This says how to output an assembler line to define a local | |
1909 | uninitialized variable. */ | |
cb0ca284 MH |
1910 | |
1911 | #undef ASM_OUTPUT_LOCAL | |
1912 | #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ | |
1913 | ( fputs ("\t.bss\t", FILE), \ | |
1914 | assemble_name (FILE, (NAME)), \ | |
1915 | fprintf (FILE, ",%u\n", (ROUNDED))) | |
1916 | ||
31445126 MH |
1917 | /* This says how to output an assembler line to define a global |
1918 | uninitialized variable. */ | |
cb0ca284 MH |
1919 | |
1920 | #undef ASM_OUTPUT_COMMON | |
1921 | #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ | |
1922 | ( fputs ("\t.globl\t", FILE), \ | |
1923 | assemble_name (FILE, (NAME)), \ | |
1924 | fputs ("\n\t.bss\t", FILE), \ | |
1925 | assemble_name (FILE, (NAME)), \ | |
1926 | fprintf (FILE, ",%u\n", (ROUNDED))) | |
1927 | ||
7bea4e7a MH |
1928 | #undef ASM_OUTPUT_BSS |
1929 | #define ASM_OUTPUT_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ | |
1930 | ( fputs ("\t.globl\t", FILE), \ | |
1931 | assemble_name (FILE, (NAME)), \ | |
1932 | fputs ("\n\t.bss\t", FILE), \ | |
1933 | assemble_name (FILE, (NAME)), \ | |
1934 | fprintf (FILE, ",%u\n", (SIZE))) | |
1935 | ||
975ab131 | 1936 | /* Macros Controlling Initialization Routines. */ |
cb0ca284 MH |
1937 | |
1938 | #define OBJECT_FORMAT_COFF | |
1939 | #define REAL_NM_FILE_NAME "c4x-nm" | |
1940 | ||
975ab131 | 1941 | /* Output of Assembler Instructions. */ |
cb0ca284 MH |
1942 | |
1943 | /* Register names when used for integer modes. */ | |
1944 | ||
1945 | #define REGISTER_NAMES \ | |
1946 | { \ | |
1947 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ | |
1948 | "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", \ | |
1949 | "dp", "ir0", "ir1", "bk", "sp", "st", "die", "iie", \ | |
1950 | "iif", "rs", "re", "rc", "r8", "r9", "r10", "r11" \ | |
1951 | } | |
1952 | ||
1953 | /* Alternate register names when used for floating point modes. */ | |
1954 | ||
1955 | #define FLOAT_REGISTER_NAMES \ | |
1956 | { \ | |
1957 | "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ | |
1958 | "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7", \ | |
1959 | "dp", "ir0", "ir1", "bk", "sp", "st", "die", "iie", \ | |
1960 | "iif", "rs", "re", "rc", "f8", "f9", "f10", "f11" \ | |
1961 | } | |
1962 | ||
cb0ca284 MH |
1963 | #define PRINT_OPERAND(FILE, X, CODE) c4x_print_operand(FILE, X, CODE) |
1964 | ||
1965 | /* Determine which codes are valid without a following integer. These must | |
1ac7a7f5 | 1966 | not be alphabetic. */ |
cb0ca284 MH |
1967 | |
1968 | #define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '#') | |
1969 | ||
cb0ca284 MH |
1970 | #define PRINT_OPERAND_ADDRESS(FILE, X) c4x_print_operand_address(FILE, X) |
1971 | ||
8b97c5f8 ZW |
1972 | /* C4x specific pragmas. */ |
1973 | #define REGISTER_TARGET_PRAGMAS(PFILE) do { \ | |
1974 | cpp_register_pragma (PFILE, 0, "CODE_SECTION", c4x_pr_CODE_SECTION); \ | |
1975 | cpp_register_pragma (PFILE, 0, "DATA_SECTION", c4x_pr_DATA_SECTION); \ | |
1976 | cpp_register_pragma (PFILE, 0, "FUNC_CANNOT_INLINE", c4x_pr_ignored); \ | |
1977 | cpp_register_pragma (PFILE, 0, "FUNC_EXT_CALLED", c4x_pr_ignored); \ | |
1978 | cpp_register_pragma (PFILE, 0, "FUNC_IS_PURE", c4x_pr_FUNC_IS_PURE); \ | |
1979 | cpp_register_pragma (PFILE, 0, "FUNC_IS_SYSTEM", c4x_pr_ignored); \ | |
1980 | cpp_register_pragma (PFILE, 0, "FUNC_NEVER_RETURNS", \ | |
1981 | c4x_pr_FUNC_NEVER_RETURNS); \ | |
1982 | cpp_register_pragma (PFILE, 0, "FUNC_NO_GLOBAL_ASG", c4x_pr_ignored); \ | |
1983 | cpp_register_pragma (PFILE, 0, "FUNC_NO_IND_ASG", c4x_pr_ignored); \ | |
1984 | cpp_register_pragma (PFILE, 0, "INTERRUPT", c4x_pr_INTERRUPT); \ | |
1985 | } while (0) | |
cb0ca284 | 1986 | |
975ab131 | 1987 | /* Assembler Commands for Alignment. */ |
cb0ca284 MH |
1988 | |
1989 | #define ASM_OUTPUT_SKIP(FILE, SIZE) \ | |
1990 | { int c = SIZE; \ | |
1991 | for (; c > 0; --c) \ | |
1992 | fprintf (FILE,"\t.word\t0\n"); \ | |
1993 | } | |
1994 | ||
1995 | #define ASM_NO_SKIP_IN_TEXT 1 | |
1996 | ||
1ac7a7f5 | 1997 | /* I'm not sure about this one. FIXME. */ |
cb0ca284 MH |
1998 | |
1999 | #define ASM_OUTPUT_ALIGN(FILE, LOG) \ | |
2000 | if ((LOG) != 0) \ | |
2001 | fprintf (FILE, "\t.align\t%d\n", (1 << (LOG))) | |
2002 | ||
2003 | ||
2004 | /* Macros for SDB and DWARF Output (use .sdef instead of .def | |
975ab131 | 2005 | to avoid conflict with TI's use of .def). */ |
cb0ca284 MH |
2006 | |
2007 | #define SDB_DELIM "\n" | |
2008 | #define SDB_DEBUGGING_INFO | |
2009 | ||
db14c6a0 MH |
2010 | /* Don't use octal since this can confuse gas for the c4x. */ |
2011 | #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0x%x%s", a, SDB_DELIM) | |
2012 | ||
cb0ca284 MH |
2013 | #define PUT_SDB_DEF(A) \ |
2014 | do { fprintf (asm_out_file, "\t.sdef\t"); \ | |
2015 | ASM_OUTPUT_LABELREF (asm_out_file, A); \ | |
2016 | fprintf (asm_out_file, SDB_DELIM); } while (0) | |
2017 | ||
2018 | #define PUT_SDB_PLAIN_DEF(A) \ | |
2019 | fprintf (asm_out_file,"\t.sdef\t.%s%s", A, SDB_DELIM) | |
2020 | ||
2021 | #define PUT_SDB_BLOCK_START(LINE) \ | |
2022 | fprintf (asm_out_file, \ | |
2023 | "\t.sdef\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ | |
2024 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
2025 | ||
2026 | #define PUT_SDB_BLOCK_END(LINE) \ | |
2027 | fprintf (asm_out_file, \ | |
2028 | "\t.sdef\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ | |
2029 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
2030 | ||
2031 | #define PUT_SDB_FUNCTION_START(LINE) \ | |
2032 | fprintf (asm_out_file, \ | |
2033 | "\t.sdef\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ | |
2034 | SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) | |
2035 | ||
01dc05dd MH |
2036 | /* Note we output relative line numbers for .ef which gas converts |
2037 | to absolute line numbers. The TI compiler outputs absolute line numbers | |
2038 | in the .sym directive which gas does not support. */ | |
cb0ca284 MH |
2039 | #define PUT_SDB_FUNCTION_END(LINE) \ |
2040 | fprintf (asm_out_file, \ | |
2041 | "\t.sdef\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ | |
01dc05dd MH |
2042 | SDB_DELIM, SDB_DELIM, SDB_DELIM, \ |
2043 | (LINE), SDB_DELIM) | |
cb0ca284 MH |
2044 | |
2045 | #define PUT_SDB_EPILOGUE_END(NAME) \ | |
2046 | do { fprintf (asm_out_file, "\t.sdef\t"); \ | |
2047 | ASM_OUTPUT_LABELREF (asm_out_file, NAME); \ | |
2048 | fprintf (asm_out_file, \ | |
2049 | "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \ | |
2050 | SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0) | |
2051 | ||
cb0ca284 MH |
2052 | /* Define this as 1 if `char' should by default be signed; else as 0. */ |
2053 | ||
2054 | #define DEFAULT_SIGNED_CHAR 1 | |
2055 | ||
2056 | /* A function address in a call instruction is a byte address (for | |
2057 | indexing purposes) so give the MEM rtx a byte's mode. */ | |
2058 | ||
2059 | #define FUNCTION_MODE QImode | |
2060 | ||
2061 | #define SLOW_BYTE_ACCESS 0 | |
2062 | ||
2063 | /* Specify the machine mode that pointers have. After generation of | |
2064 | RTL, the compiler makes no further distinction between pointers and | |
2065 | any other objects of this machine mode. */ | |
2066 | ||
2067 | #define Pmode QImode | |
2068 | ||
2069 | /* On the C4x we can write the following code. We have to clear the cache | |
2070 | every time we execute it because the data in the stack could change. | |
2071 | ||
2072 | laj $+4 | |
2073 | addi3 4,r11,ar0 | |
2074 | lda *ar0,ar1 | |
2075 | lda *+ar0(1),ar0 | |
2076 | bud ar1 | |
2077 | nop | |
2078 | nop | |
2079 | or 1000h,st | |
2080 | .word FNADDR | |
2081 | .word CXT | |
2082 | ||
2083 | On the c3x this is a bit more difficult. We have to write self | |
2084 | modifying code here. So we have to clear the cache every time | |
2085 | we execute it because the data in the stack could change. | |
2086 | ||
2087 | ldiu TOP_OF_FUNCTION,ar1 | |
2088 | lsh 16,ar1 | |
2089 | or BOTTOM_OF_FUNCTION,ar1 | |
2090 | ldiu TOP_OF_STATIC,ar0 | |
2091 | bud ar1 | |
2092 | lsh 16,ar0 | |
2093 | or BOTTOM_OF_STATIC,ar0 | |
2094 | or 1000h,st | |
2095 | ||
2096 | */ | |
2097 | ||
2098 | #define TRAMPOLINE_SIZE (TARGET_C3X ? 8 : 10) | |
2099 | ||
2100 | #define TRAMPOLINE_TEMPLATE(FILE) \ | |
2101 | { \ | |
2102 | if (TARGET_C3X) \ | |
2103 | { \ | |
2104 | asm_fprintf (FILE, "\tldiu\t0,ar1\n"); \ | |
2105 | asm_fprintf (FILE, "\tlsh\t16,ar1\n"); \ | |
2106 | asm_fprintf (FILE, "\tor\t0,ar1\n"); \ | |
2107 | asm_fprintf (FILE, "\tldiu\t0,ar0\n"); \ | |
2108 | asm_fprintf (FILE, "\tbud\tar1\n"); \ | |
2109 | asm_fprintf (FILE, "\tlsh\t16,ar0\n"); \ | |
2110 | asm_fprintf (FILE, "\tor\t0,ar0\n"); \ | |
2111 | asm_fprintf (FILE, "\tor\t1000h,st\n"); \ | |
2112 | } \ | |
2113 | else \ | |
2114 | { \ | |
2115 | asm_fprintf (FILE, "\tlaj\t$+4\n"); \ | |
2116 | asm_fprintf (FILE, "\taddi3\t4,r11,ar0\n"); \ | |
2117 | asm_fprintf (FILE, "\tlda\t*ar0,ar1\n"); \ | |
2118 | asm_fprintf (FILE, "\tlda\t*+ar0(1),ar0\n"); \ | |
2119 | asm_fprintf (FILE, "\tbud\tar1\n"); \ | |
2120 | asm_fprintf (FILE, "\tnop\n"); \ | |
2121 | asm_fprintf (FILE, "\tnop\n"); \ | |
2122 | asm_fprintf (FILE, "\tor\t1000h,st\n"); \ | |
2123 | asm_fprintf (FILE, "\t.word\t0\n"); \ | |
2124 | asm_fprintf (FILE, "\t.word\t0\n"); \ | |
2125 | } \ | |
2126 | } | |
2127 | ||
2128 | #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ | |
2129 | { \ | |
2130 | if (TARGET_C3X) \ | |
2131 | { \ | |
2132 | rtx tmp1, tmp2; \ | |
2133 | tmp1 = expand_shift (RSHIFT_EXPR, QImode, FNADDR, \ | |
2134 | size_int (16), 0, 1); \ | |
2135 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ | |
22273300 | 2136 | GEN_INT (0x5069), size_int (16), 0, 1); \ |
cb0ca284 MH |
2137 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
2138 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2139 | plus_constant (tramp, 0)), tmp1); \ | |
22273300 | 2140 | tmp1 = expand_and (QImode, FNADDR, GEN_INT (0xffff), 0); \ |
cb0ca284 | 2141 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ |
22273300 | 2142 | GEN_INT (0x1069), size_int (16), 0, 1); \ |
cb0ca284 MH |
2143 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
2144 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2145 | plus_constant (tramp, 2)), tmp1); \ | |
2146 | tmp1 = expand_shift (RSHIFT_EXPR, QImode, CXT, \ | |
2147 | size_int (16), 0, 1); \ | |
2148 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ | |
22273300 | 2149 | GEN_INT (0x5068), size_int (16), 0, 1); \ |
cb0ca284 MH |
2150 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
2151 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2152 | plus_constant (tramp, 3)), tmp1); \ | |
22273300 | 2153 | tmp1 = expand_and (QImode, CXT, GEN_INT (0xffff), 0); \ |
cb0ca284 | 2154 | tmp2 = expand_shift (LSHIFT_EXPR, QImode, \ |
22273300 | 2155 | GEN_INT (0x1068), size_int (16), 0, 1); \ |
cb0ca284 MH |
2156 | emit_insn (gen_iorqi3 (tmp1, tmp1, tmp2)); \ |
2157 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2158 | plus_constant (tramp, 6)), tmp1); \ | |
2159 | } \ | |
2160 | else \ | |
2161 | { \ | |
2162 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2163 | plus_constant (TRAMP, 8)), FNADDR); \ | |
2164 | emit_move_insn (gen_rtx (MEM, QImode, \ | |
2165 | plus_constant (TRAMP, 9)), CXT); \ | |
2166 | } \ | |
2167 | } | |
2168 | ||
2169 | /* Specify the machine mode that this machine uses for the index in | |
2170 | the tablejump instruction. */ | |
2171 | ||
2172 | #define CASE_VECTOR_MODE Pmode | |
2173 | ||
2174 | /* Max number of (32-bit) bytes we can move from memory to memory | |
2175 | in one reasonably fast instruction. */ | |
2176 | ||
2177 | #define MOVE_MAX 1 | |
2178 | ||
2179 | /* MOVE_RATIO is the number of move instructions that is better than a | |
1ac7a7f5 | 2180 | block move. */ |
cb0ca284 | 2181 | |
8a119a7d | 2182 | #define MOVE_RATIO 3 |
cb0ca284 | 2183 | |
4e8aa65c | 2184 | #define BSS_SECTION_ASM_OP "\t.bss" |
cb0ca284 MH |
2185 | |
2186 | #define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ | |
2187 | asm_fprintf (FILE, "\tpush\t%s\n", reg_names[REGNO]) | |
2188 | ||
2189 | /* This is how to output an insn to pop a register from the stack. | |
2190 | It need not be very fast code. */ | |
2191 | ||
2192 | #define ASM_OUTPUT_REG_POP(FILE, REGNO) \ | |
2193 | asm_fprintf (FILE, "\tpop\t%s\n", reg_names[REGNO]) | |
2194 | ||
2195 | /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits | |
2196 | is done just by pretending it is already truncated. */ | |
2197 | ||
2198 | #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 | |
2199 | ||
cb0ca284 MH |
2200 | /* We need to use direct addressing for large constants and addresses |
2201 | that cannot fit within an instruction. We must check for these | |
2202 | after after the final jump optimisation pass, since this may | |
2203 | introduce a local_move insn for a SYMBOL_REF. This pass | |
2204 | must come before delayed branch slot filling since it can generate | |
2205 | additional instructions. */ | |
2206 | ||
2207 | #define MACHINE_DEPENDENT_REORG(INSNS) c4x_process_after_reload(INSNS) | |
2208 | ||
8a119a7d MH |
2209 | #define DBR_OUTPUT_SEQEND(FILE) \ |
2210 | if (final_sequence != NULL_RTX) \ | |
2211 | { \ | |
2212 | int count; \ | |
2213 | rtx insn = XVECEXP (final_sequence, 0, 0); \ | |
2214 | int laj = GET_CODE (insn) == CALL_INSN \ | |
2215 | || (GET_CODE (insn) == INSN \ | |
2216 | && GET_CODE (PATTERN (insn)) == TRAP_IF);\ | |
2217 | \ | |
2218 | count = dbr_sequence_length(); \ | |
2219 | while (count < (laj ? 2 : 3)) \ | |
2220 | { \ | |
2221 | fputs("\tnop\n", FILE); \ | |
2222 | count++; \ | |
2223 | } \ | |
2224 | if (laj) \ | |
2225 | fputs("\tpush\tr11\n", FILE); \ | |
cb0ca284 MH |
2226 | } |
2227 | ||
2228 | #define NO_FUNCTION_CSE | |
2229 | ||
cb0ca284 MH |
2230 | /* We don't want a leading tab. */ |
2231 | ||
2232 | #define ASM_OUTPUT_ASM(FILE, STRING) fprintf (FILE, "%s\n", STRING) | |
2233 | ||
2234 | /* Define the codes that are matched by predicates in c4x.c. */ | |
2235 | ||
2236 | #define PREDICATE_CODES \ | |
2237 | {"fp_zero_operand", {CONST_DOUBLE}}, \ | |
2238 | {"const_operand", {CONST_INT, CONST_DOUBLE}}, \ | |
2239 | {"stik_const_operand", {CONST_INT}}, \ | |
2240 | {"not_const_operand", {CONST_INT}}, \ | |
2241 | {"reg_operand", {REG, SUBREG}}, \ | |
2242 | {"reg_or_const_operand", {REG, SUBREG, CONST_INT, CONST_DOUBLE}},\ | |
2243 | {"r0r1_reg_operand", {REG, SUBREG}}, \ | |
2244 | {"r2r3_reg_operand", {REG, SUBREG}}, \ | |
2245 | {"ext_low_reg_operand", {REG, SUBREG}}, \ | |
2246 | {"ext_reg_operand", {REG, SUBREG}}, \ | |
2247 | {"std_reg_operand", {REG, SUBREG}}, \ | |
ed3614cd | 2248 | {"std_or_reg_operand", {REG, SUBREG}}, \ |
cb0ca284 MH |
2249 | {"addr_reg_operand", {REG, SUBREG}}, \ |
2250 | {"index_reg_operand", {REG, SUBREG}}, \ | |
2251 | {"dp_reg_operand", {REG}}, \ | |
2252 | {"sp_reg_operand", {REG}}, \ | |
2253 | {"st_reg_operand", {REG}}, \ | |
d5e4ff48 | 2254 | {"rc_reg_operand", {REG}}, \ |
55310df7 | 2255 | {"call_address_operand", {REG, SYMBOL_REF, LABEL_REF, CONST}}, \ |
f416f18c | 2256 | {"dst_operand", {SUBREG, REG, MEM}}, \ |
cb0ca284 MH |
2257 | {"src_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ |
2258 | {"src_hi_operand", {SUBREG, REG, MEM, CONST_DOUBLE}}, \ | |
2259 | {"lsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ | |
2260 | {"tsrc_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ | |
65f2f288 HB |
2261 | {"nonimmediate_src_operand", {SUBREG, REG, MEM}}, \ |
2262 | {"nonimmediate_lsrc_operand", {SUBREG, REG, MEM}}, \ | |
cb0ca284 MH |
2263 | {"any_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE}}, \ |
2264 | {"par_ind_operand", {MEM}}, \ | |
2265 | {"parallel_operand", {SUBREG, REG, MEM}}, \ | |
55310df7 | 2266 | {"symbolic_address_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \ |
50c33087 | 2267 | {"mem_operand", {MEM}}, |
8a119a7d MH |
2268 | |
2269 | ||
2270 | /* Define the intrinsic functions for the c3x/c4x. */ | |
2271 | ||
2272 | enum c4x_builtins | |
2273 | { | |
2274 | /* intrinsic name */ | |
8a119a7d MH |
2275 | C4X_BUILTIN_FIX, /* fast_ftoi */ |
2276 | C4X_BUILTIN_FIX_ANSI, /* ansi_ftoi */ | |
2277 | C4X_BUILTIN_MPYI, /* fast_imult (only C3x) */ | |
2278 | C4X_BUILTIN_TOIEEE, /* toieee (only C4x) */ | |
2279 | C4X_BUILTIN_FRIEEE, /* frieee (only C4x) */ | |
2280 | C4X_BUILTIN_RCPF /* fast_invf (only C4x) */ | |
2281 | }; |