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