aof.h revision 96263
1/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
2   ARM compilation, AOF Assembler.
3   Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
4   Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING.  If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA.  */
22
23
24
25#define AOF_ASSEMBLER
26
27#define LINK_LIBGCC_SPECIAL 1
28
29#define LINK_SPEC "%{aof} %{bin} %{aif} %{ihf} %{shl,*} %{reent*} %{split} \
30		   %{ov*,*} %{reloc*} -nodebug"
31
32#define STARTFILE_SPEC "crtbegin.o%s"
33
34#define ENDFILE_SPEC "crtend.o%s"
35
36#ifndef ASM_SPEC
37#define ASM_SPEC "%{g -g} -arch 4 \
38-apcs 3%{mapcs-32:/32bit}%{mapcs-26:/26bit}%{!mapcs-26:%{!macps-32:/26bit}}"
39#endif
40
41#ifndef LIB_SPEC
42#define LIB_SPEC "%{Eb: armlib_h.32b%s}%{!Eb: armlib_h.32l%s}"
43#endif
44
45#define LIBGCC_SPEC "libgcc.a%s"
46
47/* Dividing the Output into Sections (Text, Data, ...) */
48/* AOF Assembler syntax is a nightmare when it comes to areas, since once
49   we change from one area to another, we can't go back again.  Instead,
50   we must create a new area with the same attributes and add the new output
51   to that.  Unfortunately, there is nothing we can do here to guarantee that
52   two areas with the same attributes will be linked adjacently in the
53   resulting executable, so we have to be careful not to do pc-relative
54   addressing across such boundaries.  */
55#define TEXT_SECTION_ASM_OP aof_text_section ()
56
57#define SELECT_RTX_SECTION(MODE,RTX,ALIGN) text_section ();
58
59#define DATA_SECTION_ASM_OP aof_data_section ()
60
61#define EXTRA_SECTIONS in_zero_init, in_common
62
63#define EXTRA_SECTION_FUNCTIONS	\
64ZERO_INIT_SECTION		\
65COMMON_SECTION
66
67#define ZERO_INIT_SECTION					\
68void								\
69zero_init_section ()						\
70{								\
71  static int zero_init_count = 1;				\
72  if (in_section != in_zero_init)				\
73    {								\
74      fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n",	\
75	       zero_init_count++);				\
76      in_section = in_zero_init;				\
77    }								\
78}
79
80/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
81   changed areas.  */
82#define COMMON_SECTION						\
83void								\
84common_section ()						\
85{								\
86  if (in_section != in_common)					\
87    {								\
88      in_section = in_common;					\
89    }								\
90}
91#define CTOR_LIST_BEGIN					\
92asm (CTORS_SECTION_ASM_OP);				\
93extern func_ptr __CTOR_END__[1];			\
94func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
95
96#define CTOR_LIST_END					\
97asm (CTORS_SECTION_ASM_OP);				\
98func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
99
100#define DO_GLOBAL_CTORS_BODY		\
101do {					\
102  func_ptr *ptr = __CTOR_LIST__ + 1;	\
103  while (*ptr)				\
104    (*ptr++) ();			\
105} while (0)
106
107#define DTOR_LIST_BEGIN					\
108asm (DTORS_SECTION_ASM_OP);				\
109extern func_ptr __DTOR_END__[1];			\
110func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
111
112#define DTOR_LIST_END					\
113asm (DTORS_SECTION_ASM_OP);				\
114func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
115
116#define DO_GLOBAL_DTORS_BODY		\
117do {					\
118  func_ptr *ptr = __DTOR_LIST__ + 1;	\
119  while (*ptr)				\
120    (*ptr++) ();			\
121} while (0)
122
123/* We really want to put Thumb tables in a read-only data section, but
124   switching to another section during function output is not
125   possible.  We could however do what the SPARC does and defer the
126   whole table generation until the end of the function.  */
127#define JUMP_TABLES_IN_TEXT_SECTION 1
128
129#ifndef ARM_OS_NAME
130#define ARM_OS_NAME "(generic)"
131#endif
132
133/* For the AOF linker, we need to reference __main to force the standard
134   library to get linked in. */
135
136#define ASM_FILE_START(STREAM)					\
137{								\
138  fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", 	\
139	   ASM_COMMENT_START, version_string, ARM_OS_NAME);	\
140  fprintf ((STREAM), "__r0\tRN\t0\n");				\
141  fprintf ((STREAM), "__a1\tRN\t0\n");				\
142  fprintf ((STREAM), "__a2\tRN\t1\n");				\
143  fprintf ((STREAM), "__a3\tRN\t2\n");				\
144  fprintf ((STREAM), "__a4\tRN\t3\n");				\
145  fprintf ((STREAM), "__v1\tRN\t4\n");				\
146  fprintf ((STREAM), "__v2\tRN\t5\n");				\
147  fprintf ((STREAM), "__v3\tRN\t6\n");				\
148  fprintf ((STREAM), "__v4\tRN\t7\n");				\
149  fprintf ((STREAM), "__v5\tRN\t8\n");				\
150  fprintf ((STREAM), "__v6\tRN\t9\n");				\
151  fprintf ((STREAM), "__sl\tRN\t10\n");				\
152  fprintf ((STREAM), "__fp\tRN\t11\n");				\
153  fprintf ((STREAM), "__ip\tRN\t12\n");				\
154  fprintf ((STREAM), "__sp\tRN\t13\n");				\
155  fprintf ((STREAM), "__lr\tRN\t14\n");				\
156  fprintf ((STREAM), "__pc\tRN\t15\n");				\
157  fprintf ((STREAM), "__f0\tFN\t0\n");				\
158  fprintf ((STREAM), "__f1\tFN\t1\n");				\
159  fprintf ((STREAM), "__f2\tFN\t2\n");				\
160  fprintf ((STREAM), "__f3\tFN\t3\n");				\
161  fprintf ((STREAM), "__f4\tFN\t4\n");				\
162  fprintf ((STREAM), "__f5\tFN\t5\n");				\
163  fprintf ((STREAM), "__f6\tFN\t6\n");				\
164  fprintf ((STREAM), "__f7\tFN\t7\n");				\
165  text_section ();						\
166}
167
168/* Some systems use __main in a way incompatible with its use in gcc, in these
169   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
170   give the same symbol without quotes for an alternative entry point.  You
171   must define both, or neither. */
172#define NAME__MAIN "__gccmain"
173#define SYMBOL__MAIN __gccmain
174
175#define ASM_FILE_END(STREAM)		\
176do					\
177{					\
178  if (flag_pic)				\
179    aof_dump_pic_table (STREAM);	\
180  aof_dump_imports (STREAM);		\
181  fputs ("\tEND\n", (STREAM));		\
182} while (0);
183
184#define ASM_COMMENT_START ";"
185
186#define ASM_APP_ON ""
187
188#define ASM_APP_OFF ""
189
190#define ASM_OUTPUT_ASCII(STREAM,PTR,LEN)		\
191{							\
192  int i;						\
193  const char *ptr = (PTR);				\
194  fprintf ((STREAM), "\tDCB");				\
195  for (i = 0; i < (long)(LEN); i++)			\
196    fprintf ((STREAM), " &%02x%s", 			\
197	     (unsigned ) *(ptr++),			\
198	     (i + 1 < (long)(LEN)				\
199	      ? ((i & 3) == 3 ? "\n\tDCB" : ",")	\
200	      : "\n"));					\
201}
202
203#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
204
205/* Output of Uninitialized Variables */
206
207#define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED)		\
208  (common_section (),						\
209   fprintf ((STREAM), "\tAREA "),				\
210   assemble_name ((STREAM), (NAME)),				\
211   fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n",	\
212	    (ROUNDED), ASM_COMMENT_START, SIZE))
213
214#define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED)	\
215   (zero_init_section (),				\
216    assemble_name ((STREAM), (NAME)),			\
217    fprintf ((STREAM), "\n"),				\
218    fprintf ((STREAM), "\t%% %d\t%s size=%d\n",		\
219	     (ROUNDED), ASM_COMMENT_START, SIZE))
220
221/* Output and Generation of Labels */
222
223extern int arm_main_function;
224
225#define ASM_GLOBALIZE_LABEL(STREAM,NAME)		\
226do {							\
227  fprintf ((STREAM), "\tEXPORT\t");			\
228  assemble_name ((STREAM), (NAME));			\
229  fputc ('\n', (STREAM));				\
230  if ((NAME)[0] == 'm' && ! strcmp ((NAME), "main"))	\
231    arm_main_function = 1;				\
232} while (0)
233
234#define ASM_OUTPUT_LABEL(STREAM,NAME)	\
235do {					\
236  assemble_name (STREAM,NAME);		\
237  fputs ("\n", STREAM);			\
238} while (0)
239
240#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
241{						\
242  if (TARGET_POKE_FUNCTION_NAME)		\
243    arm_poke_function_name ((STREAM), (NAME));	\
244  ASM_OUTPUT_LABEL (STREAM, NAME);		\
245  if (! TREE_PUBLIC (DECL))			\
246    {						\
247      fputs ("\tKEEP ", STREAM);		\
248      ASM_OUTPUT_LABEL (STREAM, NAME);		\
249    }						\
250  aof_delete_import ((NAME));			\
251}
252
253#define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
254{						\
255  ASM_OUTPUT_LABEL (STREAM, NAME);		\
256  if (! TREE_PUBLIC (DECL))			\
257    {						\
258      fputs ("\tKEEP ", STREAM);		\
259      ASM_OUTPUT_LABEL (STREAM, NAME);		\
260    }						\
261  aof_delete_import ((NAME));			\
262}
263
264#define ASM_OUTPUT_EXTERNAL(STREAM,DECL,NAME)	\
265 aof_add_import ((NAME))
266
267#define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF)	\
268 (fprintf ((STREAM), "\tIMPORT\t"),			\
269  assemble_name ((STREAM), XSTR ((SYMREF), 0)),		\
270  fputc ('\n', (STREAM)))
271
272#define ASM_OUTPUT_LABELREF(STREAM,NAME)	\
273  fprintf ((STREAM), "|%s|", NAME)
274
275#define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM)	\
276  sprintf ((STRING), "*|%s..%ld|", (PREFIX), (long)(NUM))
277
278#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER)	\
279 ((OUTVAR) = (char *) alloca (strlen ((NAME)) + 10),	\
280  sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
281
282/* How initialization functions are handled */
283
284#define CTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
285#define DTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
286
287/* Output of Assembler Instructions */
288
289#define REGISTER_NAMES			\
290{					\
291  "a1", "a2", "a3", "a4",	\
292  "v1", "v2", "v3", "v4",	\
293  "v5", "v6", "sl", "fp",	\
294  "ip", "sp", "lr", "pc",	\
295  "f0", "f1", "f2", "f3",	\
296  "f4", "f5", "f6", "f7",	\
297  "cc", "sfp", "afp"		\
298}
299
300#define ADDITIONAL_REGISTER_NAMES		\
301{						\
302  {"r0", 0}, {"a1", 0},				\
303  {"r1", 1}, {"a2", 1},				\
304  {"r2", 2}, {"a3", 2},				\
305  {"r3", 3}, {"a4", 3},		      		\
306  {"r4", 4}, {"v1", 4},				\
307  {"r5", 5}, {"v2", 5},				\
308  {"r6", 6}, {"v3", 6},				\
309  {"r7", 7}, {"wr", 7},				\
310  {"r8", 8}, {"v5", 8},				\
311  {"r9", 9}, {"v6", 9},				\
312  {"r10", 10}, {"sl", 10}, {"v7", 10},		\
313  {"r11", 11}, {"fp", 11},			\
314  {"r12", 12}, {"ip", 12}, 			\
315  {"r13", 13}, {"sp", 13}, 			\
316  {"r14", 14}, {"lr", 14},			\
317  {"r15", 15}, {"pc", 15}			\
318}
319
320#define REGISTER_PREFIX "__"
321#define USER_LABEL_PREFIX ""
322#define LOCAL_LABEL_PREFIX ""
323
324/* AOF does not prefix user function names with an underscore.  */
325#define ARM_MCOUNT_NAME "_mcount"
326
327/* Output of Dispatch Tables */
328
329#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL)			\
330  do {									\
331    if (TARGET_ARM)							\
332      fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE));			\
333    else								\
334      fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL));	\
335  } while (0)
336
337#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE)	\
338  fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
339
340/* A label marking the start of a jump table is a data label. */
341#define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE)	\
342  fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
343
344/* Assembler Commands for Alignment */
345
346#define ASM_OUTPUT_SKIP(STREAM,NBYTES)		\
347 fprintf ((STREAM), "\t%%\t%d\n", (NBYTES))
348
349#define ASM_OUTPUT_ALIGN(STREAM,POWER)			\
350do {							\
351  register int amount = 1 << (POWER);			\
352  if (amount == 2)					\
353    fprintf ((STREAM), "\tALIGN 2\n");			\
354  else if (amount == 4)					\
355    fprintf ((STREAM), "\tALIGN\n");			\
356  else							\
357    fprintf ((STREAM), "\tALIGN %d\n", amount);		\
358} while (0)
359
360#undef DBX_DEBUGGING_INFO
361