From 2f3c76b3d7e4a4cc6878a8e989342de91b3fe842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krystian=20Bac=C5=82awski?= Date: Sun, 17 Apr 2016 15:04:47 +0200 Subject: [PATCH] AmigaOS/m68k specific changes. --- config.sub | 6 +- gcc/Makefile.in | 34 +- gcc/c-decl.c | 76 ++- gcc/c-parse.in | 100 ++-- gcc/c-tree.h | 3 +- gcc/calls.c | 8 + gcc/config/m68k/amigaos.c | 421 ++++++++++++++ gcc/config/m68k/amigaos.h | 637 +++++++++++++++++++++ gcc/config/m68k/m68k.c | 338 ++++++++++- gcc/config/m68k/m68k.h | 116 +++- gcc/config/m68k/m68k.md | 28 +- gcc/config/m68k/t-amigaos | 79 +++ gcc/config/m68k/x-amigaos | 77 +++ gcc/configure | 7 + gcc/configure.in | 13 +- gcc/cppinit.c | 1 + gcc/fixinc/mkfixinc.sh | 1 + gcc/flow.c | 8 +- gcc/function.c | 34 ++ gcc/function.h | 1 + gcc/gcc-amigaos.texi | 1133 +++++++++++++++++++++++++++++++++++++ gcc/genconfig.c | 4 +- gcc/ginclude/stdarg.h | 4 +- gcc/ginclude/stddef.h | 2 +- gcc/ginclude/varargs.h | 4 +- gcc/output.h | 2 + gcc/protoize.c | 1 + gcc/toplev.c | 4 + include/libiberty.h | 3 + include/objalloc.h | 2 + libiberty/argv.c | 3 +- libiberty/strerror.c | 10 +- libiberty/strsignal.c | 6 +- libio/fileops.c | 10 +- libio/genops.c | 17 +- libio/ioseekoff.c | 5 +- libio/ioseekpos.c | 7 +- libio/strops.c | 5 +- 38 files changed, 3080 insertions(+), 130 deletions(-) create mode 100644 gcc/config/m68k/amigaos.c create mode 100644 gcc/config/m68k/amigaos.h create mode 100644 gcc/config/m68k/t-amigaos create mode 100644 gcc/config/m68k/x-amigaos create mode 100644 gcc/gcc-amigaos.texi diff --git a/config.sub b/config.sub index 567459e..d30e4cd 100755 --- a/config.sub +++ b/config.sub @@ -277,14 +277,14 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; amigaos | amigados) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 85bf9f8..635f155 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -367,7 +367,7 @@ TARGET_LIBGCC2_CFLAGS = LIBGCC2_DEPS = # libgcc1-test target (must also be overridable for a target) -LIBGCC1_TEST = libgcc1-test +LIBGCC1_TEST = # List of extra executables that should be compiled for this target machine # that are used for compiling from source code to object code. @@ -393,6 +393,21 @@ EXTRA_GCC_OBJS =@host_extra_gcc_objs@ # Often this is edited directly by `configure'. EXTRA_HEADERS =@extra_headers_list@ +### begin-GG-local +# List of extra targets that should be executed by make when building +# the `doc' target. +EXTRA_DOC_TARGETS = +### end-GG-local + +### begin-GG-local +# List of extra targets that should be executed by make when building +# targets `stage1' to `stage4'. +EXTRA_STAGE1_TARGETS = +EXTRA_STAGE2_TARGETS = +EXTRA_STAGE3_TARGETS = +EXTRA_STAGE4_TARGETS = +### end-GG-local + # Set this to `collect2' to enable use of collect2. USE_COLLECT2 = @will_use_collect2@ # If we might be using collect2, then this variable will be set to @@ -516,6 +531,11 @@ CRT0STUFF_T_CFLAGS = # "t" or nothing, for building multilibbed versions of, say, crtbegin.o. T = +# Even if ALLOCA is set, don't use it if compiling with GCC, unless +# a configuration file overrides this default. +USE_ALLOCA= ` case "${CC}" in "${OLDCC}") echo "${ALLOCA}" ;; esac ` +USE_HOST_ALLOCA= ` case "${HOST_CC}"@"${HOST_ALLOCA}" in "${OLDCC}"@?*) echo ${HOST_PREFIX}${HOST_ALLOCA} ;; esac ` + # End of variables for you to override. # Definition of `all' is here so that new rules inserted by sed @@ -1359,7 +1379,7 @@ graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h $(RTL_H) \ hard-reg-set.h $(BASIC_BLOCK_H) sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H) -COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o +COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o $(EXTRA_COLLECT2_OBJS) collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) # Don't try modifying collect2 (aka ld) in place--it might be linking this. -rm -f collect2$(exeext) @@ -2265,7 +2285,7 @@ stmp-fixproto: fixhdr.ready fixproto stmp-headers # # Remake the info files. -doc: info +doc: info $(EXTRA_DOC_TARGETS) info: cpp.info gcc.info lang.info cpp.info: $(srcdir)/cpp.texi @@ -3049,7 +3069,7 @@ stage1-start: cp stage1/$${f} . ; \ else true; \ fi; done -stage1: force stage1-start lang.stage1 +stage1: force stage1-start lang.stage1 $(EXTRA_STAGE1_TARGETS) stage2-start: -if [ -d stage2 ] ; then true ; else mkdir stage2 ; fi @@ -3073,7 +3093,7 @@ stage2-start: cp stage2/$${f} . ; \ else true; \ fi; done -stage2: force stage2-start lang.stage2 +stage2: force stage2-start lang.stage2 $(EXTRA_STAGE2_TARGETS) stage3-start: -if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi @@ -3097,7 +3117,7 @@ stage3-start: cp stage3/$${f} . ; \ else true; \ fi; done -stage3: force stage3-start lang.stage3 +stage3: force stage3-start lang.stage3 $(EXTRA_STAGE3_TARGETS) stage4-start: -if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi @@ -3121,7 +3141,7 @@ stage4-start: cp stage4/$${f} . ; \ else true; \ fi; done -stage4: force stage4-start lang.stage4 +stage4: force stage4-start lang.stage4 $(EXTRA_STAGE4_TARGETS) # Copy just the executable files from a particular stage into a subdirectory, # and delete the object files. Use this if you're just verifying a version diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 6f8a900..01abe22 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -4227,8 +4227,9 @@ maybe_build_cleanup (decl) record the given order of parms in `parm_order'. */ void -push_parm_decl (parm) - tree parm; +/* Amiga: explicit register specification for parameters */ +push_parm_decl (parm, asmspec) + tree parm, asmspec; { tree decl; int old_immediate_size_expand = immediate_size_expand; @@ -4253,6 +4254,77 @@ push_parm_decl (parm) } #endif + /* Amiga: explicit register specification for parameters */ + if (asmspec) +#ifdef TARGET_AMIGAOS + { + char *regname=TREE_STRING_POINTER(asmspec); + int regnum; + if ((regnum=decode_reg_name(regname))>=0) + { + tree type=TREE_TYPE(decl); + if (HARD_REGNO_MODE_OK(regnum, TYPE_MODE(type))) + { + tree t, attrs; + push_obstacks_nochange(); + end_temporary_allocation(); + /* Build tree for __attribute__ ((asm(regnum))). */ +#if 0 + /* This doesn't work well because of a bug in + attribute_list_contained(), which passes list of arguments to + simple_cst_equal() instead of passing every argument + separately. */ + attrs=tree_cons(get_identifier("asm"), tree_cons(NULL_TREE, + build_int_2_wide(regnum, 0), NULL_TREE), NULL_TREE); +#else + attrs=tree_cons(get_identifier("asm"), + build_int_2_wide(regnum, 0), NULL_TREE); +#endif +#if 0 + /* build_type_attribute_variant() would seem to be more + appropriate here. However, that function does not support + attributes for parameters properly. It modifies + TYPE_MAIN_VARIANT of a new type. As a result, comptypes() + thinks that types of parameters in prototype and definition + are different and issues error messages. See also comment + below. */ + type=build_type_attribute_variant(type, attrs); +#else + /* First check whether such a type already exists - if yes, use + that one. This is very important, since otherwise + common_type() would think that it sees two different + types and would try to merge them - this could result in + warning messages. */ + for (t=TYPE_MAIN_VARIANT(type); t; t=TYPE_NEXT_VARIANT(t)) + if (comptypes(t, type)==1 + && attribute_list_equal(TYPE_ATTRIBUTES(t), attrs)) + break; + if (t) + type=t; + else + { + /* Create a new variant, with differing attributes. + (Hack! Type with differing attributes should no longer be + a variant of its main type. See comment above for + explanation why this was necessary). */ + type=build_type_copy(type); + TYPE_ATTRIBUTES(type)=attrs; + } +#endif + TREE_TYPE(decl)=type; + pop_obstacks(); + } + else + error_with_decl(decl, + "register number for `%s' isn't suitable for the data type"); + } + else + error("invalid register name `%s'", regname); + } +#else /* !TARGET_AMIGAOS */ + error("explicit register specification for parameters is not supported for this target"); +#endif /* !TARGET_AMIGAOS */ + decl = pushdecl (decl); immediate_size_expand = old_immediate_size_expand; diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 6757c4d..f39aa50 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -2329,56 +2329,63 @@ parmlist_2: /* empty */ parms: parm - { push_parm_decl ($1); } +/* begin-GG-local: explicit register specification for parameters */ + { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); } | parms ',' parm - { push_parm_decl ($3); } + { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); } ; /* A single parameter declaration or parameter type name, as found in a parmlist. */ parm: - typed_declspecs setspecs parm_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - build_tree_list (prefix_attributes, - $4)); + typed_declspecs setspecs parm_declarator maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $3), + build_tree_list (prefix_attributes, + $5)), $4); current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } - | typed_declspecs setspecs notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - build_tree_list (prefix_attributes, - $4)); + | typed_declspecs setspecs notype_declarator maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $3), + build_tree_list (prefix_attributes, + $5)), $4); current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } - | typed_declspecs setspecs absdcl maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - build_tree_list (prefix_attributes, - $4)); + | typed_declspecs setspecs absdcl maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $3), + build_tree_list (prefix_attributes, + $5)), $4); current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } - | declmods setspecs notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - build_tree_list (prefix_attributes, - $4)); + | declmods setspecs notype_declarator maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $3), + build_tree_list (prefix_attributes, + $5)), $4); current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); resume_momentary ($2); } - | declmods setspecs absdcl maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - build_tree_list (prefix_attributes, - $4)); + | declmods setspecs absdcl maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $3), + build_tree_list (prefix_attributes, + $5)), $4); +/* end-GG-local */ current_declspecs = TREE_VALUE (declspec_stack); prefix_attributes = TREE_PURPOSE (declspec_stack); declspec_stack = TREE_CHAIN (declspec_stack); @@ -2871,30 +2878,35 @@ mydecl: myparms: myparm - { push_parm_decl ($1); } +/* begin-GG-local: explicit register specification for parameters */ + { push_parm_decl (TREE_PURPOSE($1), TREE_VALUE($1)); } | myparms ',' myparm - { push_parm_decl ($3); } + { push_parm_decl (TREE_PURPOSE($3), TREE_VALUE($3)); } ; /* A single parameter declaration or parameter type name, - as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */ + as found in a parmlist. DOES NOT ALLOW AN INITIALIZER */ myparm: - parm_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, + parm_declarator maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, $1), - build_tree_list (prefix_attributes, - $2)); } - | notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - build_tree_list (prefix_attributes, - $2)); } - | absdcl maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - build_tree_list (prefix_attributes, - $2)); } + build_tree_list (prefix_attributes, + $3)), $2); } + | notype_declarator maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $1), + build_tree_list (prefix_attributes, + $3)), $2); } + | absdcl maybeasm maybe_attribute + { $$ = build_tree_list ( + build_tree_list (build_tree_list (current_declspecs, + $1), + build_tree_list (prefix_attributes, + $3)), $2); } +/* end-GG-local */ ; optparmlist: diff --git a/gcc/c-tree.h b/gcc/c-tree.h index bcf325b..753a6ce 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -331,7 +331,8 @@ extern void print_lang_identifier PROTO((FILE *, tree, int)); extern void print_lang_type PROTO((FILE *, tree, int)); extern void push_c_function_context PROTO((void)); extern void push_label_level PROTO((void)); -extern void push_parm_decl PROTO((tree)); +/* Amiga: explicit register specification for parameters */ +extern void push_parm_decl PROTO((tree, tree)); extern tree pushdecl PROTO((tree)); extern tree pushdecl_top_level PROTO((tree)); extern void pushlevel PROTO((int)); diff --git a/gcc/calls.c b/gcc/calls.c index bb7595a..11f4a72 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2613,6 +2613,10 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, fun = orgfun; +#ifdef LIBCALL_ENCODE_SECTION_INFO + LIBCALL_ENCODE_SECTION_INFO (fun); +#endif + /* Copy all the libcall-arguments out of the varargs data and into a vector ARGVEC. @@ -3113,6 +3117,10 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, is_const = no_queue; fun = orgfun; +#ifdef LIBCALL_ENCODE_SECTION_INFO + LIBCALL_ENCODE_SECTION_INFO (fun); +#endif + /* If this kind of value comes back in memory, decide where in memory it should come back. */ if (aggregate_value_p (type_for_mode (outmode, 0))) diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c new file mode 100644 index 0000000..cc92fc5 --- /dev/null +++ b/gcc/config/m68k/amigaos.c @@ -0,0 +1,421 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 93-96, 1997 Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + Heavily modified by Kamil Iskra (iskra@student.uci.agh.edu.pl). + +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, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "rtl.h" +#include "output.h" +#include "tree.h" +#include "flags.h" +#include "expr.h" + +/* Baserel support. */ + +/* Does operand (which is a symbolic_operand) live in text space? If + so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. + + This function is used in base relative code generation. */ + +int +read_only_operand (operand) + rtx operand; +{ + if (GET_CODE (operand) == CONST) + operand = XEXP (XEXP (operand, 0), 0); + if (GET_CODE (operand) == SYMBOL_REF) + return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand); + return 1; +} + +/* This function is used while generating a base relative code. + It returns 1 if a decl is not relocatable, i. e., if it can be put + in the text section. + Currently, it's very primitive: it just checks if the object size + is less than 4 bytes (i. e., if it can hold a pointer). It also + supports arrays and floating point types. */ + +int +amigaos_put_in_text (decl) + tree decl; +{ + tree type = TREE_TYPE (decl); + if (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + return (TREE_INT_CST_HIGH (TYPE_SIZE (type)) == 0 + && TREE_INT_CST_LOW (TYPE_SIZE (type)) < 32) + || FLOAT_TYPE_P (type); +} + +/* Common routine used to check if a4 should be preserved/restored. */ + +int +amigaos_restore_a4 () +{ + return (flag_pic >= 3 && + (TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4 + || lookup_attribute ("saveds", + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))); +} + +void +amigaos_alternate_pic_setup (stream) + FILE *stream; +{ + if (TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4) + asm_fprintf (stream, "\tjbsr %U__restore_a4\n"); + else if (lookup_attribute ("saveds", + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + asm_fprintf (stream, "\tlea %U__a4_init,%Ra4\n"); +} + +/* Attributes support. */ + +#define AMIGA_CHIP_SECTION_NAME ".datachip" + +/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine + specific attribute for DECL. The attributes in ATTRIBUTES have previously + been assigned to DECL. */ + +int +valid_amigaos_decl_attribute (decl, identifier) + tree decl, identifier; +{ + if (TREE_CODE (decl) == VAR_DECL) + if (is_attribute_p ("chip", identifier)) +#ifdef ASM_OUTPUT_SECTION_NAME + { + if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl)) + error ("`chip' attribute cannot be specified for local variables"); + else + { + /* The decl may have already been given a section attribute from + a previous declaration. Ensure they match. */ + if (DECL_SECTION_NAME (decl) == NULL_TREE) + DECL_SECTION_NAME (decl) = + build_string (strlen (AMIGA_CHIP_SECTION_NAME) + 1, + AMIGA_CHIP_SECTION_NAME); + else if (strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + AMIGA_CHIP_SECTION_NAME) != 0) + { + error_with_decl (decl, + "`chip' for `%s' conflicts with previous declaration"); + return 0; + } + return 1; + } + } +#else + error ("`chip' attribute is not supported for this target"); +#endif + + return 0; +} + +/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine + specific attribute for TYPE. The attributes in ATTRIBUTES have previously + been assigned to TYPE. */ + +int +valid_amigaos_type_attribute (type, attributes, identifier, args) + tree type, attributes, identifier, args; +{ + if (valid_m68k_type_attribute (type, attributes, identifier, args)) + return 1; + else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) + { + if (is_attribute_p ("stackext", identifier)) + { + if (lookup_attribute ("interrupt", attributes) || + lookup_attribute ("interrupt_handler", attributes)) + { + error ("`stackext' and `interrupt' are mutually exclusive"); + return 0; + } + return 1; + } + if (is_attribute_p ("interrupt", identifier) || + is_attribute_p ("interrupt_handler", identifier)) + { + if (lookup_attribute ("stackext", attributes)) + { + error ("`stackext' and `interrupt' are mutually exclusive"); + return 0; + } + return 1; + } + if (is_attribute_p ("saveds", identifier)) + return 1; + } + + return 0; +} + +/* Stack checking and automatic extension support. */ + +void +amigaos_prologue_begin_hook (stream, fsize) + FILE *stream; + int fsize; +{ + if (TARGET_STACKCHECK) + { + if (fsize < 256) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tjra %U__stkovf\n" + "\t0:\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit"))); + else if (fsize < 0x8000) + asm_fprintf (stream, "\tmovel #%d:W,%Rd0\n\tjbsr %U__stkchk_d0\n", + fsize); + else + asm_fprintf (stream, "\tmovel #%d,%Rd0\n\tjbsr %U__stkchk_d0\n", + fsize); + } +} + +void +amigaos_alternate_frame_setup_f (stream, fsize) + FILE *stream; + int fsize; +{ + if (fsize < 128) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq #%d,%Rd0\n" + "\tmoveq #0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\tlink %Ra5,#%d:W\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit")), + fsize, -fsize); + else if (fsize < 0x8000) + asm_fprintf (stream, "\tmovel #%d:W,%Rd0\n\tjbsr %U__link_a5_d0_f\n", + fsize); + else + asm_fprintf (stream, "\tmovel #%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n", + fsize); +} + +void +amigaos_alternate_frame_setup (stream, fsize) + FILE *stream; + int fsize; +{ + if (! fsize) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq #0,%Rd0\n" + "\tmoveq #0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit"))); + else if (fsize + 4 < 128) + asm_fprintf (stream, "\tcmpl %s,%Rsp\n" + "\tjcc 0f\n" + "\tmoveq #%d,%Rd0\n" + "\tmoveq #0,%Rd1\n" + "\tjbsr %U__stkext_f\n" + "0:\taddw #%d,%Rsp\n", + (flag_pic == 3 ? "a4@(___stk_limit:W)" : + (flag_pic == 4 ? "a4@(___stk_limit:L)" : + "___stk_limit")), + fsize + 4, -(fsize + 4)); + else if (fsize + 4 < 0x8000) + asm_fprintf (stream, "\tmovel #%d:W,%Rd0\n\tjbsr %U__sub_d0_sp_f\n", + fsize + 4); + else + asm_fprintf (stream, "\tmovel %0I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n", + fsize + 4); +} + +static rtx +gen_stack_management_call (stack_pointer, arg, func) + rtx stack_pointer; + rtx arg; + char *func; +{ + rtx call_insn, call, seq, name; + start_sequence (); + + /* Move arg to d0. */ + emit_move_insn (gen_rtx (REG, SImode, 0), arg); + + /* Generate the function reference. */ + name = gen_rtx (SYMBOL_REF, Pmode, func); + SYMBOL_REF_FLAG (name) = 1; + /* If optimizing, put it in a psedo so that several loads can be merged + into one. */ + if (optimize && ! flag_no_function_cse) + name = copy_to_reg (name); + + /* Generate the function call. */ + call = gen_rtx (CALL, VOIDmode, gen_rtx (MEM, FUNCTION_MODE, name), + const0_rtx); + /* If we are doing stack extension, notify about the sp change. */ + if (stack_pointer) + call = gen_rtx (SET, VOIDmode, stack_pointer, call); + + /* Generate the call instruction. */ + call_insn = emit_call_insn (call); + /* Stack extension does not change memory in an unpredictable way. */ + CONST_CALL_P (call_insn) = 1; + /* We pass an argument in d0. */ + CALL_INSN_FUNCTION_USAGE (call_insn) = gen_rtx (EXPR_LIST, VOIDmode, + gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 0)), 0); + + seq = gen_sequence (); + end_sequence (); + return seq; +} + +rtx +gen_stack_cleanup_call (stack_pointer, sa) + rtx stack_pointer; + rtx sa; +{ + return gen_stack_management_call (stack_pointer, sa, "__move_d0_sp"); +} + +void +amigaos_alternate_allocate_stack (operands) + rtx *operands; +{ + if (TARGET_STACKEXTEND) + emit_insn ((rtx)gen_stack_management_call (stack_pointer_rtx, operands[1], + "__sub_d0_sp")); + else + { + if (TARGET_STACKCHECK) + emit_insn ((rtx)gen_stack_management_call (0, operands[1], + "__stkchk_d0")); + anti_adjust_stack (operands[1]); + } + emit_move_insn (operands[0], virtual_stack_dynamic_rtx); +} + +/* begin-GG-local: explicit register specification for parameters */ + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +void +amigaos_init_cumulative_args(CUMULATIVE_ARGS *cum, tree fntype) +{ + m68k_init_cumulative_args(cum, fntype); + + if (fntype) + cum->formal_type=TYPE_ARG_TYPES(fntype); + else /* Call to compiler-support function. */ + cum->formal_type=0; +} + +/* Update the data in CUM to advance over an argument. */ + +void +amigaos_function_arg_advance(CUMULATIVE_ARGS *cum) +{ + m68k_function_arg_advance(cum); + + if (cum->formal_type) + cum->formal_type=TREE_CHAIN((tree)cum->formal_type); +} + +/* A C expression that controls whether a function argument is passed + in a register, and which register. */ + +struct rtx_def * +amigaos_function_arg(CUMULATIVE_ARGS *cum, enum machine_mode mode, + tree type) +{ + tree asmtree; + if (cum->formal_type && TREE_VALUE((tree)cum->formal_type) + && (asmtree=lookup_attribute("asm", + TYPE_ATTRIBUTES(TREE_VALUE((tree)cum->formal_type))))) + { + int i; +#if 0 + /* See c-decl.c/push_parm_decl for an explanation why this doesn't work. + */ + cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(TREE_VALUE(asmtree))); +#else + cum->last_arg_reg=TREE_INT_CST_LOW(TREE_VALUE(asmtree)); +#endif + cum->last_arg_len=HARD_REGNO_NREGS(cum->last_arg_reg, mode); + + for (i=0; ilast_arg_len; i++) + if (cum->regs_already_used & (1 << cum->last_arg_reg+i)) + { + error("two parameters allocated for one register"); + break; + } + return gen_rtx(REG, mode, cum->last_arg_reg); + } + else + return (struct rtx_def *)m68k_function_arg(cum, mode, type); +} + +/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible, + one if they are compatible, and two if they are nearly compatible + (which causes a warning to be generated). */ + +int +comp_amigaos_type_attributes(tree type1, tree type2) +{ + int ret; + if ((ret=comp_m68k_type_attributes(type1, type2))!=1) + return ret; + + /* Functions or methods are incompatible if they specify mutually exclusive + ways of passing arguments. */ + if (TREE_CODE(type1)==FUNCTION_TYPE || TREE_CODE(type1)==METHOD_TYPE) + { + tree arg1, arg2; + arg1=TYPE_ARG_TYPES(type1); + arg2=TYPE_ARG_TYPES(type2); + for (; arg1 && arg2; arg1=TREE_CHAIN(arg1), arg2=TREE_CHAIN(arg2)) + if (TREE_VALUE(arg1) && TREE_VALUE(arg2)) + { + tree asm1, asm2; + asm1=lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(arg1))); + asm2=lookup_attribute("asm", TYPE_ATTRIBUTES(TREE_VALUE(arg2))); + if (asm1 && asm2) + { + if (TREE_INT_CST_LOW(TREE_VALUE(asm1))!= + TREE_INT_CST_LOW(TREE_VALUE(asm2))) + return 0; /* Two different registers specified. */ + } + else + if (asm1 || asm2) + return 0; /* "asm" used in only one type. */ + } + } + return 1; +} + +/* end-GG-local */ diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h new file mode 100644 index 0000000..74388c5 --- /dev/null +++ b/gcc/config/m68k/amigaos.h @@ -0,0 +1,637 @@ +/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS. + Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. + Contributed by Markus M. Wild (wild@amiga.physik.unizh.ch). + Heavily modified by Kamil Iskra (iskra@student.uci.agh.edu.pl). + +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, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "m68k/m68k.h" + +/* begin-GG-local: explicit register specification for parameters */ +#define TARGET_AMIGAOS +/* end-GG-local */ + +/* Specs, switches. */ + +/* See m68k.h for bits in TARGET_DEFAULT. + 0 means 68000, no hardware fpu (68881/68882/68040/68060). */ + +#define TARGET_DEFAULT 0 + +/* 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 we compile for. + When creating shared libraries, use different 'errno'. */ + +/* -msoft-float is the default, assume -mc68000 as well */ +#define CPP_SPEC \ + "%{m68881:-D__HAVE_68881__} " \ + "%{!ansi:" \ + "%{m68020:-Dmc68020} " \ + "%{mc68020:-Dmc68020} " \ + "%{m68020-40:-Dmc68020} " \ + "%{m68020-60:-Dmc68020} " \ + "%{m68030:-Dmc68030} " \ + "%{m68040:-Dmc68040} " \ + "%{m68060:-Dmc68060} " \ + "%{!noixemul:-Dixemul} " \ + "%{noixemul:-Dlibnix}} " \ + "%{m68020:-D__mc68020__ -D__mc68020} " \ + "%{mc68020:-D__mc68020__ -D__mc68020} " \ + "%{m68020-40:-D__mc68020__ -D__mc68020} " \ + "%{m68020-60:-D__mc68020__ -D__mc68020} " \ + "%{m68030:-D__mc68030__ -D__mc68030} " \ + "%{m68040:-D__mc68040__ -D__mc68040} " \ + "%{m68060:-D__mc68060__ -D__mc68060} " \ + "%{!noixemul:-D__ixemul__ -D__ixemul} " \ + "%{noixemul:-D__libnix__ -D__libnix} " \ + "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \ + "%{mrestore-a4:-Derrno=(*ixemul_errno)} " + +/* Various -m flags require special flags to the assembler. */ + +#define ASM_SPEC "\ + %{m68000:-mc68010}\ + %{mc68000:-mc68010}\ + %{m68020:-mc68020}\ + %{mc68020:-mc68020}\ + %{m68030:-mc68030}\ + %{m68040:-mc68040}\ + %{m68060:-mc68060}\ + %{m68020-40:-mc68020}\ + %{m68020-60:-mc68020}\ + %{!mc68000:%{!m68000:%{!mc68020:%{!m68020:%{!m68030:%{!m68040:%{!m68060:%{!m68020-40:%{!m68020-60:-mc68010}}}}}}}}}\ + %{msmall-code:-sc}\ +" + +/* amiga/amigaos are the new "standard" defines for the Amiga. + * MCH_AMIGA, AMIGA, __chip etc. are used in other compilers and are + * provided for compatibility reasons. */ + +#define CPP_PREDEFINES "\ + -Dmc68000\ + -Damiga\ + -Damigaos\ + -DMCH_AMIGA\ + -DAMIGA\ + -D__chip=__attribute__((__chip__))\ + -D__saveds=__attribute__((__saveds__))\ + -D__interrupt=__attribute__((__interrupt__))\ + -D__interrupt_handler=__attribute__((__interrupt_handler__))\ + -D__stackext=__attribute__((__stackext__))\ + -D__regargs=__attribute__((__regparm__))\ + -D__stdargs=__attribute__((__stkparm__))\ + -D__aligned=__attribute__((__aligned__(4)))\ + -Asystem(amigaos)\ + -Acpu(m68k)\ + -Amachine(m68k)\ +" + +/* Choose the right startup file, depending on whether we use base relative + code, base relative code with automatic relocation (-resident), their + 32-bit versions, libnix, profiling or plain crt0.o. */ + +#define STARTFILE_SPEC \ + "%{!noixemul:" \ + "%{fbaserel:%{!resident:bcrt0.o%s}}" \ + "%{resident:rcrt0.o%s}" \ + "%{fbaserel32:%{!resident32:lcrt0.o%s}}" \ + "%{resident32:scrt0.o%s}" \ + "%{!resident:%{!fbaserel:%{!resident32:%{!fbaserel32:" \ + "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}}" \ + "%{noixemul:" \ + "%{ramiga-*:" \ + "%{ramiga-lib:libnix/libinit.o%s}" \ + "%{ramiga-libr:libnix/libinitr.o%s}" \ + "%{ramiga-dev:libnix/devinit.o%s}}" \ + "%{!ramiga-*:" \ + "%{resident:libnix/nrcrt0.o%s}" \ + "%{!resident:" \ + "%{fbaserel:libnix/nbcrt0.o%s}" \ + "%{!fbaserel:libnix/ncrt0.o%s}}}}" \ + +#define ENDFILE_SPEC "%{noixemul:-lstubs}" + +/* Automatically search libamiga.a for AmigaOS 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 libamiga.a for any calls + that were not generated inline, and finally 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. Note that + if we don't search it automatically, it is very easy for the user to try + to put in a -lamiga himself and get it in the wrong place, so that (for + example) calls like sprintf come from -lamiga rather than -lc. */ + +#define LIB_SPEC \ + "%{!noixemul:" \ + "%{!p:%{!pg:-lc -lamiga -lc}}" \ + "%{p:-lc_p}%{pg:-lc_p}}" \ + "%{noixemul:-lnixmain -lnix -lamiga " \ + "%{mstackcheck:-lstack} " \ + "%{mstackextend:-lstack}}" + +#define LIBGCC_SPEC \ + "-lgcc %{noixemul:-lnix}" + +/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD + compatible debug hunk. + Also, pass appropriate linker flavours depending on user-supplied + commandline options. */ + +#define LINK_SPEC \ + "%{noixemul:-fl libnix} " \ + "%{fbaserel:%{!resident:-m amiga_bss -fl libb}} " \ + "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb} " \ + "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32}} " \ + "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32} " \ + "%{g:-amiga-debug-hunk} " \ + "%{m68020:-fl libm020} " \ + "%{mc68020:-fl libm020} " \ + "%{m68030:-fl libm020} " \ + "%{m68040:-fl libm020} " \ + "%{m68060:-fl libm020} " \ + "%{m68020-40:-fl libm020} " \ + "%{m68020-60:-fl libm020} " \ + "%{m68881:-fl libm881} " + +/* Translate '-resident' to '-fbaserel' (they differ in linking stage only). + Don't put function addresses in registers for PC-relative code. */ + +#define CC1_SPEC \ + "%{resident:-fbaserel} " \ + "%{resident32:-fbaserel32} " \ + "%{msmall-code:-fno-function-cse} " + +/* A modified copy of LINK_COMMAND_SPEC from gcc/gcc.c file. If -noixemul + * option is enabled, don't prepend libgcc.a to link libraries and make sure + * the options is at the end of command line. Otherwise linker chooses main() + * function from libgcc.a instead from libnix.a. */ + +#define LINK_COMMAND_SPEC \ + "%{!fsyntax-only: " \ + "%{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} " \ + "%{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \ + "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \ + "%{static:} %{L*} %D %o " \ + "%{!nostdlib:%{!nodefaultlibs:%{!noixemul:%G} %L}} " \ + "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \ + "%{!nostdlib:%{!nodefaultlibs:%G}} " \ + "%{T*} }}}}}} " + +/* Compile with stack extension. */ + +#define MASK_STACKEXTEND 0x40000000 +#define TARGET_STACKEXTEND (((target_flags & MASK_STACKEXTEND) \ + && !lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \ + && !lookup_attribute ("interrupt_handler", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \ + || lookup_attribute ("stackext", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + +/* Compile with stack checking. */ + +#define MASK_STACKCHECK 0x20000000 +#define TARGET_STACKCHECK ((target_flags & MASK_STACKCHECK) \ + && !(target_flags & MASK_STACKEXTEND) \ + && !lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \ + && !lookup_attribute ("interrupt_handler", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \ + && !lookup_attribute ("stackext", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + +/* Compile with a4 restoring in public functions. */ + +#define MASK_RESTORE_A4 0x10000000 +#define TARGET_RESTORE_A4 \ + ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl)) + +/* Compile with a4 restoring in all functions. */ + +#define MASK_ALWAYS_RESTORE_A4 0x8000000 +#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4) + +/* Provide a dummy entry for the '-msmall-code' switch. This is used by + the assembler and '*_SPEC'. */ + +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + { "small-code", 0}, \ + { "stackcheck", MASK_STACKCHECK}, \ + { "no-stackcheck", - MASK_STACKCHECK}, \ + { "stackextend", MASK_STACKEXTEND}, \ + { "no-stackextend", - MASK_STACKEXTEND}, \ + { "fixedstack", - (MASK_STACKCHECK|MASK_STACKEXTEND)}, \ + { "restore-a4", MASK_RESTORE_A4}, \ + { "no-restore-a4", - MASK_RESTORE_A4}, \ + { "always-restore-a4", MASK_ALWAYS_RESTORE_A4}, \ + { "no-always-restore-a4", - MASK_ALWAYS_RESTORE_A4}, + +#undef SUBTARGET_OVERRIDE_OPTIONS +#define SUBTARGET_OVERRIDE_OPTIONS \ +do \ + { \ + if (!TARGET_68020 && flag_pic==4) \ + error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \ + } \ +while (0) + +/* Various ABI issues. */ + +/* This is (almost;-) BSD, so it wants DBX format. */ + +#define DBX_DEBUGGING_INFO + +/* GDB goes mad if it sees the function end marker. */ + +#define NO_DBX_FUNCTION_END 1 + +/* Allow folding division by zero. */ + +#define REAL_INFINITY + +/* 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 + +/* Use A5 as framepointer instead of A6, since the AmigaOS ABI requires A6 + to be used as a shared library base pointer 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 the PIC pointer, not A5, which is the framepointer. */ + +#undef PIC_OFFSET_TABLE_REGNUM +#define PIC_OFFSET_TABLE_REGNUM 12 + +/* The AmigaOS ABI does not define how structures should be returned, so, + contrary to 'm68k.h', we prefer a multithread-safe solution. */ + +#undef PCC_STATIC_STRUCT_RETURN + +/* 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, AmigaOS 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) + +#undef WCHAR_TYPE +#define WCHAR_TYPE "unsigned int" + +/* Support sections in chip memory, currently '.datachip' only. */ +#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ + fprintf ((FILE), "\t%s\n", (NAME)) + +/* We define ASM_OUTPUT_SECTON_NAME, but we don't support arbitrary sections, + including '.gcc_except_table', so we emulate the standard behaviour. */ +#define EXCEPTION_SECTION() \ +do \ + { \ + if (flag_pic) \ + data_section (); \ + else \ + readonly_data_section (); \ + } \ +while(0) + +#define EH_FRAME_SECTION() readonly_data_section () + +/* Use sjlj exceptions until problems with DWARF2 unwind info on a.out + targets using GNU ld are fixed. */ +#define DWARF2_UNWIND_INFO 0 + +/* GAS supports alignment up to 32768 bytes. */ +#undef ASM_OUTPUT_ALIGN +#define ASM_OUTPUT_ALIGN(FILE, LOG) \ +do \ + { \ + if ((LOG) == 1) \ + fprintf ((FILE), "\t.even\n"); \ + else \ + fprintf ((FILE), "\t.align %d\n", (LOG)); \ + } \ +while (0) + +#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT) + +/* It is not uncommon to use a custom startup code on AmigaOS. The OS + starts an application by jumping to the first byte of the text section, + so we prefer the constants to be put after the functions. */ +/* FIXME: Disabled for now, it's buggy. */ + +/* #define CONSTANT_AFTER_FUNCTION_P(EXP) 1 */ /**/ + +/* Call __flush_cache() after building the trampoline: it will call + an appropriate OS cache-clearing routine. */ + +#undef FINALIZE_TRAMPOLINE +#define FINALIZE_TRAMPOLINE(TRAMP) \ + emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__flush_cache"), \ + 0, VOIDmode, 2, (TRAMP), Pmode, \ + GEN_INT (TRAMPOLINE_SIZE), SImode) + +/* Baserel support. */ + +/* 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 references to a symbol should be + absolute or base relative. */ + +#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) \ + && (flag_pic<3 || (TREE_CODE (DECL) == STRING_CST \ + && !flag_writable_strings) \ + || amigaos_put_in_text (DECL))) \ + || (TREE_CODE (DECL) == VAR_DECL \ + && DECL_SECTION_NAME (DECL) != NULL_TREE)) \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \ + } \ + } \ +while (0) + +#define LIBCALL_ENCODE_SECTION_INFO(FUN) \ +do \ + { \ + if (flag_pic >= 3) \ + SYMBOL_REF_FLAG (FUN) = 1; \ + } \ +while (0) + +/* according to varasm.c, RELOC referrs *only* to whether constants (!) + are addressed by address. */ + +#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 (TREE_READONLY (DECL) \ + && ! TREE_THIS_VOLATILE (DECL) \ + && DECL_INITIAL (DECL) \ + && (DECL_INITIAL (DECL) == error_mark_node \ + || TREE_CONSTANT (DECL_INITIAL (DECL))) \ + && (!flag_pic || (flag_pic<3 && !RELOC) \ + || SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)))) \ + readonly_data_section (); \ + else \ + data_section (); \ + } \ + else if ((!flag_pic || (flag_pic<3 && !RELOC)) \ + && SYMBOL_REF_FLAG (XEXP ((TREE_CODE_CLASS (TREE_CODE (DECL))\ + != 'd' ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)), 0))) \ + readonly_data_section (); \ + else \ + data_section (); \ +} + +/* Preserve the initial value of a4. */ + +#define PROLOGUE_EXTRA_SAVE(MASK, NUM_SAVED_REGS) \ +do \ + { \ + if (amigaos_restore_a4 ()) \ + { \ + (MASK) |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM); \ + (NUM_SAVED_REGS)++; \ + } \ + } \ +while (0) + +/* Restore the initial value of a4. */ + +#define EPILOGUE_EXTRA_RESTORE(MASK, NREGS) \ +do \ + { \ + if (amigaos_restore_a4 ()) \ + { \ + (MASK) |= 1 << PIC_OFFSET_TABLE_REGNUM; \ + (NREGS)++; \ + } \ + } \ +while (0) + +#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3) + +/* Make a4 point at data hunk. */ + +void amigaos_alternate_pic_setup (); +#define ALTERNATE_PIC_SETUP(STREAM) \ + (amigaos_alternate_pic_setup (STREAM)) + +/* If preserving a4, let the code generator know about it. */ + +#undef SUBTARGET_INITIAL_FP_OFFSET +#define SUBTARGET_INITIAL_FP_OFFSET(OFFSET) \ +do \ + { \ + if (amigaos_restore_a4 ()) \ + (OFFSET) += 4; \ + } \ +while (0) + +/* Determine if the epilogue should be output as RTL. + Don't do it if preserving a4. */ + +#undef USE_RETURN_INSN +#define USE_RETURN_INSN (use_return_insn () && ! amigaos_restore_a4 ()) + +/* Attribute support. */ + +/* A C expression whose value is nonzero if IDENTIFIER with arguments + ARGS is a valid machine specific attribute for DECL. The attributes + in ATTRIBUTES have previously been assigned to DECL. */ + +#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \ + (valid_amigaos_decl_attribute ((DECL), (IDENTIFIER))) + +/* A C expression whose value is nonzero if IDENTIFIER with arguments + ARGS is a valid machine specific attribute for TYPE. The attributes + in ATTRIBUTES have previously been assigned to TYPE. */ + +#undef VALID_MACHINE_TYPE_ATTRIBUTE +#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \ + (valid_amigaos_type_attribute ((TYPE), (ATTRIBUTES), (IDENTIFIER), (ARGS))) + +/* Generate the test of d0 before return to set cc register in 'interrupt' + function. */ + +#define EPILOGUE_END_HOOK(STREAM) \ +do \ + { \ + if (lookup_attribute ("interrupt", \ + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \ + asm_fprintf ((STREAM), "\ttstl %Rd0\n"); \ + } \ +while (0) + +/* begin-GG-local: explicit register specification for parameters */ + +/* Note: this is an extension of m68k_args */ +struct amigaos_args +{ + int num_of_regs; + long regs_already_used; + int last_arg_reg; + int last_arg_len; + void *formal_type; /* New field: formal type of the current argument. */ +}; + +/* A C type for declaring a variable that is used as the first + argument of `FUNCTION_ARG' and other related values. */ + +#undef CUMULATIVE_ARGS +#define CUMULATIVE_ARGS struct amigaos_args + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +#undef INIT_CUMULATIVE_ARGS +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ + (amigaos_init_cumulative_args(&(CUM), (FNTYPE))) + +/* Update the data in CUM to advance over an argument + of mode MODE and data type TYPE. + (TYPE is null for libcalls where that information may not be available.) */ + +#undef FUNCTION_ARG_ADVANCE +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ + (amigaos_function_arg_advance (&(CUM))) + +/* A C expression that controls whether a function argument is passed + in a register, and which register. */ + +#undef FUNCTION_ARG +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ + ((struct rtx_def *)amigaos_function_arg (&(CUM), (MODE), (TYPE))) + +/* A C expression whose value is zero if the attributes on TYPE1 and + TYPE2 are incompatible, one if they are compatible, and two if they + are nearly compatible (which causes a warning to be generated). */ + +#undef COMP_TYPE_ATTRIBUTES +#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \ + (comp_amigaos_type_attributes ((TYPE1), (TYPE2))) + +/* end-GG-local */ + +/* Stack checking and automatic extension support. */ + +void amigaos_prologue_begin_hook (); +#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \ + (amigaos_prologue_begin_hook ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND + +void amigaos_alternate_frame_setup_f (); +#define ALTERNATE_FRAME_SETUP_F(STREAM, FSIZE) \ + (amigaos_alternate_frame_setup_f ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND + +void amigaos_alternate_frame_setup (); +#define ALTERNATE_FRAME_SETUP(STREAM, FSIZE) \ + (amigaos_alternate_frame_setup ((STREAM), (FSIZE))) + +#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \ + (TARGET_STACKEXTEND && current_function_calls_alloca) + +#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \ + (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n")) + +#define HAVE_ALTERNATE_RETURN \ + ((TARGET_STACKEXTEND && frame_pointer_needed && \ + current_function_calls_alloca) \ + || current_function_is_interrupt) + +#define ALTERNATE_RETURN(STREAM) \ +do \ + { \ + if (current_function_is_interrupt) \ + asm_fprintf ((STREAM), "\trte\n"); \ + } \ +while (0) + +struct rtx_def* gen_stack_cleanup_call (); +#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND +#define gen_restore_stack_nonlocal gen_stack_cleanup_call + +#define HAVE_restore_stack_function TARGET_STACKEXTEND +#define gen_restore_stack_function gen_stack_cleanup_call + +#define HAVE_restore_stack_block TARGET_STACKEXTEND +#define gen_restore_stack_block gen_stack_cleanup_call + +#undef TARGET_ALTERNATE_ALLOCATE_STACK +#define TARGET_ALTERNATE_ALLOCATE_STACK 1 + +#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \ +do \ + { \ + amigaos_alternate_allocate_stack (OPERANDS); \ + DONE; \ + } \ +while (0) diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 9567c9d..69d7752 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -63,6 +63,8 @@ const char *m68k_align_loops_string; const char *m68k_align_jumps_string; /* Specify power of two alignment used for functions. */ const char *m68k_align_funcs_string; +/* Specify number of registers for integer, pointer and float arguments. */ +const char *m68k_regparm_string; /* Specify power of two alignment used for loops. */ int m68k_align_loops; @@ -70,6 +72,8 @@ int m68k_align_loops; int m68k_align_jumps; /* Specify power of two alignment used for functions. */ int m68k_align_funcs; +/* Specify number of registers for integer, pointer and float arguments. */ +int m68k_regparm; /* Nonzero if the last compare/test insn had FP operands. The sCC expanders peek at this to determine what to do for the @@ -124,6 +128,19 @@ override_options () } else m68k_align_funcs = def_align; + + /* Validate -mregparm and -mregparm= value. */ + if (m68k_regparm_string) + { + m68k_regparm = atoi (m68k_regparm_string); + if (m68k_regparm < 1 || m68k_regparm > M68K_MAX_REGPARM) + fatal ("-mregparm=%d is not between 1 and %d", + m68k_regparm, M68K_MAX_REGPARM); + target_flags |= MASK_REGPARM; + } + else + if (TARGET_REGPARM) + m68k_regparm = M68K_DEFAULT_REGPARM; } /* This function generates the assembly code for function entry. @@ -151,9 +168,17 @@ output_function_prologue (stream, size) int fsize = (size + 3) & -4; int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset; +#ifdef PROLOGUE_BEGIN_HOOK + PROLOGUE_BEGIN_HOOK (stream, fsize); +#endif if (frame_pointer_needed) { +#ifdef HAVE_ALTERNATE_FRAME_SETUP_F + if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize)) + ALTERNATE_FRAME_SETUP_F (stream, fsize); + else +#endif if (fsize == 0 && TARGET_68040) { /* on the 68040, pea + move is faster than link.w 0 */ @@ -209,6 +234,10 @@ output_function_prologue (stream, size) cfa_store_offset += fsize; } } +#ifdef HAVE_ALTERNATE_FRAME_SETUP + else if (HAVE_ALTERNATE_FRAME_SETUP (fsize)) + ALTERNATE_FRAME_SETUP (stream, fsize); +#endif else if (fsize) { if (fsize + 4 < 0x8000) @@ -313,7 +342,8 @@ output_function_prologue (stream, size) if (TARGET_68881) { for (regno = 16; regno < 24; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) + if (regs_ever_live[regno] && (! call_used_regs[regno] + || current_function_is_interrupt)) { mask |= 1 << (regno - 16); num_saved_regs++; @@ -346,7 +376,8 @@ output_function_prologue (stream, size) num_saved_regs = 0; } for (regno = 0; regno < 16; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) + if (regs_ever_live[regno] && (! call_used_regs[regno] + || current_function_is_interrupt)) { mask |= 1 << (15 - regno); num_saved_regs++; @@ -356,11 +387,14 @@ output_function_prologue (stream, size) mask &= ~ (1 << (15 - FRAME_POINTER_REGNUM)); num_saved_regs--; } - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) + if (flag_pic && flag_pic < 3 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) { mask |= 1 << (15 - PIC_OFFSET_TABLE_REGNUM); num_saved_regs++; } +#ifdef PROLOGUE_EXTRA_SAVE + PROLOGUE_EXTRA_SAVE (mask, num_saved_regs); +#endif #if NEED_PROBE #ifdef MOTOROLA @@ -462,6 +496,11 @@ output_function_prologue (stream, size) -cfa_store_offset + n_regs++ * 4); } } +#ifdef HAVE_ALTERNATE_PIC_SETUP + if (HAVE_ALTERNATE_PIC_SETUP) + ALTERNATE_PIC_SETUP (stream); + else +#endif if (flag_pic && current_function_uses_pic_offset_table) { #ifdef MOTOROLA @@ -491,7 +530,8 @@ use_return_insn () separate layout routine to perform the common work. */ for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) + if (regs_ever_live[regno] && (! call_used_regs[regno] + || current_function_is_interrupt)) return 0; return 1; @@ -552,7 +592,8 @@ output_function_epilogue (stream, size) if (TARGET_68881) { for (regno = 16; regno < 24; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) + if (regs_ever_live[regno] && (! call_used_regs[regno] + || current_function_is_interrupt)) { nregs++; fmask |= 1 << (23 - regno); @@ -563,16 +604,20 @@ output_function_epilogue (stream, size) if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; for (regno = 0; regno < 16; regno++) - if (regs_ever_live[regno] && ! call_used_regs[regno]) + if (regs_ever_live[regno] && (! call_used_regs[regno] + || current_function_is_interrupt)) { nregs++; mask |= 1 << regno; } - if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) + if (flag_pic && flag_pic < 3 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) { nregs++; mask |= 1 << PIC_OFFSET_TABLE_REGNUM; } +#ifdef EPILOGUE_EXTRA_RESTORE + EPILOGUE_EXTRA_RESTORE (mask, nregs); +#endif offset = foffset + nregs * 4; /* FIXME : leaf_function_p below is too strong. What we really need to know there is if there could be pending @@ -759,6 +804,11 @@ output_function_epilogue (stream, size) fpoffset -= 8; } if (frame_pointer_needed) +#ifdef HAVE_ALTERNATE_FRAME_DESTR_F + if (HAVE_ALTERNATE_FRAME_DESTR_F (fsize)) + ALTERNATE_FRAME_DESTR_F (stream, fsize); + else +#endif fprintf (stream, "\tunlk %s\n", reg_names[FRAME_POINTER_REGNUM]); else if (fsize) @@ -828,9 +878,19 @@ output_function_epilogue (stream, size) #endif } } + +#ifdef EPILOGUE_END_HOOK + EPILOGUE_END_HOOK (stream); +#endif + if (current_function_pops_args) asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args); else +#ifdef HAVE_ALTERNATE_RETURN + if (HAVE_ALTERNATE_RETURN) + ALTERNATE_RETURN (stream); + else +#endif fprintf (stream, "\trts\n"); } @@ -1327,12 +1387,20 @@ legitimize_pic_address (orig, mode, reg) /* First handle a simple SYMBOL_REF or LABEL_REF */ if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF) { +#ifdef LEGITIMATE_BASEREL_OPERAND_P + if (LEGITIMATE_BASEREL_OPERAND_P (orig)) + return orig; +#endif + if (reg == 0) abort (); - pic_ref = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - pic_offset_table_rtx, orig)); + if (flag_pic < 3) + pic_ref = gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, + pic_offset_table_rtx, orig)); + else + pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, orig); current_function_uses_pic_offset_table = 1; if (reload_in_progress) regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1; @@ -3104,6 +3172,10 @@ print_operand_address (file, addr) fprintf (file, ":w"); if ((flag_pic == 2) && (breg == pic_offset_table_rtx)) fprintf (file, ":l"); + if ((flag_pic == 3) && (breg == pic_offset_table_rtx)) + fprintf (file, ":W"); + if ((flag_pic == 4) && (breg == pic_offset_table_rtx)) + fprintf (file, ":L"); } if (addr != 0 && ireg != 0) { @@ -3279,6 +3351,252 @@ const_sint32_operand (op, mode) return (GET_CODE (op) == CONST_INT && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff)); } + +/* Argument-passing support functions. */ + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +void +m68k_init_cumulative_args (cum, fntype) + CUMULATIVE_ARGS *cum; + tree fntype; +{ + cum->last_arg_reg = -1; + cum->regs_already_used = 0; + if (fntype) + { + if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES (fntype))) + cum->num_of_regs = 0; + else + { + tree ratree = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype)); + if (ratree) + { + cum->num_of_regs = m68k_regparm ? m68k_regparm + : M68K_DEFAULT_REGPARM; + if (TREE_VALUE (ratree) + && TREE_CODE (TREE_VALUE (ratree)) == TREE_LIST) + { + tree num_of_regs = TREE_VALUE (TREE_VALUE (ratree)); + cum->num_of_regs = + num_of_regs ? TREE_INT_CST_LOW (num_of_regs) : + (m68k_regparm ? m68k_regparm : M68K_DEFAULT_REGPARM); + } + } + else + cum->num_of_regs = m68k_regparm; + } + } + else /* Libcall. */ + cum->num_of_regs = 0; + + if (cum->num_of_regs) + { + /* If this is a vararg call, put all arguments on stack. */ + tree param, next_param; + for (param = TYPE_ARG_TYPES (fntype); param; param = next_param) + { + next_param = TREE_CHAIN (param); + if (!next_param && TREE_VALUE (param) != void_type_node) + cum->num_of_regs = 0; + } + } + +#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (STRUCT_VALUE_REGNUM) + /* If return value is a structure, and we pass the buffer address in a + register, we can't use this register for our own purposes. + FIXME: Something similar would be useful for static chain. */ + if (fntype && aggregate_value_p (TREE_TYPE (fntype))) + cum->regs_already_used |= (1 << STRUCT_VALUE_REGNUM); +#endif +} + +/* Update the data in CUM to advance over an argument. */ + +void +m68k_function_arg_advance (cum) + CUMULATIVE_ARGS *cum; +{ + if (cum->last_arg_reg != -1) + { + int count; + for (count = 0; count < cum->last_arg_len; count++) + cum->regs_already_used |= (1 << (cum->last_arg_reg + count)); + cum->last_arg_reg = -1; + } +} + +/* Define where to put the arguments to a function. + Value is zero to push the argument on the stack, + or a hard register in which to store the argument. + + MODE is the argument's machine mode. + TYPE is the data type of the argument (as a tree). + This is null for libcalls where that information may + not be available. + CUM is a variable of type CUMULATIVE_ARGS which gives info about + the preceding args and about the function being called. */ + +struct rtx_def * +m68k_function_arg (cum, mode, type) + CUMULATIVE_ARGS *cum; + enum machine_mode mode; + tree type; +{ + if (cum->num_of_regs) + { + int regbegin = -1, altregbegin = -1, len; + + /* FIXME: The last condition below is a workaround for a bug. */ + if (TARGET_68881 && FLOAT_MODE_P (mode) && + GET_MODE_UNIT_SIZE (mode) <= 12 && + (GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT || mode == SCmode)) + { + regbegin = 16; /* FPx */ + len = GET_MODE_NUNITS (mode); + } + /* FIXME: Two last conditions below are workarounds for bugs. */ + else if (INTEGRAL_MODE_P (mode) && mode !=CQImode && mode != CHImode) + { + if (POINTER_TYPE_P (type)) + regbegin = 8; /* Ax */ + else + regbegin = 0; /* Dx */ + altregbegin = 8 - regbegin; + len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; + } + + if (regbegin != -1) + { + int reg; + long mask; + +look_for_reg: + mask = 1 << regbegin; + for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1) + if (!(cum->regs_already_used & mask)) + { + int end; + for (end = reg; end < cum->num_of_regs && end < reg + len; + end++, mask <<= 1) + if (cum->regs_already_used & mask) + break; + if (end == reg + len) + { + cum->last_arg_reg = reg + regbegin; + cum->last_arg_len = len; + break; + } + } + + if (reg == cum->num_of_regs && altregbegin != -1) + { + regbegin = altregbegin; + altregbegin = -1; + goto look_for_reg; + } + } + + if (cum->last_arg_reg != -1) + return gen_rtx (REG, mode, cum->last_arg_reg); + } + return 0; +} + +/* Attributes support. */ + +/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine + specific attribute for TYPE. The attributes in ATTRIBUTES have previously + been assigned to TYPE. */ + +int +valid_m68k_type_attribute (type, attributes, identifier, args) + tree type, attributes, identifier, args; +{ + if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) + { + /* 'regparm' accepts one optional argument - number of registers in + single class that should be used to pass arguments. */ + if (is_attribute_p ("regparm", identifier)) + { + if (lookup_attribute ("stkparm", attributes)) + { + error ("`regparm' and `stkparm' are mutually exclusive"); + return 0; + } + if (args && TREE_CODE (args) == TREE_LIST) + { + tree numofregs = TREE_VALUE (args); + if (numofregs) + if (TREE_CODE (numofregs) != INTEGER_CST + || TREE_INT_CST_HIGH (numofregs) + || TREE_INT_CST_LOW (numofregs) < 1 + || TREE_INT_CST_LOW (numofregs) > M68K_MAX_REGPARM) + { + error ("invalid argument to `regparm' attribute"); + return 0; + } + } + return 1; + } + if (is_attribute_p ("stkparm", identifier)) + { + if (lookup_attribute ("regparm", attributes)) + { + error ("`regparm' and `stkparm' are mutually exclusive"); + return 0; + } + return 1; + } + } + + return 0; +} + +/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible, + one if they are compatible, and two if they are nearly compatible + (which causes a warning to be generated). */ + +int +comp_m68k_type_attributes (type1, type2) + tree type1, type2; +{ + /* Functions or methods are incompatible if they specify mutually + exclusive ways of passing arguments. */ + if (TREE_CODE (type1) == FUNCTION_TYPE || TREE_CODE (type1) == METHOD_TYPE) + { + tree arg1, arg2; + if (!! lookup_attribute ("stkparm", TYPE_ATTRIBUTES (type1)) != + !! lookup_attribute ("stkparm", TYPE_ATTRIBUTES (type2)) + || !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1)) != + !! lookup_attribute ("regparm", TYPE_ATTRIBUTES (type2))) + return 0; /* 'regparm' and 'stkparm' are mutually exclusive. */ + + arg1 = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type1)); + arg2 = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type2)); + if (arg1 && arg2) + { + int num1 = 0, num2 = 0; + if (TREE_VALUE (arg1) && TREE_CODE (TREE_VALUE (arg1)) == TREE_LIST) + { + tree numofregs = TREE_VALUE (TREE_VALUE (arg1)); + if (numofregs) + num1 = TREE_INT_CST_LOW (numofregs); + } + if (TREE_VALUE (arg2) && TREE_CODE (TREE_VALUE (arg2)) == TREE_LIST) + { + tree numofregs = TREE_VALUE (TREE_VALUE (arg2)); + if (numofregs) + num2 = TREE_INT_CST_LOW (numofregs); + } + if (num1 != num2) + return 0; /* Different numbers, or no number in one type. */ + } + } + return 1; +} char * output_andsi3 (operands) diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index ee0dc75..e53c47a 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -68,10 +68,8 @@ extern int target_flags; #define MASK_RTD 8 #define TARGET_RTD (target_flags & MASK_RTD) -/* Compile passing first two args in regs 0 and 1. - This exists only to test compiler features that will - be needed for RISC chips. It is not usable - and is not intended to be usable on this cpu. */ +/* Compile using the first 'm68k_regparm' data, address and float + registers for arguments passing. */ #define MASK_REGPARM 16 #define TARGET_REGPARM (target_flags & MASK_REGPARM) @@ -182,6 +180,8 @@ extern int target_flags; { "cpu32", MASK_68020}, \ { "align-int", MASK_ALIGN_INT }, \ { "no-align-int", -MASK_ALIGN_INT }, \ + { "regparm", MASK_REGPARM}, \ + { "no-regparm", - MASK_REGPARM}, \ SUBTARGET_SWITCHES \ { "", TARGET_DEFAULT}} /* TARGET_DEFAULT is defined in sun*.h and isi.h, etc. */ @@ -199,6 +199,7 @@ extern int target_flags; { { "align-loops=", &m68k_align_loops_string }, \ { "align-jumps=", &m68k_align_jumps_string }, \ { "align-functions=", &m68k_align_funcs_string }, \ + { "regparm=", &m68k_regparm_string }, \ SUBTARGET_OPTIONS \ } @@ -809,7 +810,7 @@ extern enum reg_class regno_reg_class[]; #ifndef SUPPORT_SUN_FPA #define CLASS_MAX_NREGS(CLASS, MODE) \ - ((CLASS) == FP_REGS ? 1 \ + ((CLASS) == FP_REGS ? GET_MODE_NUNITS (MODE) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* Moves between fp regs and other regs are two insns. */ @@ -821,7 +822,8 @@ extern enum reg_class regno_reg_class[]; #else /* defined SUPPORT_SUN_FPA */ #define CLASS_MAX_NREGS(CLASS, MODE) \ - ((CLASS) == FP_REGS || (CLASS) == FPA_REGS || (CLASS) == LO_FPA_REGS ? 1 \ + ((CLASS) == FP_REGS || (CLASS) == FPA_REGS || (CLASS) == LO_FPA_REGS ? \ + GET_MODE_NUNITS (MODE) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* Moves between fp regs and other regs are two insns. */ @@ -925,10 +927,19 @@ extern enum reg_class regno_reg_class[]; #define PCC_STATIC_STRUCT_RETURN -/* 1 if N is a possible register number for function argument passing. - On the 68000, no registers are used in this way. */ +/* 1 if N is a possible register number for function argument passing. */ -#define FUNCTION_ARG_REGNO_P(N) 0 +#define FUNCTION_ARG_REGNO_P(N) \ + (((N) >= 0 && (N) < M68K_MAX_REGPARM) \ + || ((N) >= 8 && (N) < 8 + M68K_MAX_REGPARM) \ + || (TARGET_68881 && (N) >= 16 && (N) < 16 + M68K_MAX_REGPARM)) + +/* Nonzero if we need to generate special stack-allocating insns. + On most systems they are not needed. + When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md) + to perform the necessary actions. */ + +#define TARGET_ALTERNATE_ALLOCATE_STACK 0 /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should @@ -936,28 +947,52 @@ extern enum reg_class regno_reg_class[]; and about the args processed so far, enough to enable macros such as FUNCTION_ARG to determine where the next arg should go. - On the m68k, this is a single integer, which is a number of bytes - of arguments scanned so far. */ + On the m68k, this is a structure: + num_of_regs: number of data, address and float registers to use for + arguments passing (if it's 2, than pass arguments in d0, d1, a0, a1, + fp0 and fp1). 0 - pass everything on stack. vararg calls are + always passed entirely on stack. + regs_already_used: bitmask of the already used registers. + last_arg_reg - register number of the most recently passed argument. + -1 if passed on stack. + last_arg_len - number of registers used by the most recently passed + argument. +*/ -#define CUMULATIVE_ARGS int +struct m68k_args +{ + int num_of_regs; + long regs_already_used; + int last_arg_reg; + int last_arg_len; +}; + +#define CUMULATIVE_ARGS struct m68k_args + +/* Max. number of data, address and float registers to be used for passing + integer, pointer and float arguments when TARGET_REGPARM. + It's 4, so d0-d3, a0-a3 and fp0-fp3 can be used. */ + +#define M68K_MAX_REGPARM 4 + +/* The default number of data, address and float registers to use when + user specified '-mregparm' switch, not '-mregparm=' option. */ + +#define M68K_DEFAULT_REGPARM 2 /* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE. - For a library call, FNTYPE is 0. - - On the m68k, the offset starts at 0. */ + For a library call, FNTYPE is 0. */ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ - ((CUM) = 0) + (m68k_init_cumulative_args (&(CUM), (FNTYPE))) /* Update the data in CUM to advance over an argument of mode MODE and data type TYPE. (TYPE is null for libcalls where that information may not be available.) */ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - ((CUM) += ((MODE) != BLKmode \ - ? (GET_MODE_SIZE (MODE) + 3) & ~3 \ - : (int_size_in_bytes (TYPE) + 3) & ~3)) + (m68k_function_arg_advance (&(CUM))) /* Define where to put the arguments to a function. Value is zero to push the argument on the stack, @@ -972,24 +1007,21 @@ extern enum reg_class regno_reg_class[]; NAMED is nonzero if this argument is a named parameter (otherwise it is an extra parameter matching an ellipsis). */ -/* On the 68000 all args are pushed, except if -mregparm is specified - then the first two words of arguments are passed in d0, d1. - *NOTE* -mregparm does not work. - It exists only to test register calling conventions. */ +/* On the 68000 all args are pushed, except if -mregparm is specified, + then a number of arguments is passed in the first 'm68k_regparm' data, + address and float registers. + Note: by default, the static-chain is passed in a0. Targets that want + to make full use of '-mregparm' are advised to pass the static-chain + somewhere else. */ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8) ? gen_rtx_REG ((MODE), (CUM) / 4) : 0) + ((struct rtx_def *)m68k_function_arg (&(CUM), (MODE), (TYPE))) /* For an arg passed partly in registers and partly in memory, this is the number of registers used. For args passed entirely in registers or entirely in memory, zero. */ -#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ -((TARGET_REGPARM && (CUM) < 8 \ - && 8 < ((CUM) + ((MODE) == BLKmode \ - ? int_size_in_bytes (TYPE) \ - : GET_MODE_SIZE (MODE)))) \ - ? 2 - (CUM) / 4 : 0) +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) (0) /* Generate the assembly code for function entry. */ #define FUNCTION_PROLOGUE(FILE, SIZE) output_function_prologue(FILE, SIZE) @@ -1190,6 +1222,8 @@ while(0) of a local variable as a function of frame_pointer_needed, which is hard. */ +#define SUBTARGET_INITIAL_FP_OFFSET(OFFSET) + #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \ { int regno; \ int offset = -4; \ @@ -1199,8 +1233,9 @@ while(0) for (regno = 0; regno < 16; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ offset += 4; \ - if (flag_pic && current_function_uses_pic_offset_table) \ + if (flag_pic && flag_pic <= 2 && current_function_uses_pic_offset_table) \ offset += 4; \ + SUBTARGET_INITIAL_FP_OFFSET (offset); \ (DEPTH) = (offset + ((get_frame_size () + 3) & -4) \ + (get_frame_size () == 0 ? 0 : 4)); \ } @@ -2083,6 +2118,23 @@ do { long l; \ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) + +/* Attributes support. */ + +/* A C expression whose value is nonzero if IDENTIFIER with arguments + ARGS is a valid machine specific attribute for TYPE. The attributes + in ATTRIBUTES have previously been assigned to TYPE. */ + +#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \ + (valid_m68k_type_attribute ((TYPE), (ATTRIBUTES), (IDENTIFIER), (ARGS))) + +/* A C expression whose value is zero if the attributes on TYPE1 and + TYPE2 are incompatible, one if they are compatible, and two if they + are nearly compatible (which causes a warning to be generated). */ + +#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \ + (comp_m68k_type_attributes ((TYPE1), (TYPE2))) + /* Define functions defined in aux-output.c and used in templates. */ extern char *output_move_const_into_data_reg (); @@ -2115,9 +2167,11 @@ extern int strict_low_part_peephole_ok (); extern const char *m68k_align_loops_string; extern const char *m68k_align_jumps_string; extern const char *m68k_align_funcs_string; +extern const char *m68k_regparm_string; extern int m68k_align_loops; extern int m68k_align_jumps; extern int m68k_align_funcs; +extern int m68k_regparm; extern int m68k_last_compare_had_fp_operands; /* Functions from m68k.c used in macros. */ diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 618828b..bcba080 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -3840,7 +3840,7 @@ case -1 : /* FIXME : a scratch register would be welcome here if operand[0] is not a register */ - output_asm_insn (\"move%.l %#-1,%R0\", operands); + output_asm_insn (\"move%.l %#-1,%0\", operands); break; default : { @@ -6818,7 +6818,7 @@ (match_operand:SI 1 "general_operand" "g"))] ;; Operand 1 not really used on the m68000. - "! flag_pic" + "(! flag_pic || flag_pic >= 3)" "* #if defined (MOTOROLA) && !defined (USE_GAS) #ifdef MOTOROLA_BSR @@ -6838,7 +6838,7 @@ (match_operand:SI 1 "general_operand" "g"))] ;; Operand 1 not really used on the m68000. - "flag_pic" + "(flag_pic && flag_pic < 3)" "* if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) @@ -6881,7 +6881,7 @@ (call (match_operand:QI 1 "memory_operand" "o") (match_operand:SI 2 "general_operand" "g")))] ;; Operand 2 not really used on the m68000. - "! flag_pic" + "(! flag_pic || flag_pic >= 3)" "* #if defined (MOTOROLA) && !defined (USE_GAS) #ifdef MOTOROLA_BSR @@ -6901,7 +6901,7 @@ (call (match_operand:QI 1 "memory_operand" "o") (match_operand:SI 2 "general_operand" "g")))] ;; Operand 2 not really used on the m68000. - "flag_pic" + "(flag_pic && flag_pic < 3)" "* if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) @@ -6984,7 +6984,10 @@ "* { if (current_function_pops_args == 0) - return \"rts\"; + if (current_function_is_interrupt == 0) + return \"rts\"; + else + return \"rte\"; operands[0] = GEN_INT (current_function_pops_args); return \"rtd %0\"; }") @@ -7945,3 +7948,16 @@ (unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))] "TARGET_68881 && flag_fast_math" "fcos%.x %1,%0") + +; This is only needed for some subtargets. +(define_expand "allocate_stack" + [(set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (reg:SI 15) (match_operand:SI 1 "general_operand" ""))) + (set (reg:SI 15) (minus:SI (reg:SI 15) (match_dup 1)))] + "TARGET_ALTERNATE_ALLOCATE_STACK" + " +{ +#ifdef ALTERNATE_ALLOCATE_STACK + ALTERNATE_ALLOCATE_STACK(operands); +#endif +}") diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos new file mode 100644 index 0000000..3555275 --- /dev/null +++ b/gcc/config/m68k/t-amigaos @@ -0,0 +1,79 @@ +# Makefile fragment for AmigaOS target. + +# Each compilation environment (Manx, Dice, GCC, SAS/C, etc) provides its +# own equivalent of the UNIX /usr/include tree. For gcc, the standard headers +# are in /gg/include and system specific headers are in /gg/os-include. +# Use these paths for fixincludes. + +SYSTEM_HEADER_DIR = /gg/include + +# Extra object file linked to the cc1* executables. +amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H) + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< + +# We don't need a libgcc1, it's all in ixemul.library and LibNIX + +LIBGCC1 = libgcc1.null +CROSS_LIBGCC1 = libgcc1.null + +# Additional target dependent options for compiling libgcc.a. This just +# ensures that we don't compile libgcc* with anything other than a +# fixed stack. + +TARGET_LIBGCC2_CFLAGS = -mfixedstack + +# Support for building multiple version of libgcc. +# Note: this is taken from the toplevel Makefile.in multilib support. +LIBGCC = stmp-libgcc-multi +INSTALL_LIBGCC = install-libgcc-multi + +LIBGCC_MULTI = ".;" \ + "libb;@resident" \ + "libm020;@m68020" \ + "libb/libm020;@resident@m68020" \ + "libb32/libm020;@resident32@m68020" + +# Build multiple copies of libgcc.a, one for each target switch. +stmp-libgcc-multi: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \ + frame.h \ + $(LIB2ADD) machmode.h longlong.h gbl-ctors.h config.status + # We need the following explicit mkdir, since the toplevel + # Makefile.in attempts to create only the last directory + # of a path. + if [ -d libb32 ]; then true; else mkdir libb32; fi + for i in $(LIBGCC_MULTI); do \ + dir=`echo $$i | sed -e 's/;.*$$//'`; \ + flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \ + $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \ + CC="$(CC)" CFLAGS="$(CFLAGS)" \ + RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \ + RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \ + LANGUAGES="$(LANGUAGES)" \ + HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \ + LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS) $${flags}" \ + MULTILIB_CFLAGS="$${flags}" \ + LIBGCC1="$(LIBGCC1)" LIBGCC2="$(LIBGCC2)" \ + dir="$${dir}" stmp-multilib-sub; \ + if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ + done + touch stmp-libgcc-multi + +# Install multiple versions of libgcc.a. +install-libgcc-multi: stmp-libgcc-multi installdirs + # We need the following explicit mkdir, since below we attempt to + # create only the last directory of a path. + if [ -d $(libsubdir)/libb32 ]; then true; else mkdir $(libsubdir)/libb32; fi + for i in $(LIBGCC_MULTI); do \ + dir=`echo $$i | sed -e 's/;.*$$//'`; \ + if [ -d $(libsubdir)/$${dir} ]; then true; else mkdir $(libsubdir)/$${dir}; fi; \ + for f in libgcc.a $(EXTRA_MULTILIB_PARTS); do \ + rm -f $(libsubdir)/$${dir}/$${f}; \ + $(INSTALL_DATA) $${dir}/$${f} $(libsubdir)/$${dir}/$${f}; \ + done; \ + if $(RANLIB_TEST_FOR_TARGET); then \ + (cd $(libsubdir)/$${dir}; $(RANLIB_FOR_TARGET) libgcc.a); \ + else true; fi; \ + chmod a-x $(libsubdir)/$${dir}/libgcc.a; \ + done diff --git a/gcc/config/m68k/x-amigaos b/gcc/config/m68k/x-amigaos new file mode 100644 index 0000000..517db57 --- /dev/null +++ b/gcc/config/m68k/x-amigaos @@ -0,0 +1,77 @@ +# Makefile fragment for AmigaOS host + +# Uncomment the following macro to get a resident GCC. We don't do it +# by default, since we want to support users with mc68000. +# WARNING! If you uncomment this, you MUST add the same flags to the +# libiberty's Makefile (libiberty is now linked into GCC executables). + +#RESIDENT = -m68020 -resident32 + +# Additional host flags that are not used when compiling with GCC_FOR_TARGET, +# such as when compiling the libgcc* runtime archives. GCC uses stack +# a lot, and since AmigaOS provides processes with a small, fixed size +# stack, we have to generate code that will extend it whenever necessary. + +XCFLAGS = -mstackextend $(RESIDENT) + +# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are +# build with a custom "makeinfo". + +### begin-GG-local: gcc-amigaos +EXTRA_DOC_TARGETS = guide gcc-amigaos-doc +### end-GG-local + +# Arrange for guides to be build with GCC, in the build directory. + +ALL = all.internal doc + +# Actually build guides + +guide: cpp.guide gcc.guide + +cpp.guide: cpp.texi + $(MAKEINFO) -I$(srcdir) $(srcdir)/cpp.texi --output=$@ --amiga + +gcc.guide: gcc.texi extend.texi install.texi invoke.texi \ + md.texi rtl.texi tm.texi + $(MAKEINFO) -I$(srcdir) $(srcdir)/gcc.texi --output=$@ --amiga + +# Arrange for guides to be installed with GCC. + +### begin-GG-local: gcc-amigaos +INSTALL_TARGET=install-normal install-guide install-gcc-amigaos-doc +### end-GG-local + +# Where the guide files go + +guidedir = $(prefix)/guide + +# Actually install guides. + +install-guide: doc installdirs + -if [ -d $(guidedir) ] ; then true ; else mkdir $(guidedir) ; chmod a+rx $(guidedir) ; fi + -rm -f $(guidedir)/cpp.guide $(guidedir)/gcc.guide + for f in cpp.guide gcc.guide; \ + do $(INSTALL_DATA) $$f $(guidedir)/$$f; done + -chmod a-x $(guidedir)/cpp.guide $(guidedir)/gcc.guide + +### begin-GG-local: gcc-amigaos +# Build and install gcc-amigaos.guide - documentation specific to the +# AmigaOS port of GCC. + +gcc-amigaos-doc: gcc-amigaos.info gcc-amigaos.guide + +gcc-amigaos.info: gcc-amigaos.texi + $(MAKEINFO) -I$(srcdir) $(srcdir)/gcc-amigaos.texi --output=$@ + +gcc-amigaos.guide: gcc-amigaos.texi + $(MAKEINFO) -I$(srcdir) $(srcdir)/gcc-amigaos.texi --output=$@ --amiga + +install-gcc-amigaos-doc: doc installdirs + -if [ -d $(guidedir) ] ; then true ; else mkdir $(guidedir) ; chmod a+rx $(guidedir) ; fi + -rm -f $(infodir)/gcc-amigaos.info* $(guidedir)/gcc-amigaos.guide + for f in gcc-amigaos.info*; \ + do $(INSTALL_DATA) $$f $(infodir)/$$f; done + $(INSTALL_DATA) gcc-amigaos.guide $(guidedir) + -chmod a-x $(infodir)/gcc-amigaos.info* $(guidedir)/gcc-amigaos.guide +### end-GG-local diff --git a/gcc/configure b/gcc/configure index 38d3db4..cef4fdb 100755 --- a/gcc/configure +++ b/gcc/configure @@ -4341,6 +4341,13 @@ for machine in $build $host $target; do thread_file='vxworks' float_format=m68k ;; + m68k-*-amigaos*) + tm_file=m68k/amigaos.h + tmake_file=m68k/t-amigaos + xmake_file=m68k/x-amigaos + extra_objs=amigaos.o + gnu_ld=yes + ;; m68k-*-aout*) tmake_file=m68k/t-m68kbare tm_file="m68k/m68k-aout.h libgloss.h" diff --git a/gcc/configure.in b/gcc/configure.in index 55dcec7..50ae181 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -134,10 +134,11 @@ AC_ARG_WITH(elf, elf="$with_elf", elf=no) +### begin-GG-local: local prefix # Specify the local prefix local_prefix= AC_ARG_WITH(local-prefix, -[ --with-local-prefix=DIR specifies directory to put local include.], +[ --with-local-prefix=DIR specifies directory to put local include directory (not files).], [case "${withval}" in yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;; no) ;; @@ -146,8 +147,9 @@ esac]) # Default local prefix if it is empty if test x$local_prefix = x; then - local_prefix=/usr/local + local_prefix='${prefix}'/local fi +### end-GG-local # Don't set gcc_gxx_include_dir to gxx_include_dir since that's only # passed in by the toplevel make and thus we'd get different behavior @@ -2013,6 +2015,13 @@ changequote([,])dnl thread_file='vxworks' float_format=m68k ;; + m68k-*-amigaos*) + tm_file=m68k/amigaos.h + tmake_file=m68k/t-amigaos + xmake_file=m68k/x-amigaos + extra_objs=amigaos.o + gnu_ld=yes + ;; m68k-*-aout*) tmake_file=m68k/t-m68kbare tm_file="m68k/m68k-aout.h libgloss.h" diff --git a/gcc/cppinit.c b/gcc/cppinit.c index 453cc58..8ad3d42 100644 --- a/gcc/cppinit.c +++ b/gcc/cppinit.c @@ -140,6 +140,7 @@ include_defaults_array[] /* This is another place that the target system's headers might be. */ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 }, #endif + { LOCAL_INCLUDE_DIR, 0, 0, 1 }, #else /* not CROSS_COMPILE */ #ifdef LOCAL_INCLUDE_DIR /* This should be /usr/local/include and should come before diff --git a/gcc/fixinc/mkfixinc.sh b/gcc/fixinc/mkfixinc.sh index 2c1a26c..a7bb436 100755 --- a/gcc/fixinc/mkfixinc.sh +++ b/gcc/fixinc/mkfixinc.sh @@ -87,6 +87,7 @@ case $machine in i[34567]86-*-pe | i[34567]86-*-cygwin* | \ i[34567]86-*-mingw32* | \ mips-sgi-irix5cross64 | \ + m68k-*-amigaos* | \ powerpc-*-eabiaix* | \ powerpc-*-eabisim* | \ powerpc-*-eabi* | \ diff --git a/gcc/flow.c b/gcc/flow.c index 432a990..6a44df7 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -3157,11 +3157,13 @@ regno_uninitialized (regno) if (n_basic_blocks == 0 || (regno < FIRST_PSEUDO_REGISTER && (global_regs[regno] - || fixed_regs[regno] - || FUNCTION_ARG_REGNO_P (regno)))) +/* begin-GG-local: explicit register specification for parameters */ + || fixed_regs[regno]))) return 0; - return REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno); + return (REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno) + && (regno >= FIRST_PSEUDO_REGISTER || ! function_arg_regno_p (regno))); +/* end-GG-local */ } /* 1 if register REGNO was alive at a place where `setjmp' was called diff --git a/gcc/function.c b/gcc/function.c index edd0bca..1de7c3e 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -165,6 +165,8 @@ int current_function_has_computed_jump; we should try to cut corners where we can. */ int current_function_is_thunk; +int current_function_is_interrupt; + /* Nonzero if function being compiled can call alloca, either as a subroutine or builtin. */ @@ -572,6 +574,7 @@ push_function_context_to (context) p->contains_functions = current_function_contains_functions; p->has_computed_jump = current_function_has_computed_jump; p->is_thunk = current_function_is_thunk; + p->is_interrupt = current_function_is_interrupt; p->args_size = current_function_args_size; p->pretend_args_size = current_function_pretend_args_size; p->arg_offset_rtx = current_function_arg_offset_rtx; @@ -658,6 +661,7 @@ pop_function_context_from (context) current_function_has_nonlocal_label = p->has_nonlocal_label; current_function_has_nonlocal_goto = p->has_nonlocal_goto; current_function_is_thunk = p->is_thunk; + current_function_is_interrupt = p->is_interrupt; current_function_args_size = p->args_size; current_function_pretend_args_size = p->pretend_args_size; current_function_arg_offset_rtx = p->arg_offset_rtx; @@ -5130,6 +5134,9 @@ assign_parms (fndecl, second_time) current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl), current_function_args_size); + current_function_is_interrupt = lookup_attribute ("interrupt_handler", + TYPE_ATTRIBUTES (TREE_TYPE (fndecl))); + /* For stdarg.h function, save info about regs and stack space used by the named args. */ @@ -5958,6 +5965,7 @@ init_function_start (subr, filename, line) current_function_uses_only_leaf_regs = 0; current_function_has_computed_jump = 0; current_function_is_thunk = 0; + current_function_is_interrupt = 0; current_function_returns_pcc_struct = 0; current_function_returns_struct = 0; @@ -7027,3 +7035,29 @@ reposition_prologue_and_epilogue_notes (f) } #endif /* HAVE_prologue or HAVE_epilogue */ } + +/* begin-GG-local: explicit register specification for parameters */ +/* Return 1 if an argument for the current function was passed in + register REGNO. */ + +int +function_arg_regno_p (regno) + int regno; +{ + tree parm = DECL_ARGUMENTS (current_function_decl); + for (; parm; parm = TREE_CHAIN (parm)) + { + rtx incoming = DECL_INCOMING_RTL (parm); + if (GET_CODE (incoming) == REG) + { + int incoming_reg; + incoming_reg = REGNO (incoming); + if (regno >= incoming_reg && + regno < incoming_reg + HARD_REGNO_NREGS (incoming_reg, + GET_MODE (incoming))) + return 1; + } + } + return 0; +} +/* end-GG-local */ diff --git a/gcc/function.h b/gcc/function.h index c25933c..5d7cd35 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -82,6 +82,7 @@ struct function int contains_functions; int has_computed_jump; int is_thunk; + int is_interrupt; rtx nonlocal_goto_handler_slots; rtx nonlocal_goto_handler_labels; rtx nonlocal_goto_stack_level; diff --git a/gcc/gcc-amigaos.texi b/gcc/gcc-amigaos.texi new file mode 100644 index 0000000..f428233 --- /dev/null +++ b/gcc/gcc-amigaos.texi @@ -0,0 +1,1133 @@ +\input texinfo.tex +@setfilename gcc-amigaos.info +@settitle AmigaOS-only features of GCC +@set lastupdate Oct 25th, 1997 +@setchapternewpage odd + +@ifinfo +This document describes implemenation specific features of the GNU CC +compiler port for the AmigaOS. + +Copyright @copyright{} 1996, 1997 Kamil Iskra + +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. +@end ifinfo + +@titlepage +@sp 10 +@center @titlefont{GCC Amiga} +@subtitle Description of the AmigaOS-only features of GCC +@subtitle @value{lastupdate} +@author Kamil Iskra +@end titlepage + +@contents + +@node Top +This document describes the AmigaOS-only features of the @samp{GNU CC} +compiler. + +Last updated @value{lastupdate}. + +@menu +* Introduction:: Purpose of this document. + +* Invocation:: Command line options. +* Attributes:: Variable and function attributes. +* Defines:: Preprocessor symbols. +* Miscellaneous:: Uncategorizable. +@end menu + +@node Introduction, Invocation, Top, Top +@chapter Introduction +@cindex Introduction +@cindex Purpose of this document + +This document is supposed to be an addendum to the baseline @samp{GCC} +documentation. + +It focuses on the features that are visible by users and are important +to them. It is not supposed to document the internals of the AmigaOS +port of @samp{GCC}. + +It describes features implemented in the @samp{Geek Gadgets GCC} port. +As of this writing, this is version 2.7.2.1, @samp{Geek Gadgets} +snapshot @samp{970728}. For more information about @samp{Geek +Gadgets}, please refer to: + +@format +http://www.ninemoons.com/ADE/ADE.html +ftp://ftp.ninemoons.com/pub/geekgadgets/README +@end format + +This document also describes some features that are not yet part of +the @samp{Geek Gadgets GCC} port, but which should be there soon. Such +features are marked with @emph{[EXPERIMENTAL]}. If you have @samp{GCC} +from a snapshot later than specified above, it's possible that these +features are available in it. Some of these features might also be +available in BETA @samp{GCC} releases available on Kamil Iskra's WWW +page: + +@format +http://student.uci.agh.edu.pl/~iskra/ade.html +@end format + +This document focuses on @samp{GCC}. It does not describe the +AmigaOS-only features of other @samp{GNU} packages, such as +@samp{binutils}, unless they are very closely connected to @samp{GCC}. + +This means, that, unless stated otherwise, when we talk about the +``compiler'', we mean the @file{gcc}, @file{cpp} and @file{cc1} +executables, i.e., the executables that convert @samp{C} source code +to assembly source code. The assembler and linker are generally beyond +the scope of this document. + +The primary source of information used to create this document was the +@samp{GCC} source code. Some parts of this document are based on: + +@itemize @bullet +@item +The @samp{LibNIX} manual, written by Matthias Fleischer and Gunther +Nikl: + +@format +fleischr@@izfm.uni-stuttgart.de +gnikl@@informatik.uni-rostock.de +@end format + +@item +The @samp{A2IXLibrary} manual, written by Hans Verkuil: + +@format +hans@@wyst.hobby.nl +@end format + +@item +The @samp{README} file, maintained by Rask Ingemann Lambertsen: + +@format +gc948374@@gbar.dtu.dk +http://www.gbar.dtu.dk/~c948374/GNU/ +@end format + +@item +The @samp{Geek Gadgets FAQ}, maintained by Lynn Winebarger: + +@format +owinebar@@indiana.edu +http://nickel.ucs.indiana.edu/~owinebar/interests/amiga/amiga.html +@end format + +@item +The @samp{FAQ for g++ and libg++}, written by Joe Buck: + +@format +jbuck@@synopsys.com +http://www.cygnus.com/misc/g++FAQ_toc.html +@end format + +@item +Discussions on various @samp{Geek Gadgets} mailing lists: + +@format +gg@@ninemoons.com +gg-gcc@@ninemoons.com +gg-ixemul@@ninemoons.com +@end format +@end itemize + +This document was created by Kamil Iskra. Please email any questions, +suggestions etc. to or, even better, +to the mailing list. + +The author would like to thank Kriton Kyrimis and +Lars Hecking for correcting an awful lot of +language mistakes in this document. + +@node Invocation, Attributes, Introduction, Top +@chapter Invocation +@cindex Invocation +@cindex Command line options + +The AmigaOS port of @samp{GCC} supports the following non-standard +command line options: + +@menu +* -noixemul:: Link with @samp{LibNIX}. + +* -fbaserel:: Produce @samp{a4}-relative data. +* -resident:: Produce a @samp{pure} executable. +* -fbaserel32:: Produce @samp{a4}-relative data with no size limits. +* -resident32:: Produce a @samp{pure} executable with no size limits. +* -msmall-code:: Produce @samp{PC}-relative code. + +* -mstackcheck:: Produce stack-checking code. +* -mstackextend:: Produce stack-extending code. +* -mfixedstack:: Produce plain code. + +* -mrestore-a4:: Reload @samp{a4} in public functions. +* -malways-restore-a4:: Reload @samp{a4} in all functions. + +* -mregparm:: Pass function arguments in registers. + +* -frepo:: Enable @samp{C++} Template Repository. +@end menu + +Accordingly, the AmigaOS port of @samp{GCC} supports several flavors +of linker libraries. @xref{Library flavors, Relation between library +flavors and compile-time options}. + +@node -noixemul, -fbaserel, Invocation, Invocation +@section -noixemul +@cindex -noixemul +@cindex Link with LibNIX + +@cindex IXEmul +By default, the executables created with @samp{GCC} require +@samp{ixemul.library} to run. This has its advantages (easy porting of +@samp{UN*X} programs, resource tracking, debugging, profiling, etc) +and disadvantages (@samp{UN*X}-style pathnames, large shared library, +etc). + +@cindex LibNIX +If @samp{-noixemul} is specified on the @samp{GCC} command line, the +executable created will not require @samp{ixemul.library} --- it will +use the static linker library @samp{LibNIX} instead. This library is +very Amiga-like and @samp{SAS/C}-like, so it is convenient for the +AmigaOS-specific development. + +@quotation +@emph{Note}: There is no great mystery about the @samp{-noixemul} +option. It has absolutely no effect on the code generated by the +compiler, only instructing the @samp{gcc} driver to pass different +options to the linker and preprocessor (@pxref{Options information}, +@pxref{Library flavors}). + +This option has no negative form. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -fbaserel, -resident, -noixemul, Invocation +@section -fbaserel +@cindex -fbaserel +@cindex Produce a4-relative data + +By default, the code generated by @samp{GCC} references data using +32-bit, absolute addressing. + +@cindex a4 +@cindex 64 KB data limit +The @samp{-fbaserel} option will make @samp{GCC} generate code that +references data with 16 bit offsets relative to the @samp{a4} address +register. This makes executables smaller and faster. Unfortunately, +the size of the data section cannot exceed 64 KB, so this option +cannot be used for large programs, like @samp{GCC} itself. + +@quotation +@emph{Note}: For a base-relative executable, @samp{-fbaserel} needs to +be specified for compiling @emph{and} linking. Base-relative programs +require special startup code and special versions of linker libraries. +Since not all linker libraries are available in both plain and base +relative versions, the usefulness of this option is limited. It is +important to note that when the base-relative library is missing, the +linker will attempt to use the plain one. This might result in strange +link-time or even run-time errors. + +@cindex -fpic +This option is the AmigaOS equivalent of the standard @samp{GCC} +option @samp{-fpic}, which is not supported by the AmigaOS port. +@samp{-fpic} generates code that references data indirectly, through a +@dfn{global offset table}. The special addressing modes available on +the @samp{m68k} processor family allow for a much more efficient +implementation with @samp{-fbaserel}. + +The negative form of @samp{-fbaserel} is @samp{-fno-baserel}, and is +on by default. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -resident, -fbaserel32, -fbaserel, Invocation +@section -resident +@cindex -resident +@cindex Produce a pure executable + +Executables produced with the @samp{-resident} option are @dfn{pure}, +so they can be made @dfn{resident} using the AmigaShell +@samp{resident} command. @samp{resident} executables are loaded to +memory just once, and several concurrent instances share the code +section. + +@quotation +@emph{Note}: The compiler generates the same code for @samp{-resident} +as for @samp{-fbaserel} (@pxref{-fbaserel}). Only the linking stage is +different (special startup code is linked). + +This option has no negative form. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -fbaserel32, -resident32, -resident, Invocation +@section -fbaserel32 +@cindex -fbaserel32 +@cindex Produce a4-relative data with no size limits + +The difference between the @samp{-fbaserel32} and @samp{-fbaserel} +options (@pxref{-fbaserel}) is the same as between the standard +@samp{GCC} options @samp{-fPIC} and @samp{-fpic}. + +Code generated with @samp{-fbaserel32} references data with 32 bit +offsets relative to the @samp{a4} address register. In contrast to the +@samp{-fbaserel} (@pxref{-fbaserel}) option, there is no 64 KB size +limit. Unfortunately, the addressing modes with 32 bit offsets are +only available on 68020 and higher processors. Therefore, it is +necessary to specify @samp{-m68020} or higher to use this option. + +@quotation +@emph{Note}: This option used to be called @samp{-flarge-baserel} +before @samp{Geek Gadgets} snapshot @samp{970109}. Since it was not +functional then, this should not cause any compatibility problems. + +The negative form of @samp{-fbaserel32} is @samp{-fno-baserel32}, and +is on by default. +@end quotation + +@node -resident32, -msmall-code, -fbaserel32, Invocation +@section -resident32 +@cindex -resident32 +@cindex Produce a pure executable with no size limits + +This option is an improved version of @samp{-resident} +(@pxref{-resident}) --- it does not impose any limits on data section +size. Unfortunately, just like @samp{-fbaserel32} +(@pxref{-fbaserel32}), it is only available for 68020 or higher +processors. Therefore, it is necessary to specify @samp{-m68020} or +higher to use this option. + +@quotation +@emph{Note}: This option was first made available in the @samp{GCC} +2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}. + +This option has no negative form. +@end quotation + +@node -msmall-code, -mstackcheck, -resident32, Invocation +@section -msmall-code +@cindex -msmall-code +@cindex Produce PC-relative code + +By default, the code generated by the compiler references functions +using 32-bit, absolute addressing. + +@cindex 32 KB code limit +Code generated by @samp{GCC} with the @samp{-msmall-code} option +references symbols in the code section with 16 bit offsets, relative +to the @samp{PC} (@dfn{program counter}). This makes executables +smaller and faster. Unfortunately, the size of the code section is +generally limited to 32 KB, so this option can only be used for +relatively small programs. + +@quotation +@emph{Note}: Actually, the compiler always generates 32-bit code +references. If the assembler can calculate the offset between the +referencing instruction and the referenced symbol (in other words, if +the referenced symbol is in the same source file), it replaces the +32-bit reference with the @samp{PC}-relative one. External references +are left intact, unless @samp{-msmall-code} is used, in which case the +assembler generates @samp{PC}-relative references, and the exact +offsets are calculated by the linker. + +This option has no negative form. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -mstackcheck, -mstackextend, -msmall-code, Invocation +@section -mstackcheck +@cindex -mstackcheck +@cindex Produce stack-checking code + +By default, the code generated by @samp{GCC} does not check if there +is enough stack available before performing stack-consuming +operations. This is generally not necessary on @samp{UN*X} systems, +where the stack is extended automagically whenever needed. + +Unfortunately, the AmigaOS provides tasks with a static, fixed size +stack. + +However, if a program is compiled with @samp{-mstackcheck}, it will +check if there is enough stack available before performing any +stack-hungry operations. If there is a danger of stack overflow, the +program will abort and the user will be notified. + +Needless to say, stack checking increases the executable size and the +execution time. + +@quotation +@emph{Note}: Stack checking cannot be used for functions that might be +called from outside your task. This includes interrupt handlers, +shared library functions, hooks etc. In such cases, you should either +avoid using @samp{-mstackcheck} for files containing such functions, +or use @code{__attribute__((interrupt))} (@pxref{interrupt}). + +It is safe to call a function that performs stack checking from one +that does not, and vice versa. + +The negative form of @samp{-mstackcheck} is @samp{-mno-stackcheck}, +and is on by default. + +@emph{Warning}: @samp{-mno-stackcheck} used to be called +@samp{-mnostackcheck} before @samp{Geek Gadgets} snapshot +@samp{961012}. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -mstackextend, -mfixedstack, -mstackcheck, Invocation +@section -mstackextend +@cindex -mstackextend +@cindex Produce stack-extending code + +@samp{-mstackextend} is very similar to @samp{-mstackcheck} +(@pxref{-mstackcheck}). + +The main difference is that when a program runs out of stack, it is +not aborted, but a new stack area is allocated and the program +continues to run. + +@quotation +@emph{Note}: Stack extension can slow programs down significantly. It +is advised that programs are written in such a way that they do not +require too much stack. This can generally be achieved by explicitly +allocating memory for large structures and arrays using functions like +@samp{malloc()} or @samp{AllocMem()}, instead of creating them as +local variables. Another method is replacing recursion with iteration. +In addition, it might be considered to use stack extension only for +selected, ``dangerous'' functions (@pxref{stackext}), not for all +functions in a given program. + +The negative form of @samp{-mstackextend} is @samp{-mno-stackextend}, +and is on by default. + +@emph{Warning}: @samp{-mno-stackextend} used to be called +@samp{-mnostackextend} before @samp{Geek Gadgets} snapshot +@samp{961012}. +@end quotation + +For more information, please refer to the @samp{LibNIX} documentation. + +@node -mfixedstack, -mrestore-a4, -mstackextend, Invocation +@section -mfixedstack +@cindex -mfixedstack +@cindex Produce plain code + +This option makes @samp{GCC} generate plain code, that does neither +stack checking nor extension. Since this is the default, there is +generally no need to use this option. + +@quotation +@emph{Note}: This option has no negative form. +@end quotation + +@node -mrestore-a4, -malways-restore-a4, -mfixedstack, Invocation +@section -mrestore-a4 +@cindex -mrestore-a4 +@cindex Reload a4 in public functions + +This option is used to create the @samp{IXEmul} shared libraries +(those @file{*.ixlibrary} files). + +It sets @samp{a4} to the appropriate value in the prologues of all +public functions (i.e., functions with external linkage). This is +necessary if these functions are called from the code of application. + +@quotation +@emph{Note}: This option should not be used except for the creation of +an @samp{IXEmul} shared library. + +This option was first made available in the @samp{GCC} 2.7.2, +@samp{Geek Gadgets} snapshot @samp{960902}. It used to be called +@samp{-frestore-a4}, and was relabeled to its current name in the +@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}. + +The negative form of @samp{-mrestore-a4} is @samp{-mno-restore-a4}, +and is on by default. +@end quotation + +For more information, please refer to the @samp{A2IXLibrary} +documentation. + +@node -malways-restore-a4, -mregparm, -mrestore-a4, Invocation +@section -malways-restore-a4 +@cindex -malways-restore-a4 +@cindex Reload a4 in all functions + +This option is very similar to @samp{-mrestore-a4} +(@pxref{-mrestore-a4}). + +The only difference is that it sets @samp{a4} in all functions, +including private ones (i.e., functions with internal linkage, +@samp{static}). This is safer than @samp{-mrestore-a4} +(@pxref{-mrestore-a4}), but is also slower. + +@quotation +@emph{Note}: This option should not be used except for the creation of +an @samp{IXEmul} shared library. + +This option was first made available in the @samp{GCC} 2.7.2, +@samp{Geek Gadgets} snapshot @samp{960902}. It used to be called +@samp{-falways-restore-a4}, and was relabeled to its current name in +the @samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}. + +The negative form of @samp{-malways-restore-a4} is +@samp{-mno-always-restore-a4}, and is on by default. +@end quotation + +For more information, please refer to the @samp{A2IXLibrary} +documentation. + +@node -mregparm, -frepo, -malways-restore-a4, Invocation +@section -mregparm +@cindex -mregparm +@cindex Pass function arguments in registers + +On the @samp{m68k} architecture, @samp{GCC} passes function arguments +on the stack by default. + +@samp{-mregparm} allows for passing arguments in registers. This can +be slightly faster than the standard method of passing arguments on +the stack. + +The full syntax of this option is: + +@format +-mregparm[=] +@end format + +@samp{value} should be an integer ranging from 1 to 4. If no +@samp{value} is provided, 2 will be used. + +Four types of function arguments are recognized: + +@table @samp +@item Integer +Integer numbers (this includes enumerations, small structures and +@samp{bool} in @samp{C++}, but excludes @samp{long long}, which is too +large). They are passed in data registers, starting from @samp{d0}. + +@item Pointer +Pointers to objects or functions (this includes @samp{C++} references +and the implicit @samp{this} argument). They are passed in address +registers, starting from @samp{a0}. + +@item Float +Floating point numbers. If the floating point code generation is +enabled, they are passed in floating point registers, starting from +@samp{fp0}. Otherwise, they are handled like the next type. + +@item Other +All the other types of arguments, like large structures, pointers to +class methods in @samp{C++}, etc. They are always passed on the stack. +@end table + +The value given for @samp{-mregparm} indicates how many arguments of +each of the above first three types should be passed in registers. + +Example: @samp{GCC} is invoked with @samp{-mregparm} (without any +value, so 2 will be used) to compile a source containing the function: + +@example +void fun(int a, char *str, char b, int c); +@end example + +@samp{a} and @samp{b} will be passed in @samp{d0} and @samp{d1}, +respectively, @samp{str} will be passed in @samp{a0}, and @samp{c} +will be passed on the stack. + +@quotation +@emph{Note}: To use this option properly, it is very important that +all sources are fully prototyped. There may be very serious problems +if they are not, since @samp{GCC} will have to ``guess'' where to put +arguments, potentially making a wrong decission. Example: + +@example +[in file1.c] +void f(void) +@{ + g(0); /* Call to a function with no prototype. The argument + will be put in d0, since it is an integer. */ +@} + +[in file2.c] +void g(char *a) /* The argument is expected in a0, since it is + a pointer. */ +@{ +@} +@end example + +@samp{-Wimplicit -Wstrict-prototypes} should be used to ensure that +there are no prototypes missing. + +In case of @samp{stdargs} functions, such as @samp{printf}, all +arguments are passed on the stack. + +As of this writing, @samp{-mregparm} is supported by neither +@samp{IXEmul} nor @samp{LibNIX}, so its usefulness is very limited. + +This option was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +The negative form of @samp{-mregparm} is @samp{-mno-regparm}, and is +on by default. +@end quotation + +@node -frepo, , -mregparm, Invocation +@section -frepo +@cindex -frepo +@cindex Enable C++ Template Repository + +The AmigaOS port of @samp{GCC} includes @samp{C++} @dfn{Template +Repository} patch, so-called @samp{repo} patch. + +In order to activate it, please compile @samp{C++} source files with +@samp{-frepo}. The compiler will not generate unnecessary +@samp{template} code, and will create @samp{.rpo} files that contain +information about @samp{template} symbols used in each source file. +Afterwards, during linking stage, a special tool called +@samp{collect2} will make sure that every required instantiation of +each @samp{template} is linked into the executable, recompiling some +source files if necessary. + +@quotation +@emph{Note}: This option was first made available in the @samp{GCC} +2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}. + +This option is not specific to the AmigaOS port of +@samp{GCC}, nevertheless it is not fully supported in the baseline +sources. + +This patch has been created in Cygnus Support, a company that is a +major contributor to the @samp{GNU} project. It has not been +integrated into the baseline sources due to design disagreements. + +The negative form of @samp{-frepo} is @samp{-fno-repo}, and is on by +default. +@end quotation + +For more information, please refer to the @samp{G++ FAQ}. + +@node Attributes, Defines, Invocation, Top +@chapter Attributes +@cindex Attributes +@cindex Variable and function attributes + +The following non-standard attributes are available in the AmigaOS +port of @samp{GCC}: + +@menu +Variable attributes: +* chip:: Put object in @samp{chip} memory. + +Function attributes: +* saveds:: Reload @samp{a4}. +* interrupt:: Do not mess with the stack. +* stackext:: Generate stack extension. +* regparm:: Pass arguments in registers. +* stkparm:: Pass arguments on the stack. +@end menu + +@node chip, saveds, Attributes, Attributes +@section chip +@cindex chip +@cindex Put object in chip memory + +Amiga hardware requires some data to be located in @samp{chip} memory. + +Typically, if an initialized buffer is required (containing a picture +bitmap, for example), a plain, statically initialized buffer is used, +and the data is copied into a dynamically allocated @samp{MEMF_CHIP} +buffer. + +This is not necessary with the @samp{chip} attribute. If this +attribute is specified for an initialized, static variable, it will be +allocated in @samp{chip} memory automagically by the AmigaOS. + +A small example: + +@example +UWORD __attribute__((chip)) bitmap1[] = @{ ... @}; +@end example + +@quotation +@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers, +a preprocessor symbol @samp{__chip} is available, which expands to +@code{__attribute__((chip))} (@pxref{Keyword macros}). + +All the @samp{chip} attribute does is specifying that data should go +to a section called @samp{.datachip}. Therefore, the standard +@samp{GCC} feature @code{__attribute__((section(".datachip")))} can be +used instead. + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{970328}. + +For proper operation, this attribute requires a special version of the +assembler, which generates standard AmigaOS object files. This version +is not yet available in @samp{Geek Gadgets} in binary form, since +support for this object files format is not yet complete. +@end quotation + +@node saveds, interrupt, chip, Attributes +@section saveds +@cindex saveds +@cindex Reload a4 + +This attribute is ignored, unless base-relative data +(@pxref{-fbaserel}) is compiled. + +To improve speed, programs compiled with the AmigaOS port of +@samp{GCC} set the @samp{a4} register to the appropriate value only +once, in the startup code. Code generated with the standard @samp{GCC} +option @samp{-fpic}, in contrast, sets the @samp{a4} register in every +function which references global data. + +This is only safe as long as all function calls are performed from +within your own code. Things become ``tricky'' if callback functions, +like the AmigaOS hooks, interrupt handlers etc. are used. If global +data is referenced in such functions, @samp{a4} has to be set +properly. + +This is exactly what the @samp{saveds} attribute does: it initializes +@samp{a4} in the function prologue, and restores it to its original +value in the function epilogue. + +@quotation +@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers, +a preprocessor symbol @samp{__saveds} is available, which expands to +@code{__attribute__((saveds))} (@pxref{Keyword macros}). + +Please do not use this attribute in pure executables +(@pxref{-resident}, @pxref{-resident32}). This is because several +invocations of pure executables can run concurrently, each one having +its own data section, and there is no way to find out to which of +these sections should @samp{a4} be set. + +The @samp{saveds} attribute is not necessary in function declarations +(prototypes). +@end quotation + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node interrupt, stackext, saveds, Attributes +@section interrupt +@cindex interrupt +@cindex Do not mess with the stack + +This attribute should be used for any kind of callback functions that +can be called from outside your task. This includes interrupt +handlers, shared library functions, etc. + +Most often, the @samp{interrupt} attribute is only necessary if a +program is compiled with stack checking or extension +(@pxref{-mstackcheck}, @pxref{-mstackextend}). It will prevent the +compiler from generating stack checking or extension code for the +function it was specified for. + +Additionally, it will set @samp{CC} (@dfn{condition codes register}) +in the function epilogue to return value, by performing @code{tstl +d0}. + +@quotation +@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers, +a preprocessor symbol @samp{__interrupt} is available, which expands +to @code{__attribute__((interrupt))} (@pxref{Keyword macros}). + +The @samp{interrupt} attribute is mutually exclusive with the +@samp{stackext} attribute (@pxref{stackext}). + +This attribute is not necessary in function declarations (prototypes). +@end quotation + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node stackext, regparm, interrupt, Attributes +@section stackext +@cindex stackext +@cindex Generate stack extension + +This attribute makes @samp{GCC} generate stack extension code for the +function for which it was used (@pxref{-mstackextend}). This makes it +possible to use stack extension selectively, only for the +``dangerous'' functions --- recursive functions, functions with large +local variables, etc. + +@quotation +@emph{Note}: For compatibility with other AmigaOS @samp{C} compilers, +a preprocessor symbol @samp{__stackext} is available, which expands to +@code{__attribute__((stackext))} (@pxref{Keyword macros}). + +The @samp{stackext} attribute is mutually exclusive with the +@samp{interrupt} attribute (@pxref{interrupt}). + +This attribute is not necessary in function declarations (prototypes). +@end quotation + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node regparm, stkparm, stackext, Attributes +@section regparm +@cindex regparm +@cindex Pass arguments in registers + +The @samp{regparm} attribute, together with the @samp{stkparm} +attribute (@pxref{stkparm}), can be used to fine-tune the way +arguments are passed. It makes @samp{GCC} pass arguments in registers +for the function for which it was used, regardless of whether the +global @samp{-mregparm} option was used or not (@pxref{-mregparm}). + +An optional integer argument ranging from 1 to 4 indicates how many +arguments of each type should be passed in registers +(@pxref{-mregparm}). The syntax is the following: + +@example +void __attribute__((regparm(3))) fun(int a, char *str, char b, int c); +@end example + +This will make @samp{GCC} pass @samp{a}, @samp{b} and @samp{c} in +@samp{d0}, @samp{d1} and @samp{d2}, respectively, and @samp{str} in +@samp{a0}. + +If the argument is not provided, the value given for @samp{-mregparm} +will be used (or 2 if that option was not specified, +@pxref{-mregparm}). + +@quotation +@emph{Note}: There is generally no need to use this attribute unless +files compiled with different calling conventions are linked together. + +For compatibility with other AmigaOS @samp{C} compilers, a +preprocessor symbol @samp{__regargs} is available, which expands to +@code{__attribute__((regparm))} (@pxref{Keyword macros}). + +The @samp{regparm} attribute is mutually exclusive with the +@samp{stkparm} attribute (@pxref{stkparm}). + +This attribute is necessary both in function declarations (prototypes) +and definitions (function code). +@end quotation + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node stkparm, , regparm, Attributes +@section stkparm +@cindex stkparm +@cindex Pass arguments on the stack + +The @samp{stkparm} attribute, together with the @samp{regparm} +attribute (@pxref{regparm}), can be used to fine-tune the way +arguments are passed. It makes @samp{GCC} pass arguments on stack for +the function for which it was used, regardless of whether the global +@samp{-mregparm} option was used or not (@pxref{-mregparm}). + +@quotation +@emph{Note}: There is generally no need to use this attribute unless +files compiled with different calling conventions are linked together. + +For compatibility with other AmigaOS @samp{C} compilers, a +preprocessor symbol @samp{__stdargs} is available, which expands to +@code{__attribute__((stkparm))} (@pxref{Keyword macros}). + +The @samp{stkparm} attribute is mutually exclusive with the +@samp{regparm} attribute (@pxref{regparm}). + +This attribute is necessary both in function declarations (prototypes) +and definitions (function code). +@end quotation + +This attribute was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node Defines, Miscellaneous, Attributes, Top +@chapter Defines +@cindex Defines +@cindex Preprocessor symbols + +The AmigaOS-specific preprocessor symbols available in @samp{GCC} can +be divided into three groups: + +@menu +* Identifying machine:: What machine is this? +* Options information:: Which options have been specified? +* Keyword macros:: Compatibility with other compilers. +@end menu + +@node Identifying machine, Options information, Defines, Defines +@section Symbols identifying machine +@cindex Symbols identifying machine +@cindex What machine is this + +The following machine-identifying preprocessor symbols are available: + +@table @samp +@item mc68000 +This macro identifies the machine as having a CPU from the Motorola +68000 family. + +@item amiga +@item amigaos +@item amigados +These macros identify the machine as being an Amiga, running the +AmigaOS. + +@item AMIGA +@item MCH_AMIGA +These macros are provided for compatibility with other AmigaOS +@samp{C} compilers. +@end table + +@quotation +@emph{Note}: These symbols are available in three groups: plain (as +specified above), with two leading underscores, and with two leading +and two tailing underscores. The plain ones are not available when +compiling with the @samp{-ansi} option. + +The @samp{amigados} symbol is obsolete and will be removed in future. +Please use @samp{amigaos}, which was first made available in the +@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{961012}. +@end quotation + +@node Options information, Keyword macros, Identifying machine, Defines +@section Symbols identifying specified options +@cindex Symbols identifying specified options +@cindex Symbols identifying CPU +@cindex Symbols identifying ixemul +@cindex Which CPU model options have been specified + +@samp{GCC} has several options to choose the CPU model that the code +should be generated for. The following preprocessor symbols identify +which options have been specified on the command line: + +@table @samp +@item mc68020 +Either one of @samp{-m68020}, @samp{-mc68020} or @samp{-mc68020-40} +has been specified. + +@item mc68030 +@samp{-m68030} has been specified. + +@item mc68040 +@samp{-m68040} has been specified. + +@item mc68060 +@samp{-m68060} @emph{[EXPERIMENTAL]} has been specified. + +@item __HAVE_68881__ +@samp{-m68881} has been specified. +@end table + +@quotation +@emph{Note}: The symbols beginning with @samp{mc} are available in +three groups: plain (as specified above), with two leading +underscores, and with two leading and two tailing underscores. The +plain ones are not available when compiling with the @samp{-ansi} +option. The ``underscored'' ones were first made available in the +@samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot @samp{970109}. + +@samp{mc68000} is defined regardless of which @samp{-m680x0} options +have been used. +@end quotation + +In addition to the above, a preprocessor symbol @samp{ixemul} +(together with the ``underscored'' versions) is available when not +compiling with @samp{-noixemul} (@pxref{-noixemul}) and identifies the +runtime environment as @samp{IXEmul}. This symbol was first made +available in the @samp{GCC} 2.7.2.1, @samp{Geek Gadgets} snapshot +@samp{970328}. + +@node Keyword macros, , Options information, Defines +@section ``Keyword'' macros +@cindex Keyword macros +@cindex Compatibility with other compilers + +Most AmigaOS-specific @samp{C} compilers have special ``custom +keywords'', which make the AmigaOS-specific development easier. +Unfortunately, the idea of ``custom keywords'' is not available in +@samp{GCC}. However, @samp{attributes} are available, and they provide +virtually identical functionality. For compatibility with other +AmigaOS @samp{C} compilers, preprocessor symbols are provided, which +expand to the appropriate @samp{attributes} (@pxref{Attributes}). + +@table @samp +@item __chip +@xref{chip}. + +@item __saveds +@xref{saveds}. + +@item __interrupt +@xref{interrupt}. + +@item __stackext +@xref{stackext}. + +@item __regargs +@xref{regparm}. + +@item __stdargs +@xref{stkparm}. + +@item __aligned +This expands to the standard @samp{GCC} +@samp{__attribute__((aligned(4)))}. +@end table + +@quotation +@emph{Note}: With @samp{SAS/C}, these keywords may be specified either +before or after the type, so the following declaration is correct: + +@example +__saveds void func(void); +@end example + +Unfortunately, the syntax rules of @samp{GCC} 2.7.2.1 do not allow to +specify the attributes before the type, so the above example must be +changed to: + +@example +void __saveds func(void); +@end example + +This will be fixed in @samp{GCC} 2.8.0. +@end quotation + +@node Miscellaneous, , Defines, Top +@chapter Miscellaneous +@cindex Miscellaneous +@cindex Uncategorizable + +The following ``hard to categorize'' features are available in the +AmigaOS port of @samp{GCC}: + +@menu +* Explicit register specification:: Specify registers for arguments. +* Case sensitive CPP:: is not the same as +* GCCPRIORITY:: Set the priority of the compiler. +* Library flavors:: Linker libraries. +@end menu + +@node Explicit register specification, Case sensitive CPP, Miscellaneous, Miscellaneous +@section Explicit register specification +@cindex Explicit register specification +@cindex Specify registers for arguments + +In certain situations, like writing callback hooks, ``patchers'', +standard shared libraries, etc., functions have to receive arguments +in particular registers. + +@samp{-mregparm} (@pxref{-mregparm}) is not appropriate in this case, +since it does not give the programmer enough control on @emph{which} +registers will be used. + +To overcome this problem in the AmigaOS port of @samp{GCC}, explicit +register specification has been extended to be available for function +arguments, as well: + +@example +void myhook(struct Hook* hook __asm("a0"), APTR object __asm("a2"), + APTR message __asm("a1")) +@{ + ... +@} +@end example + +@quotation +@emph{Note}: This feature is currently not available in @samp{G++}. + +Only the @samp{ANSI}-style declarations (prototypes) are supported. + +Registers have to be specified both in function declarations +(prototypes) and definitions (function code). +@end quotation + +This feature was first made available in the @samp{GCC} 2.7.2.1, +@samp{Geek Gadgets} snapshot @samp{961012}. + +@node Case sensitive CPP, GCCPRIORITY, Explicit register specification, Miscellaneous +@section Case sensitive CPP +@cindex Case sensitive CPP +@cindex is not the same as + +The preprocessor available in the AmigaOS port of @samp{GCC} is case +sensitive. This means, that the header names provided in the +@code{#include} directives have to be correct, including upper and +lower case letters. This affects only the way the preprocessor works. +Currently available native AmigaOS file systems are case insensitive. + +@quotation +@emph{Note}: This might seem like a horrible hack and a crazy attempt +to implement a ``ridiculous'' UNIX feature on Amiga. However, this +feature has been introduced to terminate the endless @samp{G++} +problems with a standard @samp{ANSI C} header @file{string.h}: under +the AmigaOS, a @samp{C++} header @file{String.h} would be included, +instead. +@end quotation + +@node GCCPRIORITY, Library flavors, Case sensitive CPP, Miscellaneous +@section GCCPRIORITY +@cindex GCCPRIORITY +@cindex Set the priority of the compiler + +@samp{GCC} supports one AmigaOS-specific environment variable: +@samp{GCCPRIORITY}. + +This variable specifies the @samp{exec} priority of the compiler. If +this variable is not set, the default Shell priority will be used. + +@quotation +@emph{Note}: By default, the AmigaOS assigns the priority @samp{0} to +user tasks. It is thus generally unwise to set @samp{GCCPRIORITY} +higher than @samp{0}. +@end quotation + +@node Library flavors, , GCCPRIORITY, Miscellaneous +@section Library flavors +@cindex Library flavors +@cindex Linker libraries + +The AmigaOS port of @samp{GCC} may use different linker libraries +depending upon the options used while invoking the compiler. These +libraries reside in subdirectories of the standard locations, such as +@file{GG:lib/} or, with @samp{GCC} 2.7.2.1, +@file{GG:lib/gcc-lib/m68k-amigaos/2.7.2.1/}. + +If you invoke @code{gcc} with @samp{-v}, you'll see the precise flavor +of libraries used as a @samp{-fl} option in the @code{ld} invocation. +Here is a list of the available flavors (and hence the subdirectories +names): + +@itemize @bullet +@item +@file{libb} corresponds to the @ref{-fbaserel} option. +@item +@file{libb32} corresponds to the @ref{-fbaserel32} option. +@item +@file{libm020} corresponds to the @samp{-m68020} (or higher) options. +@item +@file{libm881} corresponds to the @samp{-m68881} option. +@item +@file{libnix} corresponds to the @ref{-noixemul} option. +@end itemize + +More than one flavor can be specified simultaneously. For example, +when both @ref{-fbaserel} and @samp{-m68020} are specified, the +libraries will be searched in @file{libb/libm020} subdirectory (as +well as in @file{libb} subdirectory and in the standard location). +@bye diff --git a/gcc/genconfig.c b/gcc/genconfig.c index 9f79e58..7021b97 100644 --- a/gcc/genconfig.c +++ b/gcc/genconfig.c @@ -327,8 +327,8 @@ main (argc, argv) printf ("/* Generated automatically by the program `genconfig'\n\ from the machine description file `md'. */\n\n"); - /* Allow at least 10 operands for the sake of asm constructs. */ - max_recog_operands = 9; /* We will add 1 later. */ + /* Allow at least 15 operands for the sake of asm constructs. */ + max_recog_operands = 14; /* We will add 1 later. */ max_dup_operands = 1; /* Read the machine description. */ diff --git a/gcc/ginclude/stdarg.h b/gcc/ginclude/stdarg.h index 3607db1..fcbdf85 100644 --- a/gcc/ginclude/stdarg.h +++ b/gcc/ginclude/stdarg.h @@ -178,7 +178,7 @@ typedef __gnuc_va_list va_list; But on BSD NET2 we must not test or define or undef it. (Note that the comments in NET 2's ansi.h are incorrect for _VA_LIST_--see stdio.h!) */ -#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) || defined(__amigaos__) /* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ #ifndef _VA_LIST_DEFINED /* The macro _VA_LIST is used in SCO Unix 3.2. */ @@ -189,7 +189,7 @@ typedef __gnuc_va_list va_list; #endif /* not _VA_LIST_T_H */ #endif /* not _VA_LIST */ #endif /* not _VA_LIST_DEFINED */ -#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(__amigaos__)) #define _VA_LIST_ #endif #ifndef _VA_LIST diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h index 615052e..5f218d0 100644 --- a/gcc/ginclude/stddef.h +++ b/gcc/ginclude/stddef.h @@ -24,7 +24,7 @@ /* On 4.3bsd-net2, make sure ansi.h is included, so we have one less case to deal with in the following. */ -#if defined (__BSD_NET2__) || defined (____386BSD____) || defined (__FreeBSD__) || defined(__NetBSD__) +#if defined (__BSD_NET2__) || defined (____386BSD____) || defined (__FreeBSD__) || defined(__NetBSD__) || defined (__ixemul__) || defined (__libnix__) #include #endif diff --git a/gcc/ginclude/varargs.h b/gcc/ginclude/varargs.h index bb9c98a..beb3638 100644 --- a/gcc/ginclude/varargs.h +++ b/gcc/ginclude/varargs.h @@ -194,7 +194,7 @@ typedef __gnuc_va_list va_list; /* Michael Eriksson at Thu Sep 30 11:00:57 1993: Sequent defines _VA_LIST_ in to be the type to use for va_list (``typedef _VA_LIST_ va_list'') */ -#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) +#if !defined (_VA_LIST_) || defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(WINNT) || defined(__amigaos__) /* The macro _VA_LIST_DEFINED is used in Windows NT 3.5 */ #ifndef _VA_LIST_DEFINED /* The macro _VA_LIST is used in SCO Unix 3.2. */ @@ -205,7 +205,7 @@ typedef __gnuc_va_list va_list; #endif /* not _VA_LIST_T_H */ #endif /* not _VA_LIST */ #endif /* not _VA_LIST_DEFINED */ -#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__)) +#if !(defined (__BSD_NET2__) || defined (____386BSD____) || defined (__bsdi__) || defined (__sequent__) || defined (__FreeBSD__) || defined(__amigaos__)) #define _VA_LIST_ #endif #ifndef _VA_LIST diff --git a/gcc/output.h b/gcc/output.h index 8531085..4212b61 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -347,6 +347,8 @@ extern rtx final_sequence; extern int current_function_pops_args; +extern int current_function_is_interrupt; + /* Nonzero if function being compiled needs to be given an address where the value should be stored. */ diff --git a/gcc/protoize.c b/gcc/protoize.c index 7e9205c..aeffe1c 100644 --- a/gcc/protoize.c +++ b/gcc/protoize.c @@ -255,6 +255,7 @@ struct default_include { const char *fname; { CROSS_INCLUDE_DIR, 0, 0, 0 }, /* This is another place that the target system's headers might be. */ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 }, + { LOCAL_INCLUDE_DIR, 0, 0, 1 }, #else /* not CROSS_COMPILE */ /* This should be /use/local/include and should come before the fixincludes-fixed header files. */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 5f8913f..9493893 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -924,6 +924,10 @@ lang_independent_options f_options[] = {"pic", &flag_pic, 1, "Generate position independent code, if possible"}, {"PIC", &flag_pic, 2, ""}, + {"baserel", &flag_pic, 3, + "Generate base relative code"}, + {"baserel32", &flag_pic, 4, + "Generate base relative code with no data limits"}, {"exceptions", &flag_exceptions, 1, "Enable exception handling" }, {"new-exceptions", &flag_new_exceptions, 1, diff --git a/include/libiberty.h b/include/libiberty.h index cf31366..1f22e1e 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -16,6 +16,9 @@ extern "C" { #include "ansidecl.h" +#include +#include + /* Build an argument vector from a string. Allocates memory using malloc. Use freeargv to free the vector. */ diff --git a/include/objalloc.h b/include/objalloc.h index 0b451cd..4be3d2b 100644 --- a/include/objalloc.h +++ b/include/objalloc.h @@ -22,6 +22,8 @@ Boston, MA 02111-1307, USA. */ #include "ansidecl.h" +#include + /* These routines allocate space for an object. The assumption is that the object will want to allocate space as it goes along, but will never want to free any particular block. There is a function diff --git a/libiberty/argv.c b/libiberty/argv.c index 85c17e9..531815b 100644 --- a/libiberty/argv.c +++ b/libiberty/argv.c @@ -35,12 +35,13 @@ Boston, MA 02111-1307, USA. */ #ifdef __STDC__ #include +#ifndef __APPLE__ extern void *memcpy (void *s1, const void *s2, size_t n); /* 4.11.2.1 */ extern size_t strlen (const char *s); /* 4.11.6.3 */ extern void *malloc (size_t size); /* 4.10.3.3 */ extern void *realloc (void *ptr, size_t size); /* 4.10.3.4 */ extern void free (void *ptr); /* 4.10.3.2 */ -extern char *strdup (const char *s); /* Non-ANSI */ +#endif #else /* !__STDC__ */ diff --git a/libiberty/strerror.c b/libiberty/strerror.c index 644cc75..67bc34f 100644 --- a/libiberty/strerror.c +++ b/libiberty/strerror.c @@ -7,6 +7,8 @@ #include "config.h" +#define HAVE_SYS_ERRLIST + #ifdef HAVE_SYS_ERRLIST /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) might declare sys_errlist in a way that the compiler might consider @@ -27,8 +29,10 @@ #ifdef __STDC__ #include +#ifndef __APPLE__ extern void *malloc (size_t size); /* 4.10.3.3 */ extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ +#endif #else /* !__STDC__ */ extern char *malloc (); /* Standard memory allocater */ extern char *memset (); @@ -462,8 +466,12 @@ static const char **sys_errlist; #else +#ifdef __APPLE__ +extern const int sys_nerr; +#else extern int sys_nerr; -extern char *sys_errlist[]; +#endif +extern const char *const sys_errlist[]; #endif diff --git a/libiberty/strsignal.c b/libiberty/strsignal.c index c7bb10c..ae593c7 100644 --- a/libiberty/strsignal.c +++ b/libiberty/strsignal.c @@ -25,8 +25,10 @@ #ifdef __STDC__ #include +#ifndef __APPLE__ extern void *malloc (size_t size); /* 4.10.3.3 */ extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ +#endif #else /* !__STDC__ */ extern char *malloc (); /* Standard memory allocater */ extern char *memset (); @@ -584,8 +586,8 @@ DESCRIPTION void psignal (signo, message) - unsigned signo; - char *message; + unsigned int signo; + const char *message; { if (signal_names == NULL) { diff --git a/libio/fileops.c b/libio/fileops.c index 54e13d3..14c6e06 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -419,7 +419,10 @@ _IO_file_sync (fp) return retval; } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_file_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off_t offset; @@ -587,7 +590,10 @@ _IO_file_read (fp, buf, size) return read (fp->_fileno, buf, size); } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_file_seek (fp, offset, dir) _IO_FILE *fp; _IO_off_t offset; diff --git a/libio/genops.c b/libio/genops.c index b899e15..fd8ef47 100644 --- a/libio/genops.c +++ b/libio/genops.c @@ -467,10 +467,13 @@ _IO_default_setbuf (fp, p, len) return fp; } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_default_seekpos (fp, pos, mode) _IO_FILE *fp; - _IO_pos_t pos; + _IO_off_t pos; int mode; { return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode); @@ -551,7 +554,10 @@ _IO_default_finish (fp, dummy) _IO_un_link (fp); } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_default_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off_t offset; @@ -882,7 +888,10 @@ _IO_default_pbackfail (fp, c) return (unsigned char) *fp->_IO_read_ptr; } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_default_seek (fp, offset, dir) _IO_FILE *fp; _IO_off_t offset; diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c index b1c4729..1412343 100644 --- a/libio/ioseekoff.c +++ b/libio/ioseekoff.c @@ -25,7 +25,10 @@ #include -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off_t offset; diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c index 2ce0c22..1983f8a 100644 --- a/libio/ioseekpos.c +++ b/libio/ioseekpos.c @@ -25,10 +25,13 @@ #include -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_seekpos (fp, pos, mode) _IO_FILE *fp; - _IO_pos_t pos; + _IO_off_t pos; int mode; { _IO_pos_t retval; diff --git a/libio/strops.c b/libio/strops.c index 193e39d..f48f218 100644 --- a/libio/strops.c +++ b/libio/strops.c @@ -205,7 +205,10 @@ _IO_str_count (fp) - fp->_IO_read_base); } -_IO_pos_t +// Changed 2001-04-05 Andreas Wolff +// Avoid conflicting types with libioP.h +// This may be obsolete for future versions of libio +_IO_off_t _IO_str_seekoff (fp, offset, dir, mode) _IO_FILE *fp; _IO_off_t offset;