1 /* GCC backend definitions for the Renesas RX processor.
2    Copyright (C) 2008-2013 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4 
5    This file is part of GCC.
6 
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11 
12    GCC is distributed in the hope that it will be useful, but WITHOUT
13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15    License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20 
21 
22 #define TARGET_CPU_CPP_BUILTINS()               \
23   do                                            \
24     {                                           \
25       builtin_define ("__RX__"); 		\
26       builtin_assert ("cpu=RX"); 		\
27       if (rx_cpu_type == RX610)			\
28 	{					\
29           builtin_define ("__RX610__");		\
30           builtin_assert ("machine=RX610");	\
31 	}					\
32      else					\
33         builtin_assert ("machine=RX600");	\
34       						\
35       if (TARGET_BIG_ENDIAN_DATA)		\
36 	builtin_define ("__RX_BIG_ENDIAN__");	\
37       else					\
38 	builtin_define ("__RX_LITTLE_ENDIAN__");\
39       						\
40       if (TARGET_64BIT_DOUBLES)			\
41 	builtin_define ("__RX_64BIT_DOUBLES__");\
42       else					\
43 	builtin_define ("__RX_32BIT_DOUBLES__");\
44       						\
45       if (ALLOW_RX_FPU_INSNS)			\
46 	builtin_define ("__RX_FPU_INSNS__");	\
47 						\
48       if (TARGET_AS100_SYNTAX)			\
49 	builtin_define ("__RX_AS100_SYNTAX__"); \
50       else					\
51 	builtin_define ("__RX_GAS_SYNTAX__");   \
52 						\
53       if (TARGET_GCC_ABI)			\
54 	builtin_define ("__RX_GCC_ABI__");	\
55       else					\
56 	builtin_define ("__RX_ABI__");		\
57     }                                           \
58   while (0)
59 
60 #undef  CC1_SPEC
61 #define CC1_SPEC "\
62   %{mas100-syntax:%{gdwarf*:%e-mas100-syntax is incompatible with -gdwarf}} \
63   %{mcpu=rx200:%{fpu:%erx200 cpu does not have FPU hardware}}"
64 
65 #undef  STARTFILE_SPEC
66 #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s"
67 
68 #undef  ENDFILE_SPEC
69 #define ENDFILE_SPEC "crtend.o%s crtn.o%s"
70 
71 #undef  CPP_SPEC
72 #define CPP_SPEC "\
73 %{mpid:-D_RX_PID=1} \
74 %{mint-register=*:-D_RX_INT_REGISTERS=%*} \
75 %{msmall-data-limit*:-D_RX_SMALL_DATA} \
76 "
77 
78 #undef  ASM_SPEC
79 #define ASM_SPEC "\
80 %{mbig-endian-data:-mbig-endian-data} \
81 %{m64bit-doubles:-m64bit-doubles} \
82 %{!m64bit-doubles:-m32bit-doubles} \
83 %{msmall-data-limit*:-msmall-data-limit} \
84 %{mrelax:-relax} \
85 %{mpid} \
86 %{mint-register=*} \
87 %{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \
88 "
89 
90 #undef  LIB_SPEC
91 #define LIB_SPEC "					\
92 --start-group						\
93 -lc							\
94 %{msim:-lsim}%{!msim:-lnosys}				\
95 %{fprofile-arcs|fprofile-generate|coverage:-lgcov} 	\
96 --end-group					   	\
97 %{!T*: %{msim:%Trx-sim.ld}%{!msim:%Trx.ld}}		\
98 "
99 
100 #undef  LINK_SPEC
101 #define LINK_SPEC "%{mbig-endian-data:--oformat elf32-rx-be} %{mrelax:-relax}"
102 
103 
104 #define BITS_BIG_ENDIAN 		0
105 #define BYTES_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
106 #define WORDS_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
107 
108 #define UNITS_PER_WORD 			4
109 
110 #define INT_TYPE_SIZE			32
111 #define LONG_TYPE_SIZE			32
112 #define LONG_LONG_TYPE_SIZE		64
113 
114 #define FLOAT_TYPE_SIZE 		32
115 #define DOUBLE_TYPE_SIZE 		(TARGET_64BIT_DOUBLES ? 64 : 32)
116 #define LONG_DOUBLE_TYPE_SIZE		DOUBLE_TYPE_SIZE
117 
118 #ifdef __RX_32BIT_DOUBLES__
119 #define LIBGCC2_HAS_DF_MODE		0
120 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE   32
121 #else
122 #define LIBGCC2_HAS_DF_MODE		1
123 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE   64
124 #endif
125 
126 #define DEFAULT_SIGNED_CHAR		0
127 
128 /* RX load/store instructions can handle unaligned addresses.  */
129 #define STRICT_ALIGNMENT 		0
130 #define FUNCTION_BOUNDARY 		8
131 #define BIGGEST_ALIGNMENT 		32
132 #define STACK_BOUNDARY 			32
133 #define PARM_BOUNDARY 			8
134 
135 #define STACK_GROWS_DOWNWARD		1
136 #define FRAME_GROWS_DOWNWARD		0
137 #define FIRST_PARM_OFFSET(FNDECL) 	0
138 
139 #define MAX_REGS_PER_ADDRESS 		2
140 
141 #define Pmode 				SImode
142 #define POINTER_SIZE			32
143 #undef  SIZE_TYPE
144 #define SIZE_TYPE			"long unsigned int"
145 #undef  PTRDIFF_TYPE
146 #define PTRDIFF_TYPE			"long int"
147 #undef  WCHAR_TYPE
148 #define WCHAR_TYPE			"long int"
149 #undef  WCHAR_TYPE_SIZE
150 #define WCHAR_TYPE_SIZE			BITS_PER_WORD
151 #define POINTERS_EXTEND_UNSIGNED	1
152 #define FUNCTION_MODE 			QImode
153 #define CASE_VECTOR_MODE		Pmode
154 #define WORD_REGISTER_OPERATIONS	1
155 #define HAS_LONG_COND_BRANCH		0
156 #define HAS_LONG_UNCOND_BRANCH		0
157 
158 #define MOVE_MAX 			4
159 #define STARTING_FRAME_OFFSET		0
160 
161 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC)   1
162 
163 #define HAVE_PRE_DECREMENT		1
164 #define HAVE_POST_INCREMENT		1
165 
166 #define MOVE_RATIO(SPEED) 		((SPEED) ? 4 : 2)
167 #define SLOW_BYTE_ACCESS		1
168 
169 #define STORE_FLAG_VALUE		1
170 #define LOAD_EXTEND_OP(MODE)		SIGN_EXTEND
171 #define SHORT_IMMEDIATES_SIGN_EXTEND	1
172 
173 enum reg_class
174 {
175   NO_REGS,			/* No registers in set.  */
176   GR_REGS,			/* Integer registers.  */
177   ALL_REGS,			/* All registers.  */
178   LIM_REG_CLASSES		/* Max value + 1.  */
179 };
180 
181 #define REG_CLASS_NAMES					\
182 {							\
183   "NO_REGS",						\
184   "GR_REGS",						\
185   "ALL_REGS"						\
186 }
187 
188 #define REG_CLASS_CONTENTS				\
189 {							\
190   { 0x00000000 },	/* No registers,  */		\
191   { 0x0000ffff },	/* Integer registers.  */	\
192   { 0x0000ffff }	/* All registers.  */		\
193 }
194 
195 #define N_REG_CLASSES			(int) LIM_REG_CLASSES
196 #define CLASS_MAX_NREGS(CLASS, MODE)    ((GET_MODE_SIZE (MODE) \
197 					  + UNITS_PER_WORD - 1) \
198 					 / UNITS_PER_WORD)
199 
200 #define GENERAL_REGS			GR_REGS
201 #define BASE_REG_CLASS  		GR_REGS
202 #define INDEX_REG_CLASS			GR_REGS
203 
204 #define FIRST_PSEUDO_REGISTER 		17
205 
206 #define REGNO_REG_CLASS(REGNO)          ((REGNO) < FIRST_PSEUDO_REGISTER \
207 					 ? GR_REGS : NO_REGS)
208 
209 #define STACK_POINTER_REGNUM 	        0
210 #define FUNC_RETURN_REGNUM              1
211 #define FRAME_POINTER_REGNUM 		6
212 #define ARG_POINTER_REGNUM 		7
213 #define STATIC_CHAIN_REGNUM 		8
214 #define TRAMPOLINE_TEMP_REGNUM		9
215 #define STRUCT_VAL_REGNUM		15
216 #define CC_REGNUM                       16
217 
218 /* This is the register which will probably be used to hold the address of
219    the start of the small data area, if -msmall-data-limit is being used,
220    or the address of the constant data area if -mpid is being used.  If both
221    features are in use then two consecutive registers will be used.
222 
223    Note - these registers must not be call_used because otherwise library
224    functions that are compiled without -msmall-data-limit/-mpid support
225    might clobber them.
226 
227    Note that the actual values used depends on other options; use
228    rx_gp_base_regnum() and rx_pid_base_regnum() instead.  */
229 #define GP_BASE_REGNUM			13
230 
231 #define ELIMINABLE_REGS					\
232 {{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM },	\
233  { ARG_POINTER_REGNUM,   FRAME_POINTER_REGNUM },	\
234  { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
235 
236 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)	\
237   (OFFSET) = rx_initial_elimination_offset ((FROM), (TO))
238 
239 
240 #define FUNCTION_ARG_REGNO_P(N)	  	(((N) >= 1) && ((N) <= 4))
241 #define FUNCTION_VALUE_REGNO_P(N) 	((N) == FUNC_RETURN_REGNUM)
242 #define DEFAULT_PCC_STRUCT_RETURN	0
243 
244 #define FIXED_REGISTERS					\
245 {							\
246   1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1	\
247 }
248 
249 #define CALL_USED_REGISTERS				\
250 {							\
251   1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1	\
252 }
253 
254 #define LIBCALL_VALUE(MODE)				\
255   gen_rtx_REG (((GET_MODE_CLASS (MODE) != MODE_INT	\
256                  || COMPLEX_MODE_P (MODE)		\
257 		 || GET_MODE_SIZE (MODE) >= 4)		\
258 		? (MODE)				\
259 		: SImode),				\
260 	       FUNC_RETURN_REGNUM)
261 
262 /* Order of allocation of registers.  */
263 
264 #define REG_ALLOC_ORDER						\
265 {  7,  10,  11,  12,  13,  14,  4,  3,  2,  1, 9, 8, 6, 5, 15	\
266 }
267 
268 #define REGNO_IN_RANGE(REGNO, MIN, MAX)		\
269   (IN_RANGE ((REGNO), (MIN), (MAX)) 		\
270    || (reg_renumber != NULL			\
271        && reg_renumber[(REGNO)] >= (MIN)	\
272        && reg_renumber[(REGNO)] <= (MAX)))
273 
274 #ifdef REG_OK_STRICT
275 #define REGNO_OK_FOR_BASE_P(regno)      REGNO_IN_RANGE (regno, 0, 15)
276 #else
277 #define REGNO_OK_FOR_BASE_P(regno)	1
278 #endif
279 
280 #define REGNO_OK_FOR_INDEX_P(regno)	REGNO_OK_FOR_BASE_P (regno)
281 
282 #define RTX_OK_FOR_BASE(X, STRICT)				\
283   ((STRICT) ?							\
284    (   (REG_P (X)						\
285         && REGNO_IN_RANGE (REGNO (X), 0, 15))			\
286     || (GET_CODE (X) == SUBREG					\
287         && REG_P (SUBREG_REG (X))				\
288         && REGNO_IN_RANGE (REGNO (SUBREG_REG (X)), 0, 15)))	\
289    :								\
290     ( (REG_P (X)						\
291        || (GET_CODE (X) == SUBREG				\
292 	   && REG_P (SUBREG_REG (X))))))
293 
294 
295 #define RETURN_ADDR_RTX(COUNT, FRAMEADDR)				\
296   ((COUNT) == 0								\
297    ? gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (-4))) \
298    : NULL_RTX)
299 
300 #define INCOMING_RETURN_ADDR_RTX	gen_rtx_MEM (Pmode, stack_pointer_rtx)
301 
302 #define ACCUMULATE_OUTGOING_ARGS	1
303 
304 typedef unsigned int CUMULATIVE_ARGS;
305 
306 #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
307   (CUM) = 0
308 
309 
310 #define TRAMPOLINE_SIZE 	(! TARGET_BIG_ENDIAN_DATA ? 14 : 20)
311 #define TRAMPOLINE_ALIGNMENT 	32
312 
313 #define NO_PROFILE_COUNTERS     1
314 #define PROFILE_BEFORE_PROLOGUE 1
315 
316 #define FUNCTION_PROFILER(FILE, LABELNO)	\
317     fprintf (FILE, "\tbsr\t__mcount\n");
318 
319 
320 #define HARD_REGNO_NREGS(REGNO, MODE)   CLASS_MAX_NREGS (0, MODE)
321 
322 #define HARD_REGNO_MODE_OK(REGNO, MODE) 			\
323   REGNO_REG_CLASS (REGNO) == GR_REGS
324 
325 #define MODES_TIEABLE_P(MODE1, MODE2)				\
326   (   (   GET_MODE_CLASS (MODE1) == MODE_FLOAT			\
327        || GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT)		\
328    == (   GET_MODE_CLASS (MODE2) == MODE_FLOAT			\
329        || GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
330 
331 
332 #define REGISTER_NAMES						\
333   {								\
334     "r0",  "r1",  "r2",   "r3",   "r4",   "r5",   "r6",   "r7",	\
335       "r8",  "r9",  "r10",  "r11",  "r12",  "r13",  "r14",  "r15", "cc"	\
336   }
337 
338 #define ADDITIONAL_REGISTER_NAMES	\
339 {					\
340     { "sp",    STACK_POINTER_REGNUM }	\
341   , { "fp",    FRAME_POINTER_REGNUM }	\
342   , { "arg",   ARG_POINTER_REGNUM }	\
343   , { "chain", STATIC_CHAIN_REGNUM }	\
344 }
345 
346 #define DATA_SECTION_ASM_OP	      			\
347   (TARGET_AS100_SYNTAX ? "\t.SECTION D,DATA" 		\
348    : "\t.section D,\"aw\",@progbits\n\t.p2align 2")
349 
350 #define SDATA_SECTION_ASM_OP	      			\
351   (TARGET_AS100_SYNTAX ? "\t.SECTION D_2,DATA,ALIGN=2" 	\
352    : "\t.section D_2,\"aw\",@progbits\n\t.p2align 1")
353 
354 #undef  READONLY_DATA_SECTION_ASM_OP
355 #define READONLY_DATA_SECTION_ASM_OP  			\
356   (TARGET_AS100_SYNTAX ? "\t.SECTION C,ROMDATA,ALIGN=4" \
357    : "\t.section C,\"a\",@progbits\n\t.p2align 2")
358 
359 #define BSS_SECTION_ASM_OP	      			\
360   (TARGET_AS100_SYNTAX ? "\t.SECTION B,DATA,ALIGN=4" 	\
361    : "\t.section B,\"w\",@nobits\n\t.p2align 2")
362 
363 #define SBSS_SECTION_ASM_OP	      			\
364   (TARGET_AS100_SYNTAX ? "\t.SECTION B_2,DATA,ALIGN=2" 	\
365    : "\t.section B_2,\"w\",@nobits\n\t.p2align 1")
366 
367 /* The following definitions are conditional depending upon whether the
368    compiler is being built or crtstuff.c is being compiled by the built
369    compiler.  */
370 #if defined CRT_BEGIN || defined CRT_END
371 # ifdef __RX_AS100_SYNTAX
372 #  define TEXT_SECTION_ASM_OP	      "\t.SECTION P,CODE"
373 #  define CTORS_SECTION_ASM_OP	      "\t.SECTION init_array,CODE"
374 #  define DTORS_SECTION_ASM_OP	      "\t.SECTION fini_array,CODE"
375 #  define INIT_ARRAY_SECTION_ASM_OP   "\t.SECTION init_array,CODE"
376 #  define FINI_ARRAY_SECTION_ASM_OP   "\t.SECTION fini_array,CODE"
377 # else
378 #  define TEXT_SECTION_ASM_OP	      "\t.section P,\"ax\""
379 #  define CTORS_SECTION_ASM_OP	      \
380   "\t.section\t.init_array,\"awx\",@init_array"
381 #  define DTORS_SECTION_ASM_OP	      \
382   "\t.section\t.fini_array,\"awx\",@fini_array"
383 #  define INIT_ARRAY_SECTION_ASM_OP   \
384   "\t.section\t.init_array,\"awx\",@init_array"
385 #  define FINI_ARRAY_SECTION_ASM_OP   \
386   "\t.section\t.fini_array,\"awx\",@fini_array"
387 # endif
388 #else
389 # define TEXT_SECTION_ASM_OP	      \
390   (TARGET_AS100_SYNTAX ? "\t.SECTION P,CODE" : "\t.section P,\"ax\"")
391 
392 # define CTORS_SECTION_ASM_OP			      \
393   (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
394    : "\t.section\t.init_array,\"awx\",@init_array")
395 
396 # define DTORS_SECTION_ASM_OP			      \
397   (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
398    : "\t.section\t.fini_array,\"awx\",@fini_array")
399 
400 # define INIT_ARRAY_SECTION_ASM_OP		      \
401   (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
402    : "\t.section\t.init_array,\"awx\",@init_array")
403 
404 # define FINI_ARRAY_SECTION_ASM_OP		      \
405   (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
406    : "\t.section\t.fini_array,\"awx\",@fini_array")
407 #endif
408 
409 #define GLOBAL_ASM_OP 		\
410   (TARGET_AS100_SYNTAX ? "\t.GLB\t" : "\t.global\t")
411 #define ASM_COMMENT_START	" ;"
412 #define ASM_APP_ON		""
413 #define ASM_APP_OFF 		""
414 #define LOCAL_LABEL_PREFIX	"L"
415 #undef  USER_LABEL_PREFIX
416 #define USER_LABEL_PREFIX	"_"
417 
418 /* Compute the alignment needed for label X in various situations.
419    If the user has specified an alignment then honour that, otherwise
420    use rx_align_for_label.  */
421 #define JUMP_ALIGN(x)				(align_jumps ? align_jumps : rx_align_for_label (x, 0))
422 #define LABEL_ALIGN(x)				(align_labels ? align_labels : rx_align_for_label (x, 3))
423 #define LOOP_ALIGN(x)				(align_loops ? align_loops : rx_align_for_label (x, 2))
424 #define LABEL_ALIGN_AFTER_BARRIER(x)		rx_align_for_label (x, 0)
425 
426 #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP)	\
427   do						\
428     {						\
429       if ((LOG) == 0 || (MAX_SKIP) == 0)	\
430         break;					\
431       if (TARGET_AS100_SYNTAX)			\
432 	{					\
433 	  if ((LOG) >= 2)			\
434 	    fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
435 	  else					\
436 	    fprintf (STREAM, "\t.ALIGN 2\n");	\
437 	}					\
438       else					\
439 	fprintf (STREAM, "\t.balign %d,3,%d\n", 1 << (LOG), (MAX_SKIP));	\
440     }						\
441   while (0)
442 
443 #define ASM_OUTPUT_ALIGN(STREAM, LOG)		\
444   do						\
445     {						\
446       if ((LOG) == 0)				\
447         break;					\
448       if (TARGET_AS100_SYNTAX)			\
449 	{					\
450 	  if ((LOG) >= 2)			\
451 	    fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
452 	  else					\
453 	    fprintf (STREAM, "\t.ALIGN 2\n");	\
454 	}					\
455       else					\
456 	fprintf (STREAM, "\t.balign %d\n", 1 << (LOG));	\
457     }						\
458   while (0)
459 
460 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
461   fprintf (FILE, TARGET_AS100_SYNTAX ? "\t.LWORD L%d\n" : "\t.long .L%d\n", \
462 	   VALUE)
463 
464 /* This is how to output an element of a case-vector that is relative.
465    Note: The local label referenced by the "1b" below is emitted by
466    the tablejump insn.  */
467 
468 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
469   fprintf (FILE, TARGET_AS100_SYNTAX \
470 	   ? "\t.LWORD L%d - ?-\n" : "\t.long .L%d - 1b\n", VALUE)
471 
472 #define CASE_VECTOR_PC_RELATIVE	(TARGET_PID)
473 
474 #define ASM_OUTPUT_SIZE_DIRECTIVE(STREAM, NAME, SIZE)			\
475   do									\
476     {									\
477       HOST_WIDE_INT size_ = (SIZE);					\
478 									\
479       /* The as100 assembler does not have an equivalent of the SVR4    \
480 	 .size pseudo-op.  */						\
481       if (TARGET_AS100_SYNTAX)						\
482 	break;								\
483 									\
484       fputs (SIZE_ASM_OP, STREAM);					\
485       assemble_name (STREAM, NAME);					\
486       fprintf (STREAM, ", " HOST_WIDE_INT_PRINT_DEC "\n", size_);	\
487     }									\
488   while (0)
489 
490 #define ASM_OUTPUT_MEASURED_SIZE(STREAM, NAME)				\
491   do									\
492     {									\
493       /* The as100 assembler does not have an equivalent of the SVR4    \
494 	 .size pseudo-op.  */						\
495       if (TARGET_AS100_SYNTAX)						\
496 	break;								\
497       fputs (SIZE_ASM_OP, STREAM);					\
498       assemble_name (STREAM, NAME);					\
499       fputs (", .-", STREAM);						\
500       assemble_name (STREAM, NAME);					\
501       putc ('\n', STREAM);						\
502     }									\
503   while (0)
504 
505 #define ASM_OUTPUT_TYPE_DIRECTIVE(STREAM, NAME, TYPE)			\
506   do									\
507     {									\
508       /* The as100 assembler does not have an equivalent of the SVR4    \
509 	 .size pseudo-op.  */						\
510       if (TARGET_AS100_SYNTAX)						\
511 	break;								\
512       fputs (TYPE_ASM_OP, STREAM);					\
513       assemble_name (STREAM, NAME);					\
514       fputs (", ", STREAM);						\
515       fprintf (STREAM, TYPE_OPERAND_FMT, TYPE);				\
516       putc ('\n', STREAM);						\
517     }									\
518   while (0)
519 
520 #undef  ASM_GENERATE_INTERNAL_LABEL
521 #define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)		\
522   do								\
523     {								\
524       sprintf (LABEL, TARGET_AS100_SYNTAX ? "*%s%u" : "*.%s%u", \
525 	       PREFIX, (unsigned) (NUM));			\
526     }								\
527   while (0)
528 
529 #undef  ASM_OUTPUT_EXTERNAL
530 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)			\
531   do								\
532     {								\
533       if (TARGET_AS100_SYNTAX)					\
534 	targetm.asm_out.globalize_label (FILE, NAME);		\
535       default_elf_asm_output_external (FILE, DECL, NAME);	\
536     }								\
537   while (0)
538 
539 #undef  ASM_OUTPUT_ALIGNED_COMMON
540 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
541   do									\
542     {									\
543       if (TARGET_AS100_SYNTAX)						\
544 	{								\
545 	  fprintf ((FILE), "\t.GLB\t");					\
546 	  assemble_name ((FILE), (NAME));				\
547 	  fprintf ((FILE), "\n");					\
548           assemble_name ((FILE), (NAME));				\
549 	  switch ((ALIGN) / BITS_PER_UNIT)				\
550             {								\
551             case 4:							\
552               fprintf ((FILE), ":\t.BLKL\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
553 		       (SIZE) / 4);					\
554 	      break;							\
555             case 2:							\
556               fprintf ((FILE), ":\t.BLKW\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
557 		       (SIZE) / 2);					\
558 	      break;							\
559             default:							\
560               fprintf ((FILE), ":\t.BLKB\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
561 		       (SIZE));						\
562 	      break;							\
563             }								\
564         }								\
565       else								\
566         {								\
567           fprintf ((FILE), "%s", COMMON_ASM_OP);			\
568           assemble_name ((FILE), (NAME));				\
569           fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",	\
570 	           (SIZE), (ALIGN) / BITS_PER_UNIT);			\
571 	}								\
572     }									\
573   while (0)
574 
575 #undef  SKIP_ASM_OP
576 #define SKIP_ASM_OP   (TARGET_AS100_SYNTAX ? "\t.BLKB\t" : "\t.zero\t")
577 
578 #undef  ASM_OUTPUT_LIMITED_STRING
579 #define ASM_OUTPUT_LIMITED_STRING(FILE, STR)		\
580   do							\
581     {							\
582       const unsigned char *_limited_str =		\
583 	(const unsigned char *) (STR);			\
584       unsigned ch;					\
585 							\
586       fprintf ((FILE), TARGET_AS100_SYNTAX 		\
587 	       ? "\t.BYTE\t\"" : "\t.string\t\"");	\
588 							\
589       for (; (ch = *_limited_str); _limited_str++)	\
590         {						\
591 	  int escape;					\
592 							\
593 	  switch (escape = ESCAPES[ch])			\
594 	    {						\
595 	    case 0:					\
596 	      putc (ch, (FILE));			\
597 	      break;					\
598 	    case 1:					\
599 	      fprintf ((FILE), "\\%03o", ch);		\
600 	      break;					\
601 	    default:					\
602 	      putc ('\\', (FILE));			\
603 	      putc (escape, (FILE));			\
604 	      break;					\
605 	    }						\
606         }						\
607 							\
608       fprintf ((FILE), TARGET_AS100_SYNTAX ? "\"\n\t.BYTE\t0\n" : "\"\n");\
609     }							\
610   while (0)
611 
612 /* For PIC put jump tables into the text section so that the offsets that
613    they contain are always computed between two same-section symbols.  */
614 #define JUMP_TABLES_IN_TEXT_SECTION	(TARGET_PID || flag_pic)
615 
616 /* This is a version of REG_P that also returns TRUE for SUBREGs.  */
617 #define RX_REG_P(rtl) (REG_P (rtl) || GET_CODE (rtl) == SUBREG)
618 
619 /* Like REG_P except that this macro is true for SET expressions.  */
620 #define SET_P(rtl)    (GET_CODE (rtl) == SET)
621 
622 /* The AS100 assembler does not support .leb128 and .uleb128, but
623    the compiler-build-time configure tests will have enabled their
624    use because GAS supports them.  So default to generating STABS
625    debug information instead of DWARF2 when generating AS100
626    compatible output.  */
627 #undef  PREFERRED_DEBUGGING_TYPE
628 #define PREFERRED_DEBUGGING_TYPE (TARGET_AS100_SYNTAX \
629 				  ? DBX_DEBUG : DWARF2_DEBUG)
630 
631 #define INCOMING_FRAME_SP_OFFSET		4
632 #define ARG_POINTER_CFA_OFFSET(FNDECL)		4
633 #define FRAME_POINTER_CFA_OFFSET(FNDECL)	4
634 
635 #define TARGET_USE_FPU		(! TARGET_NO_USE_FPU)
636 
637 /* This macro is used to decide when RX FPU instructions can be used.  */
638 #define ALLOW_RX_FPU_INSNS	(TARGET_USE_FPU)
639 
640 #define BRANCH_COST(SPEED,PREDICT)       1
641 #define REGISTER_MOVE_COST(MODE,FROM,TO) 2
642 
643 #define SELECT_CC_MODE(OP,X,Y)  rx_select_cc_mode(OP, X, Y)
644 
645 #define ADJUST_INSN_LENGTH(INSN,LENGTH)				\
646   do								\
647     {								\
648       (LENGTH) = rx_adjust_insn_length ((INSN), (LENGTH));	\
649     }								\
650   while (0)
651