(TARGET_CPU_arm*, TARGET_CPU_strongarm*, TARGET_CPU_generic):
[official-gcc.git] / gcc / config / arm / aof.h
blobab9093d068c97b98816fbe9a89b42334bd4404d8
1 /* Definitions of target machine for GNU compiler, for Advanced RISC Machines
2 ARM compilation, AOF Assembler.
3 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
25 #define AOF_ASSEMBLER
27 #define LINK_LIBGCC_SPECIAL 1
29 #define LINK_SPEC "%{aof} %{bin} %{aif} %{ihf} %{shl,*} %{reent*} %{split} \
30 %{ov*,*} %{reloc*} -nodebug"
32 #define STARTFILE_SPEC "crtbegin.o%s"
34 #define ENDFILE_SPEC "crtend.o%s"
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
41 #ifndef LIB_SPEC
42 #define LIB_SPEC "%{Eb: armlib_h.32b%s}%{!Eb: armlib_h.32l%s}"
43 #endif
45 #define LIBGCC_SPEC "libgcc.a%s"
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 char *aof_text_section ();
56 #define TEXT_SECTION_ASM_OP aof_text_section ()
58 #define SELECT_RTX_SECTION(MODE,RTX) text_section ();
60 char *aof_data_section ();
61 #define DATA_SECTION_ASM_OP aof_data_section ()
63 #define EXTRA_SECTIONS in_zero_init, in_ctor, in_dtor
65 #define EXTRA_SECTION_FUNCTIONS \
66 ZERO_INIT_SECTION \
67 CTOR_SECTION \
68 DTOR_SECTION
70 #define ZERO_INIT_SECTION \
71 void \
72 zero_init_section () \
73 { \
74 static int zero_init_count = 1; \
75 if (in_section != in_zero_init) \
76 { \
77 fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
78 zero_init_count++); \
79 in_section = in_zero_init; \
80 } \
83 #define CTOR_SECTION \
84 void \
85 ctor_section () \
86 { \
87 static int ctors_once = 0; \
88 if (in_section != in_ctor) \
89 { \
90 if (ctors_once) \
91 { \
92 fprintf (stderr, \
93 "Attempt to output more than one ctor section\n"); \
94 abort (); \
95 } \
96 fprintf (asm_out_file, "\t%s\n", CTORS_SECTION_ASM_OP); \
97 in_section = in_ctor; \
98 ctors_once = 1; \
99 } \
102 #define DTOR_SECTION \
103 void \
104 dtor_section () \
106 static int dtors_once = 0; \
107 if (in_section != in_dtor) \
109 if (dtors_once) \
111 fprintf (stderr, \
112 "Attempt to output more than one dtor section\n"); \
113 abort (); \
115 fprintf (asm_out_file, "\t%s\n", DTORS_SECTION_ASM_OP); \
116 in_section = in_dtor; \
117 dtors_once = 1; \
121 #define CTOR_LIST_BEGIN \
122 asm (CTORS_SECTION_ASM_OP); \
123 extern func_ptr __CTOR_END__[1]; \
124 func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
126 #define CTOR_LIST_END \
127 asm (CTORS_SECTION_ASM_OP); \
128 func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
130 #define DO_GLOBAL_CTORS_BODY \
131 do { \
132 func_ptr *ptr = __CTOR_LIST__ + 1; \
133 while (*ptr) \
134 (*ptr++) (); \
135 } while (0)
137 #define DTOR_LIST_BEGIN \
138 asm (DTORS_SECTION_ASM_OP); \
139 extern func_ptr __DTOR_END__[1]; \
140 func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
142 #define DTOR_LIST_END \
143 asm (DTORS_SECTION_ASM_OP); \
144 func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
146 #define DO_GLOBAL_DTORS_BODY \
147 do { \
148 func_ptr *ptr = __DTOR_LIST__ + 1; \
149 while (*ptr) \
150 (*ptr++) (); \
151 } while (0)
153 #define JUMP_TABLES_IN_TEXT_SECTION 1
155 #ifndef ARM_OS_NAME
156 #define ARM_OS_NAME "(generic)"
157 #endif
159 /* For the AOF linker, we need to reference __main to force the standard
160 library to get linked in. */
162 #define ASM_FILE_START(STREAM) \
164 extern char *version_string; \
165 fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", \
166 ASM_COMMENT_START, version_string, ARM_OS_NAME); \
167 fprintf ((STREAM), "__a1\tRN\t0\n"); \
168 fprintf ((STREAM), "__a2\tRN\t1\n"); \
169 fprintf ((STREAM), "__a3\tRN\t2\n"); \
170 fprintf ((STREAM), "__a4\tRN\t3\n"); \
171 fprintf ((STREAM), "__v1\tRN\t4\n"); \
172 fprintf ((STREAM), "__v2\tRN\t5\n"); \
173 fprintf ((STREAM), "__v3\tRN\t6\n"); \
174 fprintf ((STREAM), "__v4\tRN\t7\n"); \
175 fprintf ((STREAM), "__v5\tRN\t8\n"); \
176 fprintf ((STREAM), "__v6\tRN\t9\n"); \
177 fprintf ((STREAM), "__sl\tRN\t10\n"); \
178 fprintf ((STREAM), "__fp\tRN\t11\n"); \
179 fprintf ((STREAM), "__ip\tRN\t12\n"); \
180 fprintf ((STREAM), "__sp\tRN\t13\n"); \
181 fprintf ((STREAM), "__lr\tRN\t14\n"); \
182 fprintf ((STREAM), "__pc\tRN\t15\n"); \
183 fprintf ((STREAM), "__f0\tFN\t0\n"); \
184 fprintf ((STREAM), "__f1\tFN\t1\n"); \
185 fprintf ((STREAM), "__f2\tFN\t2\n"); \
186 fprintf ((STREAM), "__f3\tFN\t3\n"); \
187 fprintf ((STREAM), "__f4\tFN\t4\n"); \
188 fprintf ((STREAM), "__f5\tFN\t5\n"); \
189 fprintf ((STREAM), "__f6\tFN\t6\n"); \
190 fprintf ((STREAM), "__f7\tFN\t7\n"); \
191 text_section (); \
194 /* Some systems use __main in a way incompatible with its use in gcc, in these
195 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
196 give the same symbol without quotes for an alternative entry point. You
197 must define both, or niether. */
198 #define NAME__MAIN "__gccmain"
199 #define SYMBOL__MAIN __gccmain
201 #define ASM_FILE_END(STREAM) \
202 do \
204 if (flag_pic) \
205 aof_dump_pic_table (STREAM); \
206 aof_dump_imports (STREAM); \
207 fputs ("\tEND\n", (STREAM)); \
208 } while (0);
210 #define ASM_IDENTIFY_GCC(STREAM) fputs ("|gcc2_compiled.|\n", (STREAM))
212 #define ASM_COMMENT_START ";"
214 #define ASM_APP_ON ""
216 #define ASM_APP_OFF ""
218 #define ASM_OUTPUT_LONG_DOUBLE(STREAM,VALUE) \
219 ASM_OUTPUT_DOUBLE((STREAM),(VALUE))
221 #define ASM_OUTPUT_DOUBLE(STREAM,VALUE) \
222 do { \
223 char dstr[30]; \
224 long l[2]; \
225 REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), l); \
226 REAL_VALUE_TO_DECIMAL ((VALUE), "%.14g", dstr); \
227 fprintf ((STREAM), "\tDCD &%lx, &%lx\t%s double %s\n", \
228 l[0], l[1], ASM_COMMENT_START, dstr); \
229 } while (0)
231 #define ASM_OUTPUT_FLOAT(STREAM,VALUE) \
232 do { \
233 char dstr[30]; \
234 long l; \
235 REAL_VALUE_TO_TARGET_SINGLE ((VALUE), l); \
236 REAL_VALUE_TO_DECIMAL ((VALUE), "%.7g", dstr); \
237 fprintf ((STREAM), "\tDCD &%lx\t%s double %s\n", \
238 l, ASM_COMMENT_START, dstr); \
239 } while (0)
241 #define ASM_OUTPUT_INT(STREAM,VALUE) \
242 (fprintf ((STREAM), "\tDCD\t"), \
243 output_addr_const ((STREAM), (VALUE)), \
244 fputc ('\n', (STREAM)))
246 #define ASM_OUTPUT_SHORT(STREAM,VALUE) \
247 (fprintf ((STREAM), "\tDCW\t"), \
248 output_addr_const ((STREAM), (VALUE)), \
249 fputc ('\n', (STREAM)))
251 #define ASM_OUTPUT_CHAR(STREAM,VALUE) \
252 (fprintf ((STREAM), "\tDCB\t"), \
253 output_addr_const ((STREAM), (VALUE)), \
254 fputc ('\n', (STREAM)))
256 #define ASM_OUTPUT_BYTE(STREAM,VALUE) \
257 fprintf ((STREAM), "\tDCB\t%d\n", (VALUE))
259 #define ASM_OUTPUT_ASCII(STREAM,PTR,LEN) \
261 int i; \
262 char *ptr = (PTR); \
263 fprintf ((STREAM), "\tDCB"); \
264 for (i = 0; i < (LEN); i++) \
265 fprintf ((STREAM), " &%02x%s", \
266 (unsigned ) *(ptr++), \
267 (i + 1 < (LEN) \
268 ? ((i & 3) == 3 ? "\n\tDCB" : ",") \
269 : "\n")); \
272 #define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
274 #define ASM_OPEN_PAREN "("
275 #define ASM_CLOSE_PAREN ")"
277 /* Output of Uninitialized Variables */
279 #define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED) \
280 (fprintf ((STREAM), "\tAREA "), \
281 assemble_name ((STREAM), (NAME)), \
282 fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
283 (ROUNDED), ASM_COMMENT_START, SIZE))
285 #define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED) \
286 (zero_init_section (), \
287 assemble_name ((STREAM), (NAME)), \
288 fprintf ((STREAM), "\n"), \
289 fprintf ((STREAM), "\t%% %d\t%s size=%d\n", \
290 (ROUNDED), ASM_COMMENT_START, SIZE))
292 /* Output and Generation of Labels */
294 extern int arm_main_function;
296 #define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
297 do { \
298 fprintf ((STREAM), "\tEXPORT\t"); \
299 assemble_name ((STREAM), (NAME)); \
300 fputc ('\n', (STREAM)); \
301 if ((NAME)[0] == 'm' && ! strcmp ((NAME), "main")) \
302 arm_main_function = 1; \
303 } while (0)
305 #define ARM_OUTPUT_LABEL(STREAM,NAME) \
306 do { \
307 assemble_name (STREAM,NAME); \
308 fputs ("\n", STREAM); \
309 } while (0)
311 #define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL) \
313 ASM_OUTPUT_LABEL (STREAM, NAME); \
314 if (! TREE_PUBLIC (DECL)) \
316 fputs ("\tKEEP ", STREAM); \
317 ASM_OUTPUT_LABEL (STREAM, NAME); \
319 aof_delete_import ((NAME)); \
322 #define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
324 ASM_OUTPUT_LABEL (STREAM, NAME); \
325 if (! TREE_PUBLIC (DECL)) \
327 fputs ("\tKEEP ", STREAM); \
328 ASM_OUTPUT_LABEL (STREAM, NAME); \
330 aof_delete_import ((NAME)); \
333 #define ASM_OUTPUT_EXTERNAL(STREAM,DECL,NAME) \
334 aof_add_import ((NAME))
336 #define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF) \
337 (fprintf ((STREAM), "\tIMPORT\t"), \
338 assemble_name ((STREAM), XSTR ((SYMREF), 0)), \
339 fputc ('\n', (STREAM)))
341 #define ASM_OUTPUT_LABELREF(STREAM,NAME) \
342 fprintf ((STREAM), "|%s|", NAME)
344 #define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM) \
345 sprintf ((STRING), "*|%s..%d|", (PREFIX), (NUM))
347 #define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
348 ((OUTVAR) = (char *) alloca (strlen ((NAME)) + 10), \
349 sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
351 /* How initialization functions are handled */
353 #define CTORS_SECTION_ASM_OP "AREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
354 #define DTORS_SECTION_ASM_OP "AREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
356 #define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
357 do { \
358 ctor_section (); \
359 fprintf ((STREAM), "\tDCD\t"); \
360 assemble_name ((STREAM), (NAME)); \
361 fputc ('\n', (STREAM)); \
362 } while (0);
364 #define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
365 do { \
366 dtor_section (); \
367 fprintf ((STREAM), "\tDCD\t"); \
368 assemble_name ((STREAM), (NAME)); \
369 fputc ('\n', (STREAM)); \
370 } while (0);
372 /* Output of Assembler Instructions */
374 #define REGISTER_NAMES \
376 "a1", "a2", "a3", "a4", \
377 "v1", "v2", "v3", "v4", \
378 "v5", "v6", "sl", "fp", \
379 "ip", "sp", "lr", "pc", \
380 "f0", "f1", "f2", "f3", \
381 "f4", "f5", "f6", "f7", \
382 "cc", "sfp", "afp" \
385 #define ADDITIONAL_REGISTER_NAMES \
387 {"r0", 0}, {"a1", 0}, \
388 {"r1", 1}, {"a2", 1}, \
389 {"r2", 2}, {"a3", 2}, \
390 {"r3", 3}, {"a4", 3}, \
391 {"r4", 4}, {"v1", 4}, \
392 {"r5", 5}, {"v2", 5}, \
393 {"r6", 6}, {"v3", 6}, \
394 {"r7", 7}, {"wr", 7}, \
395 {"r8", 8}, {"v5", 8}, \
396 {"r9", 9}, {"v6", 9}, \
397 {"r10", 10}, {"sl", 10}, {"v7", 10}, \
398 {"r11", 11}, {"fp", 11}, \
399 {"r12", 12}, {"ip", 12}, \
400 {"r13", 13}, {"sp", 13}, \
401 {"r14", 14}, {"lr", 14}, \
402 {"r15", 15}, {"pc", 15} \
405 #define REGISTER_PREFIX "__"
406 #define USER_LABEL_PREFIX ""
407 #define LOCAL_LABEL_PREFIX ""
409 /* Output of Dispatch Tables */
411 #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,VALUE,REL) \
412 fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE))
414 #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
415 fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
417 /* A label marking the start of a jump table is a data label. */
418 #define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) \
419 fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
421 /* Assembler Commands for Alignment */
423 #define ASM_OUTPUT_SKIP(STREAM,NBYTES) \
424 fprintf ((STREAM), "\t%%\t%d\n", (NBYTES))
426 #define ASM_OUTPUT_ALIGN(STREAM,POWER) \
427 do { \
428 register int amount = 1 << (POWER); \
429 if (amount == 2) \
430 fprintf ((STREAM), "\tALIGN 2\n"); \
431 else if (amount == 4) \
432 fprintf ((STREAM), "\tALIGN\n"); \
433 else \
434 fprintf ((STREAM), "\tALIGN %d\n", amount); \
435 } while (0)
437 #include "arm/arm.h"
439 #undef DBX_DEBUGGING_INFO