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