1255570Strasz/* GCC backend definitions for the Renesas RX processor.
2255570Strasz   Copyright (C) 2008-2020 Free Software Foundation, Inc.
3255570Strasz   Contributed by Red Hat.
4255570Strasz
5255570Strasz   This file is part of GCC.
6255570Strasz
7255570Strasz   GCC is free software; you can redistribute it and/or modify it
8255570Strasz   under the terms of the GNU General Public License as published
9255570Strasz   by the Free Software Foundation; either version 3, or (at your
10255570Strasz   option) any later version.
11255570Strasz
12255570Strasz   GCC is distributed in the hope that it will be useful, but WITHOUT
13255570Strasz   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14255570Strasz   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15255570Strasz   License for more details.
16255570Strasz
17255570Strasz   You should have received a copy of the GNU General Public License
18255570Strasz   along with GCC; see the file COPYING3.  If not see
19255570Strasz   <http://www.gnu.org/licenses/>.  */
20255570Strasz
21255570Strasz
22255570Strasz#define TARGET_CPU_CPP_BUILTINS()               \
23255570Strasz  do                                            \
24255570Strasz    {                                           \
25255570Strasz      builtin_define ("__RX__"); 		\
26255570Strasz      builtin_assert ("cpu=RX"); 		\
27255570Strasz      if (rx_cpu_type == RX610)			\
28255570Strasz	{					\
29255570Strasz          builtin_define ("__RX610__");		\
30255570Strasz          builtin_assert ("machine=RX610");	\
31270888Strasz	}					\
32270888Strasz      else if (rx_cpu_type == RX100)		\
33270888Strasz	{					\
34255570Strasz          builtin_define ("__RX100__");		\
35255570Strasz          builtin_assert ("machine=RX100");	\
36255570Strasz	}					\
37255570Strasz      else if (rx_cpu_type == RX200)		\
38255570Strasz	{					\
39255570Strasz          builtin_define ("__RX200__");		\
40268140Smav          builtin_assert ("machine=RX200");	\
41268140Smav        }					\
42255570Strasz      else if (rx_cpu_type == RX600)		\
43255570Strasz        {					\
44255570Strasz          builtin_define ("__RX600__");		\
45255570Strasz          builtin_assert ("machine=RX600");	\
46255570Strasz        }					\
47255570Strasz						\
48255570Strasz      if (TARGET_BIG_ENDIAN_DATA)		\
49255570Strasz	builtin_define ("__RX_BIG_ENDIAN__");	\
50255570Strasz      else					\
51255570Strasz	builtin_define ("__RX_LITTLE_ENDIAN__");\
52255570Strasz      						\
53255570Strasz      if (TARGET_64BIT_DOUBLES)			\
54255570Strasz	builtin_define ("__RX_64BIT_DOUBLES__");\
55255570Strasz      else					\
56255570Strasz	builtin_define ("__RX_32BIT_DOUBLES__");\
57255570Strasz      						\
58255570Strasz      if (ALLOW_RX_FPU_INSNS)			\
59255570Strasz	builtin_define ("__RX_FPU_INSNS__");	\
60255570Strasz						\
61255570Strasz      if (TARGET_AS100_SYNTAX)			\
62255570Strasz	builtin_define ("__RX_AS100_SYNTAX__"); \
63255570Strasz      else					\
64255570Strasz	builtin_define ("__RX_GAS_SYNTAX__");   \
65255570Strasz						\
66255570Strasz      if (TARGET_GCC_ABI)			\
67255570Strasz	builtin_define ("__RX_GCC_ABI__");	\
68276613Smav      else					\
69255570Strasz	builtin_define ("__RX_ABI__");		\
70276613Smav						\
71255570Strasz      if (rx_allow_string_insns)		\
72255570Strasz	builtin_define ("__RX_ALLOW_STRING_INSNS__"); \
73255570Strasz      else					\
74276613Smav	builtin_define ("__RX_DISALLOW_STRING_INSNS__");\
75255570Strasz    }                                           \
76255570Strasz  while (0)
77255570Strasz
78279879Smav#undef  CC1_SPEC
79279879Smav#define CC1_SPEC "\
80255570Strasz  %{mas100-syntax:%{gdwarf*:%e-mas100-syntax is incompatible with -gdwarf}} \
81255570Strasz  %{mcpu=rx100:%{fpu:%erx100 cpu does not have FPU hardware}} \
82255570Strasz  %{mcpu=rx200:%{fpu:%erx200 cpu does not have FPU hardware}}"
83255570Strasz
84255570Strasz#undef  STARTFILE_SPEC
85255570Strasz#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s} crtbegin.o%s"
86255570Strasz
87255570Strasz#undef  ENDFILE_SPEC
88255570Strasz#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
89255570Strasz
90255570Strasz#undef  CPP_SPEC
91255570Strasz#define CPP_SPEC "\
92255570Strasz%{mpid:-D_RX_PID=1} \
93255570Strasz%{mint-register=*:-D_RX_INT_REGISTERS=%*} \
94255570Strasz%{msmall-data-limit*:-D_RX_SMALL_DATA} \
95255570Strasz"
96255570Strasz
97255570Strasz#undef  ASM_SPEC
98255570Strasz#define ASM_SPEC "\
99255570Strasz%{mbig-endian-data:-mbig-endian-data} \
100255570Strasz%{m64bit-doubles:-m64bit-doubles} \
101255570Strasz%{!m64bit-doubles:-m32bit-doubles} \
102255570Strasz%{msmall-data-limit*:-msmall-data-limit} \
103255570Strasz%{mrelax:-relax} \
104255570Strasz%{mpid} \
105255570Strasz%{mno-allow-string-insns} \
106255570Strasz%{mint-register=*} \
107255570Strasz%{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \
108255570Strasz%{mcpu=*} \
109255570Strasz"
110255570Strasz
111255570Strasz#undef  LIB_SPEC
112255570Strasz#define LIB_SPEC "					\
113255570Strasz--start-group						\
114255570Strasz-lc							\
115255570Strasz%{msim:-lsim}%{!msim:-lnosys}				\
116255570Strasz%{fprofile-arcs|fprofile-generate|coverage:-lgcov} 	\
117255570Strasz--end-group					   	\
118255570Strasz%{!T*: %{msim:%Trx-sim.ld}%{!msim:%Trx.ld}}		\
119255570Strasz"
120255570Strasz
121255570Strasz#undef  LINK_SPEC
122255570Strasz#define LINK_SPEC "%{mbig-endian-data:--oformat elf32-rx-be} %{mrelax:-relax}"
123255570Strasz
124255570Strasz
125276613Smav#define BITS_BIG_ENDIAN 		0
126255570Strasz#define BYTES_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
127276613Smav#define WORDS_BIG_ENDIAN 		TARGET_BIG_ENDIAN_DATA
128255570Strasz
129255570Strasz#define UNITS_PER_WORD 			4
130255570Strasz
131255570Strasz#define INT_TYPE_SIZE			32
132276613Smav#define LONG_TYPE_SIZE			32
133255570Strasz#define LONG_LONG_TYPE_SIZE		64
134255570Strasz
135255570Strasz#define FLOAT_TYPE_SIZE 		32
136279879Smav#define DOUBLE_TYPE_SIZE 		(TARGET_64BIT_DOUBLES ? 64 : 32)
137279879Smav#define LONG_DOUBLE_TYPE_SIZE		DOUBLE_TYPE_SIZE
138255570Strasz
139255570Strasz#define DEFAULT_SIGNED_CHAR		0
140255570Strasz
141255570Strasz/* RX load/store instructions can handle unaligned addresses.  */
142255570Strasz#define STRICT_ALIGNMENT 		0
143255570Strasz#define FUNCTION_BOUNDARY 		((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 4 : 8)
144255570Strasz#define BIGGEST_ALIGNMENT 		32
145255570Strasz#define STACK_BOUNDARY 			32
146255570Strasz#define PARM_BOUNDARY 			8
147255570Strasz
148255570Strasz#define STACK_GROWS_DOWNWARD		1
149255570Strasz#define FRAME_GROWS_DOWNWARD		0
150255570Strasz#define FIRST_PARM_OFFSET(FNDECL) 	0
151255570Strasz
152255570Strasz#define MAX_REGS_PER_ADDRESS 		2
153255570Strasz
154255570Strasz#define Pmode 				SImode
155255570Strasz#define POINTER_SIZE			32
156255570Strasz#undef  SIZE_TYPE
157255570Strasz#define SIZE_TYPE			"long unsigned int"
158255570Strasz#undef  PTRDIFF_TYPE
159255570Strasz#define PTRDIFF_TYPE			"long int"
160255570Strasz#undef  WCHAR_TYPE
161255570Strasz#define WCHAR_TYPE			"long int"
162255570Strasz#undef  WCHAR_TYPE_SIZE
163255570Strasz#define WCHAR_TYPE_SIZE			BITS_PER_WORD
164255570Strasz#define POINTERS_EXTEND_UNSIGNED	1
165255570Strasz#define FUNCTION_MODE 			QImode
166268140Smav#define CASE_VECTOR_MODE		Pmode
167274875Strasz#define WORD_REGISTER_OPERATIONS	1
168268140Smav#define HAS_LONG_COND_BRANCH		0
169279006Smav#define HAS_LONG_UNCOND_BRANCH		0
170268140Smav
171268140Smav#define MOVE_MAX 			4
172268140Smav
173268140Smav#define HAVE_PRE_DECREMENT		1
174268140Smav#define HAVE_POST_INCREMENT		1
175268140Smav
176268140Smav#define MOVE_RATIO(SPEED) 		((SPEED) ? 4 : 2)
177279006Smav#define SLOW_BYTE_ACCESS		1
178279006Smav
179279006Smav#define STORE_FLAG_VALUE		1
180279006Smav#define LOAD_EXTEND_OP(MODE)		SIGN_EXTEND
181268140Smav#define SHORT_IMMEDIATES_SIGN_EXTEND	1
182268140Smav
183268140Smavenum reg_class
184268140Smav{
185268140Smav  NO_REGS,			/* No registers in set.  */
186268140Smav  GR_REGS,			/* Integer registers.  */
187268140Smav  ALL_REGS,			/* All registers.  */
188268140Smav  LIM_REG_CLASSES		/* Max value + 1.  */
189268140Smav};
190268140Smav
191268140Smav#define REG_CLASS_NAMES					\
192268140Smav{							\
193268140Smav  "NO_REGS",						\
194279006Smav  "GR_REGS",						\
195268140Smav  "ALL_REGS"						\
196268140Smav}
197268140Smav
198268140Smav#define REG_CLASS_CONTENTS				\
199268140Smav{							\
200279006Smav  { 0x00000000 },	/* No registers,  */		\
201268140Smav  { 0x0000ffff },	/* Integer registers.  */	\
202268140Smav  { 0x0000ffff }	/* All registers.  */		\
203268140Smav}
204268140Smav
205268140Smav#define N_REG_CLASSES			(int) LIM_REG_CLASSES
206268140Smav#define CLASS_MAX_NREGS(CLASS, MODE)    ((GET_MODE_SIZE (MODE) \
207268140Smav					  + UNITS_PER_WORD - 1) \
208268140Smav					 / UNITS_PER_WORD)
209279006Smav
210268140Smav#define GENERAL_REGS			GR_REGS
211268140Smav#define BASE_REG_CLASS  		GR_REGS
212268140Smav#define INDEX_REG_CLASS			GR_REGS
213275244Strasz
214275244Strasz#define FIRST_PSEUDO_REGISTER 		17
215279006Smav
216275244Strasz#define REGNO_REG_CLASS(REGNO)          ((REGNO) < FIRST_PSEUDO_REGISTER \
217275244Strasz					 ? GR_REGS : NO_REGS)
218275244Strasz
219279006Smav#define STACK_POINTER_REGNUM 	        0
220275244Strasz#define FUNC_RETURN_REGNUM              1
221275244Strasz#define FRAME_POINTER_REGNUM 		6
222275244Strasz#define ARG_POINTER_REGNUM 		7
223279006Smav#define STATIC_CHAIN_REGNUM 		8
224279006Smav#define TRAMPOLINE_TEMP_REGNUM		9
225279006Smav#define STRUCT_VAL_REGNUM		15
226279006Smav#define CC_REGNUM                       16
227275244Strasz
228275244Strasz/* This is the register which will probably be used to hold the address of
229275244Strasz   the start of the small data area, if -msmall-data-limit is being used,
230275244Strasz   or the address of the constant data area if -mpid is being used.  If both
231275244Strasz   features are in use then two consecutive registers will be used.
232275244Strasz
233275244Strasz   Note - these registers must not be call_used because otherwise library
234275244Strasz   functions that are compiled without -msmall-data-limit/-mpid support
235275244Strasz   might clobber them.
236275244Strasz
237275244Strasz   Note that the actual values used depends on other options; use
238275244Strasz   rx_gp_base_regnum() and rx_pid_base_regnum() instead.  */
239275244Strasz#define GP_BASE_REGNUM			13
240275244Strasz
241275244Strasz#define ELIMINABLE_REGS					\
242275244Strasz{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM },	\
243275244Strasz { ARG_POINTER_REGNUM,   FRAME_POINTER_REGNUM },	\
244275244Strasz { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }}
245275244Strasz
246275244Strasz#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)	\
247275244Strasz  (OFFSET) = rx_initial_elimination_offset ((FROM), (TO))
248275244Strasz
249275244Strasz
250275244Strasz#define FUNCTION_ARG_REGNO_P(N)	  	(((N) >= 1) && ((N) <= 4))
251275244Strasz#define FUNCTION_VALUE_REGNO_P(N) 	((N) == FUNC_RETURN_REGNUM)
252275244Strasz#define DEFAULT_PCC_STRUCT_RETURN	0
253275244Strasz
254275244Strasz#define FIXED_REGISTERS					\
255275244Strasz{							\
256275244Strasz  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1	\
257275244Strasz}
258275244Strasz
259275244Strasz#define CALL_USED_REGISTERS				\
260275244Strasz{							\
261275244Strasz  1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1	\
262275244Strasz}
263275244Strasz
264275244Strasz#define LIBCALL_VALUE(MODE)				\
265275244Strasz  gen_rtx_REG (((GET_MODE_CLASS (MODE) != MODE_INT	\
266275244Strasz                 || COMPLEX_MODE_P (MODE)		\
267275244Strasz                 || VECTOR_MODE_P (MODE)		\
268275244Strasz		 || GET_MODE_SIZE (MODE) >= 4)		\
269275244Strasz		? (MODE)				\
270275244Strasz		: SImode),				\
271275244Strasz	       FUNC_RETURN_REGNUM)
272275244Strasz
273275244Strasz/* Order of allocation of registers.  */
274275244Strasz
275275244Strasz#define REG_ALLOC_ORDER						\
276255570Strasz{  7,  10,  11,  12,  13,  14,  4,  3,  2,  1, 9, 8, 6, 5, 15	\
277255570Strasz}
278255570Strasz
279255570Strasz#define REGNO_IN_RANGE(REGNO, MIN, MAX)		\
280255570Strasz  (IN_RANGE ((REGNO), (MIN), (MAX)) 		\
281279006Smav   || (reg_renumber != NULL			\
282274875Strasz       && reg_renumber[(REGNO)] >= (MIN)	\
283255570Strasz       && reg_renumber[(REGNO)] <= (MAX)))
284255570Strasz
285274875Strasz#ifdef REG_OK_STRICT
286274875Strasz#define REGNO_OK_FOR_BASE_P(regno)      REGNO_IN_RANGE (regno, 0, 15)
287255570Strasz#else
288255570Strasz#define REGNO_OK_FOR_BASE_P(regno)	1
289255570Strasz#endif
290255570Strasz
291255570Strasz#define REGNO_OK_FOR_INDEX_P(regno)	REGNO_OK_FOR_BASE_P (regno)
292255570Strasz
293255570Strasz#define RTX_OK_FOR_BASE(X, STRICT)				\
294255570Strasz  ((STRICT) ?							\
295255570Strasz   (   (REG_P (X)						\
296255570Strasz        && REGNO_IN_RANGE (REGNO (X), 0, 15))			\
297255570Strasz    || (GET_CODE (X) == SUBREG					\
298255570Strasz        && REG_P (SUBREG_REG (X))				\
299255570Strasz        && REGNO_IN_RANGE (REGNO (SUBREG_REG (X)), 0, 15)))	\
300279006Smav   :								\
301279006Smav    ( (REG_P (X)						\
302275244Strasz       || (GET_CODE (X) == SUBREG				\
303275244Strasz	   && REG_P (SUBREG_REG (X))))))
304275244Strasz
305279006Smav
306255570Strasz#define RETURN_ADDR_RTX(COUNT, FRAMEADDR)				\
307255570Strasz  ((COUNT) == 0								\
308279006Smav   ? gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (-4))) \
309279006Smav   : NULL_RTX)
310255570Strasz
311255570Strasz#define INCOMING_RETURN_ADDR_RTX	gen_rtx_MEM (Pmode, stack_pointer_rtx)
312275244Strasz
313279006Smav#define ACCUMULATE_OUTGOING_ARGS	1
314275244Strasz
315275244Strasztypedef unsigned int CUMULATIVE_ARGS;
316279006Smav
317275244Strasz#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
318275244Strasz  (CUM) = 0
319255570Strasz
320255570Strasz
321255570Strasz#define TRAMPOLINE_SIZE 	(! TARGET_BIG_ENDIAN_DATA ? 14 : 20)
322255570Strasz#define TRAMPOLINE_ALIGNMENT 	32
323255570Strasz
324255570Strasz#define NO_PROFILE_COUNTERS     1
325255570Strasz#define PROFILE_BEFORE_PROLOGUE 1
326255570Strasz
327255570Strasz#define FUNCTION_PROFILER(FILE, LABELNO)	\
328255570Strasz    fprintf (FILE, "\tbsr\t__mcount\n");
329255570Strasz
330255570Strasz
331255570Strasz#define REGISTER_NAMES						\
332255570Strasz  {								\
333255570Strasz    "r0",  "r1",  "r2",   "r3",   "r4",   "r5",   "r6",   "r7",	\
334255570Strasz      "r8",  "r9",  "r10",  "r11",  "r12",  "r13",  "r14",  "r15", "cc"	\
335255570Strasz  }
336255570Strasz
337255570Strasz#define ADDITIONAL_REGISTER_NAMES	\
338{					\
339    { "sp",    STACK_POINTER_REGNUM }	\
340  , { "fp",    FRAME_POINTER_REGNUM }	\
341  , { "arg",   ARG_POINTER_REGNUM }	\
342  , { "chain", STATIC_CHAIN_REGNUM }	\
343}
344
345#define DATA_SECTION_ASM_OP	      			\
346  (TARGET_AS100_SYNTAX ? "\t.SECTION D,DATA" 		\
347   : "\t.section D,\"aw\",@progbits\n\t.p2align 2")
348
349#define SDATA_SECTION_ASM_OP	      			\
350  (TARGET_AS100_SYNTAX ? "\t.SECTION D_2,DATA,ALIGN=2" 	\
351   : "\t.section D_2,\"aw\",@progbits\n\t.p2align 1")
352
353#undef  READONLY_DATA_SECTION_ASM_OP
354#define READONLY_DATA_SECTION_ASM_OP  			\
355  (TARGET_AS100_SYNTAX ? "\t.SECTION C,ROMDATA,ALIGN=4" \
356   : "\t.section C,\"a\",@progbits\n\t.p2align 2")
357
358#define BSS_SECTION_ASM_OP	      			\
359  (TARGET_AS100_SYNTAX ? "\t.SECTION B,DATA,ALIGN=4" 	\
360   : "\t.section B,\"w\",@nobits\n\t.p2align 2")
361
362#define SBSS_SECTION_ASM_OP	      			\
363  (TARGET_AS100_SYNTAX ? "\t.SECTION B_2,DATA,ALIGN=2" 	\
364   : "\t.section B_2,\"w\",@nobits\n\t.p2align 1")
365
366/* The following definitions are conditional depending upon whether the
367   compiler is being built or crtstuff.c is being compiled by the built
368   compiler.  */
369#if defined CRT_BEGIN || defined CRT_END
370# ifdef __RX_AS100_SYNTAX
371#  define TEXT_SECTION_ASM_OP	      "\t.SECTION P,CODE"
372#  define CTORS_SECTION_ASM_OP	      "\t.SECTION init_array,CODE"
373#  define DTORS_SECTION_ASM_OP	      "\t.SECTION fini_array,CODE"
374#  define INIT_ARRAY_SECTION_ASM_OP   "\t.SECTION init_array,CODE"
375#  define FINI_ARRAY_SECTION_ASM_OP   "\t.SECTION fini_array,CODE"
376# else
377#  define TEXT_SECTION_ASM_OP	      "\t.section P,\"ax\""
378#  define CTORS_SECTION_ASM_OP	      \
379  "\t.section\t.init_array,\"awx\",@init_array"
380#  define DTORS_SECTION_ASM_OP	      \
381  "\t.section\t.fini_array,\"awx\",@fini_array"
382#  define INIT_ARRAY_SECTION_ASM_OP   \
383  "\t.section\t.init_array,\"awx\",@init_array"
384#  define FINI_ARRAY_SECTION_ASM_OP   \
385  "\t.section\t.fini_array,\"awx\",@fini_array"
386# endif
387#else
388# define TEXT_SECTION_ASM_OP	      \
389  (TARGET_AS100_SYNTAX ? "\t.SECTION P,CODE" : "\t.section P,\"ax\"")
390
391# define CTORS_SECTION_ASM_OP			      \
392  (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
393   : "\t.section\t.init_array,\"awx\",@init_array")
394
395# define DTORS_SECTION_ASM_OP			      \
396  (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
397   : "\t.section\t.fini_array,\"awx\",@fini_array")
398
399# define INIT_ARRAY_SECTION_ASM_OP		      \
400  (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
401   : "\t.section\t.init_array,\"awx\",@init_array")
402
403# define FINI_ARRAY_SECTION_ASM_OP		      \
404  (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
405   : "\t.section\t.fini_array,\"awx\",@fini_array")
406#endif
407
408#define GLOBAL_ASM_OP 		\
409  (TARGET_AS100_SYNTAX ? "\t.GLB\t" : "\t.global\t")
410#define ASM_COMMENT_START	" ;"
411#undef ASM_APP_ON
412#define ASM_APP_ON		""
413#undef ASM_APP_OFF
414#define ASM_APP_OFF 		""
415#define LOCAL_LABEL_PREFIX	"L"
416#undef  USER_LABEL_PREFIX
417#define USER_LABEL_PREFIX	"_"
418
419/* Compute the alignment needed for label X in various situations.
420   If the user has specified an alignment then honour that, otherwise
421   use rx_align_for_label.  */
422#define JUMP_ALIGN(x)				(align_jumps.levels[0].log > 0 ? align_jumps : align_flags (rx_align_for_label (x, 0)))
423#define LABEL_ALIGN(x)				(align_labels.levels[0].log > 0 ? align_labels : align_flags (rx_align_for_label (x, 3)))
424#define LOOP_ALIGN(x)				(align_loops.levels[0].log > 0 ? align_loops : align_flags (rx_align_for_label (x, 2)))
425#define LABEL_ALIGN_AFTER_BARRIER(x)		rx_align_for_label (x, 0)
426
427#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP)	\
428  do						\
429    {						\
430      if ((LOG) == 0 || (MAX_SKIP) == 0)	\
431        break;					\
432      if (TARGET_AS100_SYNTAX)			\
433	{					\
434	  if ((LOG) >= 2)			\
435	    fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
436	  else					\
437	    fprintf (STREAM, "\t.ALIGN 2\n");	\
438	}					\
439      else					\
440	fprintf (STREAM, "\t.balign %d,3,%d\n", 1 << (LOG), (MAX_SKIP));	\
441    }						\
442  while (0)
443
444#define ASM_OUTPUT_ALIGN(STREAM, LOG)		\
445  do						\
446    {						\
447      if ((LOG) == 0)				\
448        break;					\
449      if (TARGET_AS100_SYNTAX)			\
450	{					\
451	  if ((LOG) >= 2)			\
452	    fprintf (STREAM, "\t.ALIGN 4\t; %d alignment actually requested\n", 1 << (LOG)); \
453	  else					\
454	    fprintf (STREAM, "\t.ALIGN 2\n");	\
455	}					\
456      else					\
457	fprintf (STREAM, "\t.balign %d\n", 1 << (LOG));	\
458    }						\
459  while (0)
460
461#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
462  fprintf (FILE, TARGET_AS100_SYNTAX ? "\t.LWORD L%d\n" : "\t.long .L%d\n", \
463	   VALUE)
464
465/* This is how to output an element of a case-vector that is relative.
466   Note: The local label referenced by the "1b" below is emitted by
467   the tablejump insn.  */
468
469#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
470  fprintf (FILE, TARGET_AS100_SYNTAX \
471	   ? "\t.LWORD L%d - ?-\n" : "\t.long .L%d - 1b\n", VALUE)
472
473#define CASE_VECTOR_PC_RELATIVE	(TARGET_PID)
474
475#define ASM_OUTPUT_SIZE_DIRECTIVE(STREAM, NAME, SIZE)			\
476  do									\
477    {									\
478      HOST_WIDE_INT size_ = (SIZE);					\
479									\
480      /* The as100 assembler does not have an equivalent of the SVR4    \
481	 .size pseudo-op.  */						\
482      if (TARGET_AS100_SYNTAX)						\
483	break;								\
484									\
485      fputs (SIZE_ASM_OP, STREAM);					\
486      assemble_name (STREAM, NAME);					\
487      fprintf (STREAM, ", " HOST_WIDE_INT_PRINT_DEC "\n", size_);	\
488    }									\
489  while (0)
490
491#define ASM_OUTPUT_MEASURED_SIZE(STREAM, NAME)				\
492  do									\
493    {									\
494      /* The as100 assembler does not have an equivalent of the SVR4    \
495	 .size pseudo-op.  */						\
496      if (TARGET_AS100_SYNTAX)						\
497	break;								\
498      fputs (SIZE_ASM_OP, STREAM);					\
499      assemble_name (STREAM, NAME);					\
500      fputs (", .-", STREAM);						\
501      assemble_name (STREAM, NAME);					\
502      putc ('\n', STREAM);						\
503    }									\
504  while (0)
505
506#define ASM_OUTPUT_TYPE_DIRECTIVE(STREAM, NAME, TYPE)			\
507  do									\
508    {									\
509      /* The as100 assembler does not have an equivalent of the SVR4    \
510	 .size pseudo-op.  */						\
511      if (TARGET_AS100_SYNTAX)						\
512	break;								\
513      fputs (TYPE_ASM_OP, STREAM);					\
514      assemble_name (STREAM, NAME);					\
515      fputs (", ", STREAM);						\
516      fprintf (STREAM, TYPE_OPERAND_FMT, TYPE);				\
517      putc ('\n', STREAM);						\
518    }									\
519  while (0)
520
521#undef  ASM_GENERATE_INTERNAL_LABEL
522#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM)		\
523  do								\
524    {								\
525      sprintf (LABEL, TARGET_AS100_SYNTAX ? "*%s%u" : "*.%s%u", \
526	       PREFIX, (unsigned) (NUM));			\
527    }								\
528  while (0)
529
530#undef  ASM_OUTPUT_EXTERNAL
531#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)			\
532  do								\
533    {								\
534      if (TARGET_AS100_SYNTAX)					\
535	targetm.asm_out.globalize_label (FILE, NAME);		\
536      default_elf_asm_output_external (FILE, DECL, NAME);	\
537    }								\
538  while (0)
539
540#undef  ASM_OUTPUT_ALIGNED_COMMON
541#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
542  do									\
543    {									\
544      if (TARGET_AS100_SYNTAX)						\
545	{								\
546	  fprintf ((FILE), "\t.GLB\t");					\
547	  assemble_name ((FILE), (NAME));				\
548	  fprintf ((FILE), "\n");					\
549          assemble_name ((FILE), (NAME));				\
550	  switch ((ALIGN) / BITS_PER_UNIT)				\
551            {								\
552            case 4:							\
553              fprintf ((FILE), ":\t.BLKL\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
554		       (SIZE) / 4);					\
555	      break;							\
556            case 2:							\
557              fprintf ((FILE), ":\t.BLKW\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
558		       (SIZE) / 2);					\
559	      break;							\
560            default:							\
561              fprintf ((FILE), ":\t.BLKB\t" HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
562		       (SIZE));						\
563	      break;							\
564            }								\
565        }								\
566      else								\
567        {								\
568          fprintf ((FILE), "%s", COMMON_ASM_OP);			\
569          assemble_name ((FILE), (NAME));				\
570          fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",	\
571	           (SIZE), (ALIGN) / BITS_PER_UNIT);			\
572	}								\
573    }									\
574  while (0)
575
576#undef  SKIP_ASM_OP
577#define SKIP_ASM_OP   (TARGET_AS100_SYNTAX ? "\t.BLKB\t" : "\t.zero\t")
578
579#undef  ASM_OUTPUT_LIMITED_STRING
580#define ASM_OUTPUT_LIMITED_STRING(FILE, STR)		\
581  do							\
582    {							\
583      const unsigned char *_limited_str =		\
584	(const unsigned char *) (STR);			\
585      unsigned ch;					\
586							\
587      fprintf ((FILE), TARGET_AS100_SYNTAX 		\
588	       ? "\t.BYTE\t\"" : "\t.string\t\"");	\
589							\
590      for (; (ch = *_limited_str); _limited_str++)	\
591        {						\
592	  int escape;					\
593							\
594	  switch (escape = ESCAPES[ch])			\
595	    {						\
596	    case 0:					\
597	      putc (ch, (FILE));			\
598	      break;					\
599	    case 1:					\
600	      fprintf ((FILE), "\\%03o", ch);		\
601	      break;					\
602	    default:					\
603	      putc ('\\', (FILE));			\
604	      putc (escape, (FILE));			\
605	      break;					\
606	    }						\
607        }						\
608							\
609      fprintf ((FILE), TARGET_AS100_SYNTAX ? "\"\n\t.BYTE\t0\n" : "\"\n");\
610    }							\
611  while (0)
612
613/* For PIC put jump tables into the text section so that the offsets that
614   they contain are always computed between two same-section symbols.  */
615#define JUMP_TABLES_IN_TEXT_SECTION	(TARGET_PID || flag_pic)
616
617/* This is a version of REG_P that also returns TRUE for SUBREGs.  */
618#define RX_REG_P(rtl) (REG_P (rtl) || GET_CODE (rtl) == SUBREG)
619
620/* Like REG_P except that this macro is true for SET expressions.  */
621#define SET_P(rtl)    (GET_CODE (rtl) == SET)
622
623/* The AS100 assembler does not support .leb128 and .uleb128, but
624   the compiler-build-time configure tests will have enabled their
625   use because GAS supports them.  So default to generating STABS
626   debug information instead of DWARF2 when generating AS100
627   compatible output.  */
628#undef  PREFERRED_DEBUGGING_TYPE
629#define PREFERRED_DEBUGGING_TYPE (TARGET_AS100_SYNTAX \
630				  ? DBX_DEBUG : DWARF2_DEBUG)
631
632#define INCOMING_FRAME_SP_OFFSET		4
633#define ARG_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