/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
ARM compilation, AOF Assembler.
- Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2000, 2003, 2004, 2007
+ Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
- the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
\f
#define ENDFILE_SPEC "crtend.o%s"
#ifndef ASM_SPEC
-#define ASM_SPEC "%{g -g} -arch 4 \
--apcs 3%{mapcs-32:/32bit}%{mapcs-26:/26bit}%{!mapcs-26:%{!macps-32:/26bit}}"
+#define ASM_SPEC "%{g -g} -arch 4 -apcs 3/32bit"
#endif
#ifndef LIB_SPEC
#define LIBGCC_SPEC "libgcc.a%s"
-/* Dividing the Output into Sections (Text, Data, ...) */
-/* AOF Assembler syntax is a nightmare when it comes to areas, since once
- we change from one area to another, we can't go back again. Instead,
- we must create a new area with the same attributes and add the new output
- to that. Unfortunately, there is nothing we can do here to guarantee that
- two areas with the same attributes will be linked adjacently in the
- resulting executable, so we have to be careful not to do pc-relative
- addressing across such boundaries. */
-#define TEXT_SECTION_ASM_OP aof_text_section ()
-
-#define DATA_SECTION_ASM_OP aof_data_section ()
-
-#define EXTRA_SECTIONS in_zero_init, in_common
-
-#define EXTRA_SECTION_FUNCTIONS \
-ZERO_INIT_SECTION \
-COMMON_SECTION
-
-#define ZERO_INIT_SECTION \
-void \
-zero_init_section () \
-{ \
- static int zero_init_count = 1; \
- if (in_section != in_zero_init) \
- { \
- fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
- zero_init_count++); \
- in_section = in_zero_init; \
- } \
-}
-
-/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
- changed areas. */
-#define COMMON_SECTION \
-void \
-common_section () \
-{ \
- if (in_section != in_common) \
- { \
- in_section = in_common; \
- } \
-}
-#define CTOR_LIST_BEGIN \
-asm (CTORS_SECTION_ASM_OP); \
-extern func_ptr __CTOR_END__[1]; \
-func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
+#define CTOR_LIST_BEGIN \
+ asm (CTORS_SECTION_ASM_OP); \
+ extern func_ptr __CTOR_END__[1]; \
+ func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
-#define CTOR_LIST_END \
-asm (CTORS_SECTION_ASM_OP); \
-func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+#define CTOR_LIST_END \
+ asm (CTORS_SECTION_ASM_OP); \
+ func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
-#define DO_GLOBAL_CTORS_BODY \
-do { \
- func_ptr *ptr = __CTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define DO_GLOBAL_CTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __CTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
-#define DTOR_LIST_BEGIN \
-asm (DTORS_SECTION_ASM_OP); \
-extern func_ptr __DTOR_END__[1]; \
-func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
+#define DTOR_LIST_BEGIN \
+ asm (DTORS_SECTION_ASM_OP); \
+ extern func_ptr __DTOR_END__[1]; \
+ func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
-#define DTOR_LIST_END \
-asm (DTORS_SECTION_ASM_OP); \
-func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+#define DTOR_LIST_END \
+ asm (DTORS_SECTION_ASM_OP); \
+ func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
-#define DO_GLOBAL_DTORS_BODY \
-do { \
- func_ptr *ptr = __DTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define DO_GLOBAL_DTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __DTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
/* We really want to put Thumb tables in a read-only data section, but
switching to another section during function output is not
whole table generation until the end of the function. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-#ifndef ARM_OS_NAME
-#define ARM_OS_NAME "(generic)"
-#endif
-
-/* For the AOF linker, we need to reference __main to force the standard
- library to get linked in. */
-
-#define ASM_FILE_START(STREAM) \
-{ \
- fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", \
- ASM_COMMENT_START, version_string, ARM_OS_NAME); \
- fprintf ((STREAM), "__r0\tRN\t0\n"); \
- fprintf ((STREAM), "__a1\tRN\t0\n"); \
- fprintf ((STREAM), "__a2\tRN\t1\n"); \
- fprintf ((STREAM), "__a3\tRN\t2\n"); \
- fprintf ((STREAM), "__a4\tRN\t3\n"); \
- fprintf ((STREAM), "__v1\tRN\t4\n"); \
- fprintf ((STREAM), "__v2\tRN\t5\n"); \
- fprintf ((STREAM), "__v3\tRN\t6\n"); \
- fprintf ((STREAM), "__v4\tRN\t7\n"); \
- fprintf ((STREAM), "__v5\tRN\t8\n"); \
- fprintf ((STREAM), "__v6\tRN\t9\n"); \
- fprintf ((STREAM), "__sl\tRN\t10\n"); \
- fprintf ((STREAM), "__fp\tRN\t11\n"); \
- fprintf ((STREAM), "__ip\tRN\t12\n"); \
- fprintf ((STREAM), "__sp\tRN\t13\n"); \
- fprintf ((STREAM), "__lr\tRN\t14\n"); \
- fprintf ((STREAM), "__pc\tRN\t15\n"); \
- fprintf ((STREAM), "__f0\tFN\t0\n"); \
- fprintf ((STREAM), "__f1\tFN\t1\n"); \
- fprintf ((STREAM), "__f2\tFN\t2\n"); \
- fprintf ((STREAM), "__f3\tFN\t3\n"); \
- fprintf ((STREAM), "__f4\tFN\t4\n"); \
- fprintf ((STREAM), "__f5\tFN\t5\n"); \
- fprintf ((STREAM), "__f6\tFN\t6\n"); \
- fprintf ((STREAM), "__f7\tFN\t7\n"); \
- text_section (); \
-}
+#define TARGET_ASM_INIT_SECTIONS aof_asm_init_sections
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
- must define both, or neither. */
+ must define both, or neither. */
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
#define ASM_COMMENT_START ";"
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
-#define ASM_APP_ON ""
-
-#define ASM_APP_OFF ""
-
-#define ASM_OUTPUT_ASCII(STREAM,PTR,LEN) \
+#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
{ \
int i; \
const char *ptr = (PTR); \
for (i = 0; i < (long)(LEN); i++) \
fprintf ((STREAM), " &%02x%s", \
(unsigned ) *(ptr++), \
- (i + 1 < (long)(LEN) \
+ (i + 1 < (long)(LEN) \
? ((i & 3) == 3 ? "\n\tDCB" : ",") \
: "\n")); \
}
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
-/* Output of Uninitialized Variables */
+/* Output of Uninitialized Variables. */
-#define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED) \
- (common_section (), \
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
+ (in_section = NULL, \
fprintf ((STREAM), "\tAREA "), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
(int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
-#define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED) \
+#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
(zero_init_section (), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), "\n"), \
(int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
/* Output and Generation of Labels */
-
extern int arm_main_function;
/* Globalizing directive for a label. */
#define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM) \
sprintf ((STRING), "*|%s..%ld|", (PREFIX), (long)(NUM))
-/* How initialization functions are handled */
+/* How initialization functions are handled. */
#define CTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
#define DTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
-/* Output of Assembler Instructions */
-
-#define REGISTER_NAMES \
-{ \
- "a1", "a2", "a3", "a4", \
- "v1", "v2", "v3", "v4", \
- "v5", "v6", "sl", "fp", \
- "ip", "sp", "lr", "pc", \
- "f0", "f1", "f2", "f3", \
- "f4", "f5", "f6", "f7", \
- "cc", "sfp", "afp" \
+/* Output of Assembler Instructions. Note that the ?xx registers are
+ there so that VFPv3/NEON registers D16-D31 have the same spacing as D0-D15
+ (each of which is overlaid on two S registers), although there are no
+ actual single-precision registers which correspond to D16-D31. */
+
+#define REGISTER_NAMES \
+{ \
+ "a1", "a2", "a3", "a4", \
+ "v1", "v2", "v3", "v4", \
+ "v5", "v6", "sl", "fp", \
+ "ip", "sp", "lr", "pc", \
+ "f0", "f1", "f2", "f3", \
+ "f4", "f5", "f6", "f7", \
+ "cc", "sfp", "afp", \
+ "mv0", "mv1", "mv2", "mv3", \
+ "mv4", "mv5", "mv6", "mv7", \
+ "mv8", "mv9", "mv10", "mv11", \
+ "mv12", "mv13", "mv14", "mv15", \
+ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \
+ "wr0", "wr1", "wr2", "wr3", \
+ "wr4", "wr5", "wr6", "wr7", \
+ "wr8", "wr9", "wr10", "wr11", \
+ "wr12", "wr13", "wr14", "wr15", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", \
+ "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", \
+ "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", \
+ "d16", "?16", "d17", "?17", "d18", "?18", "d19", "?19", \
+ "d20", "?20", "d21", "?21", "d22", "?22", "d23", "?23", \
+ "d24", "?24", "d25", "?25", "d26", "?26", "d27", "?27", \
+ "d28", "?28", "d29", "?29", "d30", "?30", "d31", "?31", \
+ "vfpcc" \
}
#define ADDITIONAL_REGISTER_NAMES \
{"r12", 12}, {"ip", 12}, \
{"r13", 13}, {"sp", 13}, \
{"r14", 14}, {"lr", 14}, \
- {"r15", 15}, {"pc", 15} \
+ {"r15", 15}, {"pc", 15}, \
+ {"d0", 63}, \
+ {"d1", 65}, \
+ {"d2", 67}, \
+ {"d3", 69}, \
+ {"d4", 71}, \
+ {"d5", 73}, \
+ {"d6", 75}, \
+ {"d7", 77}, \
+ {"d8", 79}, \
+ {"d9", 81}, \
+ {"d10", 83}, \
+ {"d11", 85}, \
+ {"d12", 87}, \
+ {"d13", 89}, \
+ {"d14", 91}, \
+ {"d15", 93} \
}
#define REGISTER_PREFIX "__"
/* AOF does not prefix user function names with an underscore. */
#define ARM_MCOUNT_NAME "_mcount"
-/* Output of Dispatch Tables */
-
-#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
- do { \
- if (TARGET_ARM) \
- fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
- else \
- fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
- } while (0)
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
- fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
+/* Output of Dispatch Tables. */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
+ do \
+ { \
+ if (TARGET_ARM) \
+ fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
+ else if (TARGET_THUMB1) \
+ fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
+ else /* Thumb-2 */ \
+ { \
+ switch (GET_MODE(body)) \
+ { \
+ case QImode: /* TBB */ \
+ asm_fprintf (STREAM, "\tDCB\t(|L..%d| - |L..%d|)/2\n", \
+ VALUE, REL); \
+ break; \
+ case HImode: /* TBH */ \
+ asm_fprintf (STREAM, "\tDCW\t|L..%d| - |L..%d|)/2\n", \
+ VALUE, REL); \
+ break; \
+ case SImode: \
+ if (flag_pic) \
+ asm_fprintf (STREAM, "\tDCD\t|L..%d| + 1 - |L..%d|\n", \
+ VALUE, REL); \
+ else \
+ asm_fprintf (STREAM, "\tDCD\t|L..%d| + 1\n", VALUE); \
+ break; \
+ default: \
+ gcc_unreachable(); \
+ } \
+ } \
+ } \
+ while (0)
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
+ do \
+ { \
+ gcc_assert (!TARGET_THUMB2) \
+ fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE)) \
+ } \
+ while (0)
+
-/* A label marking the start of a jump table is a data label. */
-#define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) \
+/* A label marking the start of a jump table is a data label. */
+#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
-/* Assembler Commands for Alignment */
-
-#define ASM_OUTPUT_SKIP(STREAM,NBYTES) \
- fprintf ((STREAM), "\t%%\t%d\n", (int)(NBYTES))
-
-#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
-do { \
- register int amount = 1 << (POWER); \
- if (amount == 2) \
- fprintf ((STREAM), "\tALIGN 2\n"); \
- else if (amount == 4) \
- fprintf ((STREAM), "\tALIGN\n"); \
- else \
- fprintf ((STREAM), "\tALIGN %d\n", amount); \
-} while (0)
+/* Assembler Commands for Alignment. */
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+ fprintf ((STREAM), "\t%%\t%d\n", (int) (NBYTES))
+
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do \
+ { \
+ int amount = 1 << (POWER); \
+ \
+ if (amount == 2) \
+ fprintf ((STREAM), "\tALIGN 2\n"); \
+ else if (amount == 4) \
+ fprintf ((STREAM), "\tALIGN\n"); \
+ else \
+ fprintf ((STREAM), "\tALIGN %d\n", amount); \
+ } \
+ while (0)
#undef DBX_DEBUGGING_INFO