home *** CD-ROM | disk | FTP | other *** search
- /* Definitions of target machine for GNU compiler. amiga 68000/68020 version.
- Copyright (C) 1992 Free Software Foundation, Inc.
- Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch).
-
- This file is part of GNU CC.
-
- GNU CC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU CC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU CC; see the file COPYING. If not, write to
- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- #include "m68k/m68k.h"
-
- /* See m68k.h for bits in TARGET_DEFAULT.
- 0 means 68000, no hardware fpu (68881/68882/68040).
- 7 means 68020 (or higher) with hardware fpu. */
-
- #ifndef TARGET_DEFAULT
- #define TARGET_DEFAULT 0
- #endif
-
- /* Define __HAVE_68881__ in preprocessor according to the -m flags.
- This will control the use of inline 68881 insns in certain macros.
- Also inform the program which CPU this is for. */
-
- #if TARGET_DEFAULT & 02
-
- /* -m68881 is the default */
- #define CPP_SPEC \
- "%{!msoft-float:-D__HAVE_68881__ }\
- %{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
-
- #else
-
- /* -msoft-float is the default, assume -mc68000 as well */
- #define CPP_SPEC \
- "%{m68881:-D__HAVE_68881__ }\
- %{!ansi:%{m68020:-Dmc68020}%{mc68020:-Dmc68020}%{!mc68020:%{!m68020:-Dmc68010}}}"
-
- /* Don't try using XFmode since we don't have appropriate runtime software
- support. */
- #undef LONG_DOUBLE_TYPE_SIZE
- #define LONG_DOUBLE_TYPE_SIZE 64
-
- #endif
-
- /* -m68000 requires special flags to the assembler. */
-
- #if TARGET_DEFAULT & 01
-
- #define ASM_SPEC \
- "%{m68000:-mc68010}%{mc68000:-mc68010}%{!mc68000:%{!m68000:-mc68020}} %{msmall-code:-l} "
-
- #else
-
- #define ASM_SPEC \
- "%{m68020:-mc68020}%{mc68020:-mc68020}%{!mc68020:%{!m68020:-mc68010}} %{msmall-code:-l} "
-
- #endif
-
- /* amiga/amigados are the new "standard" defines for the Amiga, MCH_AMIGA
- * was used before and is included for compatibility reasons */
-
- #define CPP_PREDEFINES "-Dmc68000 -Damiga -Damigados -DMCH_AMIGA -DAMIGA"
-
- /* Choose the right startup file, depending on whether we use base relative
- code, base relative code with automatic relocation (-resident), or plain
- crt0.o.
-
- Profiling is currently only available for plain startup.
- mcrt0.o does not (yet) exist. */
-
- #define STARTFILE_SPEC \
- "%{resident:rcrt0.o%s}%{!resident:%{!fbaserel:%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}%{fbaserel:%{pg:bgcrt0.o%s}%{!pg:%{p:bmcrt0.o%s}%{!p:bcrt0.o%s}}}}"
-
-
- /* Automatically search libamiga.a for AmigaDOS specific functions. Note
- that we first search the standard C library to resolve as much as
- possible from there, since it has names that are duplicated in libamiga.a
- which we *don't* want from there. Then search the standard C library
- again to resolve any references that libamiga.a might have generated.
- This may only be a temporary solution since it might be better to simply
- remove the things from libamiga.a that should be pulled in from libc.a
- instead, which would eliminate the first reference to libc.a. */
-
- #define LIB_SPEC "%{!p:%{!pg:-lc -lamiga -lc}}%{p:-lc_p -lamiga -lc_p}%{pg:-lc_p -lamiga -lc_p}"
-
- /* if debugging, tell the linker to output amiga-hunk symbols *and* a BSD
- compatible debug hunk (which will probably change in the future, it's not
- tremendously useful in its current state). */
-
- #define LINK_SPEC "%{g:-amiga-debug-hunk} %{fbaserel:-databss-together} %{resident:-databss-together -datadata-reloc -f libb} "
-
- #define CC1_SPEC "%{resident:-fbaserel} "
-
- #define CC1PLUS_SPEC "%{resident:-fbaserel} "
-
- /* Omit frame pointer at high optimization levels. (This doesn't hurt, since
- GDB doesn't work under AmigaDOS at the moment anyway..) */
-
- #define OPTIMIZATION_OPTIONS(OPTIMIZE) \
- { \
- if (OPTIMIZE >= 2) \
- flag_omit_frame_pointer = 1; \
- }
-
- /* provide a dummy entry for the small-code switch. This is currently only
- needed by the assembler (explanations: m68k.h), but will be used by cc1
- to output 16bit pc-relative code later. */
-
- #undef TARGET_SWITCHES
- #define TARGET_SWITCHES \
- { { "68020", 5}, \
- { "c68020", 5}, \
- { "68881", 2}, \
- { "bitfield", 4}, \
- { "68000", -5}, \
- { "c68000", -5}, \
- { "soft-float", -0102}, \
- { "nobitfield", -4}, \
- { "rtd", 8}, \
- { "nortd", -8}, \
- { "short", 040}, \
- { "noshort", -040}, \
- { "fpa", 0100}, \
- { "nofpa", -0100}, \
- { "sky", 0200}, \
- { "nosky", -0200}, \
- { "68040", 0407}, \
- { "68030", -01400}, \
- { "68030", 7}, \
- { "68040-only", 01000}, \
- { "small-code", 0 }, \
- { "", TARGET_DEFAULT}}
-
- /* Every structure or union's size must be a multiple of 2 bytes. */
-
- #define STRUCTURE_SIZE_BOUNDARY 16
-
- /* This is (almost;-)) BSD, so it wants DBX format. */
-
- #define DBX_DEBUGGING_INFO
-
- /* Allow folding division by zero. */
- #define REAL_INFINITY
-
- #if 0 /* This apparently is no longer necessary? */
-
- /* This is how to output an assembler line defining a `double' constant. */
-
- #undef ASM_OUTPUT_DOUBLE
- #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
- { \
- if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.double 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
- { \
- union { double d; long l[2];} t; \
- t.d = (VALUE); \
- fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n", t.l[0], t.l[1]); \
- } \
- else \
- fprintf (FILE, "\t.double 0r%.17g\n", VALUE); \
- }
-
- /* This is how to output an assembler line defining a `float' constant. */
-
- #undef ASM_OUTPUT_FLOAT
- #define ASM_OUTPUT_FLOAT(FILE,VALUE) \
- { \
- if (REAL_VALUE_ISINF (VALUE)) \
- fprintf (FILE, "\t.single 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
- else if (isnan (VALUE)) \
- { \
- union { float f; long l;} t; \
- t.f = (VALUE); \
- fprintf (FILE, "\t.long 0x%lx\n", t.l); \
- } \
- else \
- fprintf (FILE, "\t.single 0r%.9g\n", VALUE); \
- }
-
- /* This is how to output an assembler lines defining floating operands.
- There's no way to output a NaN's fraction, so we lose it. */
-
- #undef ASM_OUTPUT_FLOAT_OPERAND
- #define ASM_OUTPUT_FLOAT_OPERAND(CODE,FILE,VALUE) \
- do { \
- if (CODE == 'f') \
- { \
- (REAL_VALUE_ISINF ((VALUE)) \
- ? asm_fprintf (FILE, "%I0r%s99e999", ((VALUE) > 0 ? "" : "-")) \
- : (VALUE) == -0.0 \
- ? asm_fprintf (FILE, "%I0r-0.0") \
- : asm_fprintf (FILE, "%I0r%.9g", (VALUE))) \
- } else { \
- long l; \
- REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
- if (sizeof (int) == sizeof (long)) \
- asm_fprintf ((FILE), "%I0x%x", l); \
- else \
- asm_fprintf ((FILE), "%I0x%lx", l); \
- } \
- } while (0)
-
- #undef ASM_OUTPUT_DOUBLE_OPERAND
- #define ASM_OUTPUT_DOUBLE_OPERAND(FILE,VALUE) \
- (REAL_VALUE_ISINF ((VALUE)) \
- ? asm_fprintf (FILE, "%I0r%s99e999", ((VALUE) > 0 ? "" : "-")) \
- : (VALUE) == -0.0 \
- ? asm_fprintf (FILE, "%I0r-0.0") \
- : asm_fprintf (FILE, "%I0r%.17g", (VALUE)))
-
- #endif /* 0 */
-
- /* use A5 as framepointer instead of A6, this makes A6 available as a
- general purpose register, and can thus be used without problems in
- direct library calls. */
-
- #undef FRAME_POINTER_REGNUM
- #define FRAME_POINTER_REGNUM 13
- #undef ARG_POINTER_REGNUM
- #define ARG_POINTER_REGNUM 13
-
- /* we use A4 for this, not A5, which is the framepointer */
- #undef PIC_OFFSET_TABLE_REGNUM
- #define PIC_OFFSET_TABLE_REGNUM 12
-
- /* setup a default shell return value for those (gazillion..) programs that
- (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus
- cause the shell to randomly caugh upon executing such programs (contrary
- to Unix, AmigaDOS scripts are terminated with an error if a program returns
- with an error code above the `error' or even `failure' level
- (which is configurable with the FAILAT command) */
-
- #define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-
- /* we do have an ansi-compliant c-library ;-) */
- #define HAVE_VPRINTF
- #define HAVE_VFPRINTF
- #define HAVE_PUTENV
- #define HAVE_STRERROR
- #define HAVE_ATEXIT
-
- /* given that symbolic_operand(X), return TRUE if no special
- base relative relocation is necessary */
-
- #define LEGITIMATE_BASEREL_OPERAND_P(X) \
- (flag_pic >= 3 && read_only_operand (X))
-
- #undef LEGITIMATE_PIC_OPERAND_P
- #define LEGITIMATE_PIC_OPERAND_P(X) \
- (! symbolic_operand (X, VOIDmode) || LEGITIMATE_BASEREL_OPERAND_P (X))
-
-
- /* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- The macro definition, if any, is executed immediately after the
- rtl for DECL or other node is created.
- The value of the rtl will be a `mem' whose address is a
- `symbol_ref'.
-
- The usual thing for this macro to do is to a flag in the
- `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
- name string in the `symbol_ref' (if one bit is not enough
- information).
-
- On the Amiga we use this to indicate if a symbol is in text or
- data space. */
-
- #define ENCODE_SECTION_INFO(DECL)\
- do \
- { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1; \
- else \
- { \
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \
- ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \
- if (RTX_UNCHANGING_P (rtl) && !MEM_VOLATILE_P (rtl)) \
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \
- } \
- } \
- while (0)
-
- #undef SELECT_RTX_SECTION
- #define SELECT_RTX_SECTION(MODE, X) readonly_data_section ();
-
- /* according to varasm.c, RELOC referrs *only* to whether constants (!)
- are addressed by address. This doesn't matter in baserelative code,
- so we allow (inspite of flag_pic) readonly_data_section() in that
- case */
-
- #undef SELECT_SECTION
- #define SELECT_SECTION(DECL, RELOC) \
- { \
- if (TREE_CODE (DECL) == STRING_CST) \
- { \
- if (! flag_writable_strings) \
- readonly_data_section (); \
- else \
- data_section (); \
- } \
- else if (TREE_CODE (DECL) == VAR_DECL) \
- { \
- if ((flag_pic && flag_pic < 3 && RELOC) \
- || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL)) \
- data_section (); \
- else \
- readonly_data_section (); \
- } \
- else \
- readonly_data_section (); \
- }
-
-
-
- #if not_yet_working
-
- /* starting support for amiga specific keywords
- * --------------------------------------------
- */
-
- /* validate attributes that don't take a parameter. Currently we support
- * __attribute__ (saveds) and __attribute__ (interrupt)
- */
- #define HANDLE_ATTRIBUTE0(attr) \
- (strcmp(attr, "saveds") != 0 && strcmp(attr, "interrupt") != 0)
-
- /* (c-common.c)
- * install additional attributes
- */
- #define HANDLE_EXTRA_ATTRIBUTES(a) \
- if (TREE_VALUE (a) != 0 \
- && TREE_CODE (TREE_VALUE (a)) == IDENTIFIER_NODE \
- && TREE_VALUE (a) == get_identifier ("saveds")) \
- { \
- if (TREE_CODE (decl) != FUNCTION_DECL) \
- { \
- warning_with_decl (decl, \
- "saveds attribute specified for non-function `%s'"); \
- return; \
- } \
- \
- attr_do_saveds (DECL_NAME (decl)); \
- } \
- else if (TREE_VALUE (a) != 0 \
- && TREE_CODE (TREE_VALUE (a)) == IDENTIFIER_NODE \
- && TREE_VALUE (a) == get_identifier ("interrupt")) \
- { \
- if (TREE_CODE (decl) != FUNCTION_DECL) \
- { \
- warning_with_decl (decl, \
- "saveds attribute specified for non-function `%s'"); \
- return; \
- } \
- \
- attr_do_interrupt (DECL_NAME (decl)); \
- } \
-
-
- #define PROLOGUE_EXTRA_SAVE(mask) \
- { extern char *current_function_name; \
- /* saveds makes the function preserve d1/a0/a1 as well */ \
- if (attr_does_saveds (current_function_name)) \
- mask |= 0x40c0; } \
-
-
- #define EPILOGUE_EXTRA_RESTORE(mask, nregs) \
- { extern char *current_function_name; \
- /* restore those extra registers */ \
- if (attr_does_saveds (current_function_name)) \
- { \
- mask |= 0x0302; \
- nregs += 3; \
- } } \
-
-
- #define EPILOGUE_EXTRA_BARRIER_KLUDGE(stream) \
- { extern char *current_function_name; \
- /* PLEASE Help! how is this done cleaner?? */ \
- if (attr_does_saveds (current_function_name)) \
- { \
- fprintf (stderr, \
- "warning: couldn't cleanup `saveds'-stack in `%s'.\n"); \
- fprintf (stderr, \
- " this is only ok, if the function never returns!\n"); \
- } } \
-
-
- #define EPILOGUE_EXTRA_TEST(stream) \
- { extern char *current_function_name; \
- /* with the interrupt-attribute, we have to set the cc before rts */ \
- if (attr_does_interrupt (current_function_name)) \
- asm_fprintf (stream, "\ttstl %s\n", reg_names[0]); } \
-
- #endif
-