1/* Definitions of target machine for GNU compiler,
2   for ARM with COFF obj format.
3   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
4   Contributed by Doug Evans (dje@cygnus.com).
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#include "arm/semi.h"
24#include "arm/aout.h"
25
26#undef  USER_LABEL_PREFIX
27#define USER_LABEL_PREFIX "_"
28
29
30/* Run-time Target Specification.  */
31#undef  TARGET_VERSION
32#define TARGET_VERSION fputs (" (ARM/coff)", stderr)
33
34#undef  TARGET_DEFAULT
35#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32)
36
37#define MULTILIB_DEFAULTS { "mlittle-endian", "msoft-float", "mapcs-32" }
38
39/* Setting this to 32 produces more efficient code, but the value set in previous
40   versions of this toolchain was 8, which produces more compact structures. The
41   command line option -mstructure_size_boundary=<n> can be used to change this
42   value.  */
43#undef  STRUCTURE_SIZE_BOUNDARY
44#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
45
46extern int arm_structure_size_boundary;
47
48/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
49   is a valid machine specific attribute for DECL.
50   The attributes in ATTRIBUTES have previously been assigned to DECL.  */
51#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
52arm_valid_machine_decl_attribute (DECL, IDENTIFIER, ARGS)
53
54/* This is COFF, but prefer stabs.  */
55#define SDB_DEBUGGING_INFO
56
57#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
58
59#include "dbxcoff.h"
60
61/* A C statement to output assembler commands which will identify the
62   object file as having been compiled with GNU CC (or another GNU
63   compiler).  */
64/* Define this to NULL so we don't get anything.
65   We have ASM_IDENTIFY_LANGUAGE.
66   Also, when using stabs, gcc2_compiled must be a stabs entry, not an
67   ordinary symbol, or gdb won't see it.  The stabs entry must be
68   before the N_SO in order for gdb to find it.  */
69#define ASM_IDENTIFY_GCC(STREAM) 				\
70     fprintf (STREAM, "%sgcc2_compiled.:\n", LOCAL_LABEL_PREFIX )
71
72/* This outputs a lot of .req's to define alias for various registers.
73   Let's try to avoid this.  */
74#undef ASM_FILE_START
75#define ASM_FILE_START(STREAM) \
76do {								\
77  extern char *version_string;					\
78  fprintf (STREAM, "%s Generated by gcc %s for ARM/coff\n",	\
79	   ASM_COMMENT_START, version_string);			\
80} while (0)
81
82/* A C statement to output something to the assembler file to switch to section
83   NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
84   NULL_TREE.  Some target formats do not support arbitrary sections.  Do not
85   define this macro in such cases.  */
86#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
87do {								\
88  if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL)		\
89    fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME));		\
90  else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC))	\
91    fprintf (STREAM, "\t.section %s,\"\"\n", (NAME));		\
92  else								\
93    fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME));		\
94} while (0)
95
96/* Support the ctors/dtors and other sections.  */
97
98#undef INIT_SECTION_ASM_OP
99
100/* Define this macro if jump tables (for `tablejump' insns) should be
101   output in the text section, along with the assembler instructions.
102   Otherwise, the readonly data section is used.  */
103#define JUMP_TABLES_IN_TEXT_SECTION 1
104
105#undef  READONLY_DATA_SECTION
106#define READONLY_DATA_SECTION	rdata_section
107#undef  RDATA_SECTION_ASM_OP
108#define RDATA_SECTION_ASM_OP	"\t.section .rdata"
109#undef  CTORS_SECTION_ASM_OP
110#define CTORS_SECTION_ASM_OP	"\t.section .ctors,\"x\""
111#undef  DTORS_SECTION_ASM_OP
112#define DTORS_SECTION_ASM_OP	"\t.section .dtors,\"x\""
113
114/* A list of other sections which the compiler might be "in" at any
115   given time.  */
116
117#undef EXTRA_SECTIONS
118#define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata, in_ctors, in_dtors
119
120#define SUBTARGET_EXTRA_SECTIONS
121
122/* A list of extra section function definitions.  */
123
124#undef EXTRA_SECTION_FUNCTIONS
125#define EXTRA_SECTION_FUNCTIONS \
126  RDATA_SECTION_FUNCTION	\
127  CTORS_SECTION_FUNCTION	\
128  DTORS_SECTION_FUNCTION	\
129  SUBTARGET_EXTRA_SECTION_FUNCTIONS
130
131#define SUBTARGET_EXTRA_SECTION_FUNCTIONS
132
133#define RDATA_SECTION_FUNCTION \
134void									\
135rdata_section ()							\
136{									\
137  if (in_section != in_rdata)						\
138    {									\
139      fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP);		\
140      in_section = in_rdata;						\
141    }									\
142}
143
144#define CTORS_SECTION_FUNCTION \
145void									\
146ctors_section ()							\
147{									\
148  if (in_section != in_ctors)						\
149    {									\
150      fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);		\
151      in_section = in_ctors;						\
152    }									\
153}
154
155#define DTORS_SECTION_FUNCTION \
156void									\
157dtors_section ()							\
158{									\
159  if (in_section != in_dtors)						\
160    {									\
161      fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);		\
162      in_section = in_dtors;						\
163    }									\
164}
165
166/* Support the ctors/dtors sections for g++.  */
167
168#define INT_ASM_OP ".word"
169
170/* A C statement (sans semicolon) to output an element in the table of
171   global constructors.  */
172#undef ASM_OUTPUT_CONSTRUCTOR
173#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
174do {						\
175  ctors_section ();				\
176  fprintf (STREAM, "\t%s\t ", INT_ASM_OP);	\
177  assemble_name (STREAM, NAME);			\
178  fprintf (STREAM, "\n");			\
179} while (0)
180
181/* A C statement (sans semicolon) to output an element in the table of
182   global destructors.  */
183#undef ASM_OUTPUT_DESTRUCTOR
184#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
185do {						\
186  dtors_section ();                   		\
187  fprintf (STREAM, "\t%s\t ", INT_ASM_OP);	\
188  assemble_name (STREAM, NAME);              	\
189  fprintf (STREAM, "\n");			\
190} while (0)
191
192/* __CTOR_LIST__ and __DTOR_LIST__ must be defined by the linker script.  */
193#define CTOR_LISTS_DEFINED_EXTERNALLY
194
195#undef DO_GLOBAL_CTORS_BODY
196#undef DO_GLOBAL_DTORS_BODY
197
198/* If you don't define HAVE_ATEXIT, and the object file format/OS/whatever
199   does not support constructors/destructors, then gcc implements destructors
200   by defining its own exit function, which calls the destructors.  This gcc
201   exit function overrides the C library's exit function, and this can cause
202   all kinds of havoc if the C library has a non-trivial exit function.  You
203   really don't want to use the exit function in libgcc2.c.  */
204#define HAVE_ATEXIT
205
206/* The ARM development system defines __main.  */
207#define NAME__MAIN "__gccmain"
208#define SYMBOL__MAIN __gccmain
209