mirror of
https://frontier.innolan.net/github/amigaos-cross-toolchain6.git
synced 2024-10-19 10:29:55 +00:00
Get rid of MorphOS support.
This commit is contained in:
@@ -177,7 +177,7 @@
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
@@ -59,68 +180,82 @@
|
||||
@@ -59,68 +180,79 @@
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
@@ -283,9 +283,6 @@
|
||||
*:[Aa]miga[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-amigaos
|
||||
exit 0 ;;
|
||||
+ *:MorphOS:*:*)
|
||||
+ echo ${UNAME_MACHINE}-unknown-morphos
|
||||
+ exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
|
||||
@@ -540,7 +540,7 @@
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
@@ -548,24 +616,36 @@
|
||||
@@ -548,24 +616,32 @@
|
||||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
@@ -555,10 +555,6 @@
|
||||
;;
|
||||
- msdos) # EGCS LOCAL
|
||||
- basic_machine=i386-unknown
|
||||
+ morphos)
|
||||
+ basic_machine=powerpc-unknown
|
||||
+ os=-morphos
|
||||
+ ;;
|
||||
+ msdos)
|
||||
+ basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@@ -850,7 +846,7 @@
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
- | -aos* \
|
||||
+ | -amigaos* | -amigados* | -morphos* \
|
||||
+ | -amigaos* | -amigados* \
|
||||
+ | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* Windows does not natively support inodes, and neither does MSDOS. */
|
||||
#if (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)) \
|
||||
- || defined (__MSDOS__)
|
||||
+ || defined (__MSDOS__) || defined (__amigaos__) || defined (__morphos__)
|
||||
+ || defined (__MSDOS__) || defined (__amigaos__)
|
||||
#define INO_T_EQ(a, b) 0
|
||||
#endif
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
return to - filename;
|
||||
}
|
||||
}
|
||||
+#if !defined (__amigaos__) && !defined (__morphos__) /* Don't convert ':' on Amiga! */
|
||||
+#if !defined (__amigaos__) /* Don't convert ':' on Amiga! */
|
||||
#if defined(DIR_SEPARATOR_2)
|
||||
/* Simplify to one directory separator. */
|
||||
to[-1] = DIR_SEPARATOR;
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/* 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"
|
||||
|
||||
extern enum rs6000_sdata_type rs6000_sdata;
|
||||
|
||||
/* Common routine used to check if r13 should be preserved/restored. */
|
||||
|
||||
int
|
||||
morphos_restore_r13 ()
|
||||
{
|
||||
return ((rs6000_sdata == SDATA_BREL || rs6000_sdata == SDATA_DATA) &&
|
||||
(TARGET_RESTORE_R13 || TARGET_ALWAYS_RESTORE_R13
|
||||
|| lookup_attribute ("saveds",
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))));
|
||||
}
|
||||
|
||||
/* 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
|
||||
morphos_valid_type_attribute_p (type, attributes, identifier, args)
|
||||
tree type, attributes, identifier, args;
|
||||
{
|
||||
if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
|
||||
{
|
||||
if (is_attribute_p ("stackext", identifier) ||
|
||||
is_attribute_p ("saveds", identifier) ||
|
||||
is_attribute_p ("varargs68k", identifier))
|
||||
return 1;
|
||||
}
|
||||
return rs6000_valid_type_attribute_p (type, attributes, identifier, args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* stack check/extension code */
|
||||
|
||||
void morphos_output_prolog(file, size)
|
||||
FILE *file;
|
||||
int size;
|
||||
{
|
||||
if (TARGET_STACKCHECK || TARGET_STACKEXTEND)
|
||||
asm_fprintf(file, "\tmflr 0\n\tbl __stk%s1\n",
|
||||
TARGET_STACKEXTEND ? "ext" : "chk");
|
||||
output_prolog(file, size);
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
|
||||
For incoming args we set the number of arguments in the prototype large
|
||||
so we never return a PARALLEL. */
|
||||
|
||||
void
|
||||
morphos_init_cumulative_args (cum, fntype, libname, incoming)
|
||||
CUMULATIVE_ARGS *cum;
|
||||
tree fntype;
|
||||
rtx libname ATTRIBUTE_UNUSED;
|
||||
int incoming;
|
||||
{
|
||||
init_cumulative_args (cum, fntype, libname, incoming);
|
||||
if (fntype && lookup_attribute ("varargs68k", TYPE_ATTRIBUTES (fntype)))
|
||||
cum->call_cookie |= CALL_VARARGS68K;
|
||||
}
|
||||
|
||||
|
||||
/* Determine where to put an argument 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.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
|
||||
On RS/6000 the first eight words of non-FP are normally in registers
|
||||
and the rest are pushed. Under AIX, the first 13 FP args are in registers.
|
||||
Under V.4, the first 8 FP args are in registers.
|
||||
|
||||
If this is floating-point and no prototype is specified, we use
|
||||
both an FP and integer register (or possibly FP reg and stack). Library
|
||||
functions (when TYPE is zero) always have the proper types for args,
|
||||
so we can pass the FP value just in one register. emit_library_function
|
||||
doesn't support PARALLEL anyway. */
|
||||
|
||||
struct rtx_def *
|
||||
morphos_function_arg (cum, mode, type, named)
|
||||
CUMULATIVE_ARGS *cum;
|
||||
enum machine_mode mode;
|
||||
tree type;
|
||||
int named;
|
||||
{
|
||||
/* Return a marker to indicate whether CR1 needs to set or clear the bit
|
||||
that V.4 uses to say fp args were passed in registers. Assume that we
|
||||
don't need the marker for software floating point, or compiler generated
|
||||
library calls. */
|
||||
if (mode == VOIDmode && cum->call_cookie & CALL_VARARGS68K)
|
||||
return GEN_INT (cum->call_cookie);
|
||||
|
||||
return function_arg (cum, mode, type, named);
|
||||
}
|
||||
|
||||
|
||||
/* 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.) */
|
||||
|
||||
void
|
||||
morphos_function_arg_advance (cum, mode, type, named)
|
||||
CUMULATIVE_ARGS *cum;
|
||||
enum machine_mode mode;
|
||||
tree type;
|
||||
int named;
|
||||
{
|
||||
function_arg_advance(cum, mode, type, named);
|
||||
if (cum->call_cookie & CALL_VARARGS68K &&
|
||||
cum->sysv_gregno + cum->fregno - GP_ARG_MIN_REG - FP_ARG_MIN_REG > cum->orig_nargs)
|
||||
{
|
||||
cum->sysv_gregno = GP_ARG_MAX_REG + 1;
|
||||
cum->fregno = FP_ARG_V4_MAX_REG + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Perform any needed actions needed for a function that is receiving a
|
||||
variable number of arguments.
|
||||
|
||||
CUM is as above.
|
||||
|
||||
MODE and TYPE are the mode and type of the current parameter.
|
||||
|
||||
PRETEND_SIZE is a variable that should be set to the amount of stack
|
||||
that must be pushed by the prolog to pretend that our caller pushed
|
||||
it.
|
||||
|
||||
Normally, this macro will push all remaining incoming registers on the
|
||||
stack and set PRETEND_SIZE to the length of the registers pushed. */
|
||||
|
||||
void
|
||||
morphos_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
|
||||
CUMULATIVE_ARGS *cum;
|
||||
enum machine_mode mode;
|
||||
tree type;
|
||||
int *pretend_size;
|
||||
int no_rtl;
|
||||
|
||||
{
|
||||
CUMULATIVE_ARGS next_cum;
|
||||
int reg_size = TARGET_32BIT ? 4 : 8;
|
||||
rtx save_area;
|
||||
int first_reg_offset;
|
||||
tree fntype;
|
||||
int stdarg_p;
|
||||
|
||||
if (!(cum->call_cookie & CALL_VARARGS68K)) {
|
||||
setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl);
|
||||
return;
|
||||
}
|
||||
|
||||
fntype = TREE_TYPE (current_function_decl);
|
||||
stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
|
||||
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
|
||||
!= void_type_node));
|
||||
|
||||
/* For varargs, we do not want to skip the dummy va_dcl argument.
|
||||
For stdargs, we do want to skip the last named argument. */
|
||||
next_cum = *cum;
|
||||
if (stdarg_p)
|
||||
function_arg_advance (&next_cum, mode, type, 1);
|
||||
|
||||
/* Indicate to allocate space on the stack for varargs save area. */
|
||||
/* ??? Does this really have to be located at a magic spot on the
|
||||
stack, or can we allocate this with assign_stack_local instead. */
|
||||
rs6000_sysv_varargs_p = 1;
|
||||
if (! no_rtl)
|
||||
save_area = plus_constant (virtual_stack_vars_rtx,
|
||||
- RS6000_VARARGS_SIZE);
|
||||
|
||||
first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
|
||||
}
|
||||
|
||||
|
||||
/* If defined, is a C expression that produces the machine-specific
|
||||
code for a call to `__builtin_saveregs'. This code will be moved
|
||||
to the very beginning of the function, before any parameter access
|
||||
are made. The return value of this function should be an RTX that
|
||||
contains the value to use as the return of `__builtin_saveregs'.
|
||||
|
||||
The argument ARGS is a `tree_list' containing the arguments that
|
||||
were passed to `__builtin_saveregs'.
|
||||
|
||||
If this macro is not defined, the compiler will output an ordinary
|
||||
call to the library function `__builtin_saveregs'.
|
||||
|
||||
On the Power/PowerPC return the address of the area on the stack
|
||||
used to hold arguments. Under AIX, this includes the 8 word register
|
||||
save area.
|
||||
|
||||
Under V.4, things are more complicated. We do not have access to
|
||||
all of the virtual registers required for va_start to do its job,
|
||||
so we construct the va_list in its entirity here, and reduce va_start
|
||||
to a block copy. This is similar to the way we do things on Alpha. */
|
||||
|
||||
struct rtx_def *
|
||||
morphos_expand_builtin_saveregs (args)
|
||||
tree args ATTRIBUTE_UNUSED;
|
||||
{
|
||||
rtx block, mem_gpr_fpr, /*mem_reg_save_area, */mem_overflow, tmp;
|
||||
tree fntype;
|
||||
int stdarg_p;
|
||||
HOST_WIDE_INT words, gpr, bits;
|
||||
|
||||
if (!(current_function_args_info.call_cookie & CALL_VARARGS68K))
|
||||
return expand_builtin_saveregs (args);
|
||||
|
||||
fntype = TREE_TYPE (current_function_decl);
|
||||
stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
|
||||
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
|
||||
!= void_type_node));
|
||||
|
||||
/* Allocate the va_list constructor. */
|
||||
block = assign_stack_local (BLKmode, 3 * UNITS_PER_WORD, BITS_PER_WORD);
|
||||
RTX_UNCHANGING_P (block) = 1;
|
||||
RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
|
||||
|
||||
mem_gpr_fpr = change_address (block, word_mode, XEXP (block, 0));
|
||||
mem_overflow = change_address (block, ptr_mode,
|
||||
plus_constant (XEXP (block, 0),
|
||||
UNITS_PER_WORD));
|
||||
/*mem_reg_save_area = change_address (block, ptr_mode,
|
||||
plus_constant (XEXP (block, 0),
|
||||
2 * UNITS_PER_WORD));*/
|
||||
|
||||
/* Construct the two characters of `gpr' and `fpr' as a unit. */
|
||||
words = current_function_args_info.words;
|
||||
gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
|
||||
|
||||
/* Varargs has the va_dcl argument, but we don't count it. */
|
||||
if (!stdarg_p)
|
||||
{
|
||||
if (gpr > GP_ARG_NUM_REG)
|
||||
words -= 1;
|
||||
}
|
||||
|
||||
bits = (GP_ARG_MAX_REG - GP_ARG_MIN_REG + 1) << 8
|
||||
| (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1);
|
||||
if (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD)
|
||||
tmp = GEN_INT (bits << (BITS_PER_WORD - 16));
|
||||
else
|
||||
{
|
||||
bits <<= BITS_PER_WORD - HOST_BITS_PER_WIDE_INT - 16;
|
||||
tmp = immed_double_const (0, bits, word_mode);
|
||||
}
|
||||
|
||||
emit_move_insn (mem_gpr_fpr, tmp);
|
||||
|
||||
/* Find the overflow area. */
|
||||
tmp = expand_binop (Pmode, add_optab, virtual_incoming_args_rtx,
|
||||
GEN_INT (words * UNITS_PER_WORD),
|
||||
mem_overflow, 0, OPTAB_WIDEN);
|
||||
if (tmp != mem_overflow)
|
||||
emit_move_insn (mem_overflow, tmp);
|
||||
|
||||
/*tmp = expand_binop (Pmode, add_optab, virtual_stack_vars_rtx,
|
||||
GEN_INT (-RS6000_VARARGS_SIZE),
|
||||
mem_reg_save_area, 0, OPTAB_WIDEN);
|
||||
if (tmp != mem_reg_save_area)
|
||||
emit_move_insn (mem_reg_save_area, tmp);*/
|
||||
|
||||
/* Return the address of the va_list constructor. */
|
||||
return XEXP (block, 0);
|
||||
}
|
||||
|
||||
@@ -1,398 +0,0 @@
|
||||
/* Definitions of target machine for GNU compiler. Amiga powerpc version.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
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 "rs6000/sysv4.h"
|
||||
|
||||
/* Enable some special Amiga only features. FIXME: This define should
|
||||
be eliminated in favor of more general ways to enable the features. */
|
||||
|
||||
#define TARGET_MORPHOS 1
|
||||
|
||||
#undef PROCESSOR_DEFAULT
|
||||
#define PROCESSOR_DEFAULT PROCESSOR_PPC604e
|
||||
|
||||
#undef DEFAULT_ABI
|
||||
#define DEFAULT_ABI ABI_V4
|
||||
|
||||
/* Put jump tables in text section to suppress some relocations */
|
||||
#undef JUMP_TABLES_IN_TEXT_SECTION
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
||||
|
||||
extern enum rs6000_sdata_type rs6000_sdata;
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC \
|
||||
"%{!ansi:" \
|
||||
"%{!noixemul:-Dixemul} " \
|
||||
"%{noixemul:-Dlibnix}} " \
|
||||
"%{mcpu=603e:-D__603e__} " \
|
||||
"%{mcpu=604e:-D__604e__} " \
|
||||
"%{!noixemul:-D__ixemul__ -D__ixemul} " \
|
||||
"%{noixemul:-D__libnix__ -D__libnix} " \
|
||||
"%{malways-restore-r13:-Derrno=(*ixemul_errno)} " \
|
||||
"%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
|
||||
"%{mrestore-r13:-Derrno=(*ixemul_errno)} " \
|
||||
"%{mrestore-a4:-Derrno=(*ixemul_errno)} " \
|
||||
"%{msoft-float: -D_SOFT_FLOAT} "
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__PPC__ -D_CALL_SYSV -Damiga -Damigaos -DMCH_AMIGA -DAMIGA " \
|
||||
"-Asystem(morphos) --Acpu(powerpc) -Amachine(powerpc) " \
|
||||
"-D__MORPHOS__ -Dmorphos -D__powerpc__ " \
|
||||
"-D__saveds=__attribute__((__saveds__)) "\
|
||||
"-D__stackext=__attribute__((__stackext__)) " \
|
||||
|
||||
|
||||
/* Choose the right startup file, depending on whether we use base relative
|
||||
code, base relative code with automatic relocation (-resident), or plain
|
||||
crt0.o.
|
||||
|
||||
Profiling is currently only available for plain startup.
|
||||
mcrt0.o does not (yet) exist. */
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC \
|
||||
"%{!noixemul:" \
|
||||
"%{mbaserel:%{!mresident:bcrt0.o%s}}" \
|
||||
"%{mresident:rcrt0.o%s}" \
|
||||
"%{mbaserel32:%{!mresident32:lcrt0.o%s}}" \
|
||||
"%{mresident32:scrt0.o%s}" \
|
||||
"%{!mresident:%{!mbaserel:%{!mresident32:%{!mbaserel32:" \
|
||||
"%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}}" \
|
||||
"%{noixemul:libnix/startup.o%s} "
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
/*#define ENDFILE_SPEC \
|
||||
"%{noixemul:libnix/end.o%s} "*/
|
||||
|
||||
/* 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 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. */
|
||||
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC \
|
||||
"%{!noixemul:" \
|
||||
"%{!p:%{!pg:-lc -lamiga -lamigastubs -lc}}" \
|
||||
"%{p:-lc_p}%{pg:-lc_p}}" \
|
||||
"%{noixemul:-lc -lamiga -lamigastubs" \
|
||||
"%{mstackcheck:-lstack} " \
|
||||
"%{mstackextend:-lstack}} -lsyscall "
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC \
|
||||
"%{h*} %{v:-V} %{G*} %{Wl,*:%*} %{YP,*} %{R*} %{Qy:} %{!Qn:-Qy} " \
|
||||
"%{noixemul:-fl libnix} " \
|
||||
"%{mbaserel:%{!mresident:-m morphos_baserel -G 1000000 -fl libb}} " \
|
||||
"%{mresident:-m morphos_baserel -datadata-reloc -G 100000 -fl libb} " \
|
||||
"%{mbaserel32:%{!mresident32:-m morphos_baserel -fl libb32}} " \
|
||||
"%{mresident32:-m morphos_baserel -datadata-reloc -fl libb32} "
|
||||
|
||||
/* The place to find libc.a, libamiga.c and crt0.o depends on the runtime
|
||||
** environment being used. As usual, default to the ixemul environment.
|
||||
*/
|
||||
|
||||
/*#undef LINK_PATH_SPEC
|
||||
#define LINK_PATH_SPEC \
|
||||
"%{!runtime=*:ixemul%s} %{runtime=ixemul:ixemul%s} \
|
||||
%{runtime=libnix:libnix%s} %{runtime=librilc:librilc%s}"*/
|
||||
|
||||
/*#undef LINK_SYSCALL:
|
||||
#define LINK_SYSCALL "-lsyscall "*/
|
||||
|
||||
/* Translate '-resident' to '-fbaserel' (they differ in linking stage only).
|
||||
Don't put function addresses in registers for PC-relative code. */
|
||||
|
||||
#undef CC1_SPEC
|
||||
#define CC1_SPEC \
|
||||
"%{G*} " \
|
||||
"%{mbaserel:-msdata=sysv -G 100000} " \
|
||||
"%{mbaserel32:-msdata=baserel} " \
|
||||
"%{mresident:-msdata=sysv -G 100000} " \
|
||||
"%{mresident32:-msdata=baserel} "
|
||||
|
||||
/* Define the name of the runtime environment (libc, etc.) used so it can be
|
||||
tested for during compilation.
|
||||
Abuse (?) CPP_OS_DEFAULT_SPEC for this purpose. -rask */
|
||||
|
||||
/*#undef CPP_OS_DEFAULT_SPEC
|
||||
#define CPP_OS_DEFAULT_SPEC \
|
||||
"%{!runtime=*:-D__ixemul__} %{runtime=ixemul:-D__ixemul__} \
|
||||
%{runtime=libnix:-D__libnix__} %{runtime=librilc:-D__librilc__}"*/
|
||||
|
||||
#undef EXTRA_SPECS
|
||||
#undef MULTILIB_DEFAULTS
|
||||
|
||||
/* Compile with stack extension. */
|
||||
|
||||
#define MASK_STACKEXTEND 0x00800000
|
||||
#define TARGET_STACKEXTEND ((target_flags & MASK_STACKEXTEND) \
|
||||
|| lookup_attribute ("stackext", \
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
|
||||
|
||||
/* Compile with stack checking. */
|
||||
|
||||
#define MASK_STACKCHECK 0x00400000
|
||||
#define TARGET_STACKCHECK ((target_flags & MASK_STACKCHECK) \
|
||||
&& !(target_flags & MASK_STACKEXTEND) \
|
||||
&& !lookup_attribute ("stackext", \
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
|
||||
|
||||
/* Compile with r13 restoring in public functions. */
|
||||
|
||||
#define MASK_RESTORE_R13 0x00200000
|
||||
#define TARGET_RESTORE_R13 \
|
||||
((target_flags & MASK_RESTORE_R13) && TREE_PUBLIC (current_function_decl))
|
||||
|
||||
/* Compile with r13 restoring in all functions. */
|
||||
|
||||
#define MASK_ALWAYS_RESTORE_R13 0x00100000
|
||||
#define TARGET_ALWAYS_RESTORE_R13 (target_flags & MASK_ALWAYS_RESTORE_R13)
|
||||
|
||||
#undef EXTRA_SUBTARGET_SWITCHES
|
||||
#define EXTRA_SUBTARGET_SWITCHES \
|
||||
{ "baserel", 0, "16-bits relative data access"}, \
|
||||
{ "baserel32", 0, "32-bits relative data access"}, \
|
||||
{ "resident", 0, "make a reentrant executable with <= 64k data"}, \
|
||||
{ "resident32", 0, "make reentrant executable"}, \
|
||||
{ "stackcheck", MASK_STACKCHECK, "check for stack overflow"}, \
|
||||
{ "no-stackcheck", - MASK_STACKCHECK, "don't check for stack overflow"}, \
|
||||
{ "stackextend", MASK_STACKEXTEND, "automatically extend stack"}, \
|
||||
{ "no-stackextend", - MASK_STACKEXTEND, "don't extend stack"}, \
|
||||
{ "fixedstack", - (MASK_STACKCHECK|MASK_STACKEXTEND), "don't extend the stack" },\
|
||||
{ "restore-r13", MASK_RESTORE_R13}, \
|
||||
{ "no-restore-r13", - MASK_RESTORE_R13}, \
|
||||
{ "always-restore-r13", MASK_ALWAYS_RESTORE_R13}, \
|
||||
{ "no-always-restore-r13", - MASK_ALWAYS_RESTORE_R13}, \
|
||||
{ "restore-a4", MASK_RESTORE_R13}, \
|
||||
{ "no-restore-a4", - MASK_RESTORE_R13}, \
|
||||
{ "always-restore-a4", MASK_ALWAYS_RESTORE_R13}, \
|
||||
{ "no-always-restore-a4", - MASK_ALWAYS_RESTORE_R13},
|
||||
|
||||
|
||||
/* This macro generates the assembly code for function entry.
|
||||
FILE is a stdio stream to output the code to.
|
||||
SIZE is an int: how many units of temporary storage to allocate.
|
||||
Refer to the array `regs_ever_live' to determine which registers
|
||||
to save; `regs_ever_live[I]' is nonzero if register number I
|
||||
is ever used in the function. This macro is responsible for
|
||||
knowing which registers should not be saved even if used. */
|
||||
|
||||
#undef FUNCTION_PROLOGUE
|
||||
#define FUNCTION_PROLOGUE(FILE, SIZE) morphos_output_prolog (FILE, SIZE)
|
||||
|
||||
|
||||
/* This is (almost;-)) BSD, so it wants DBX format. */
|
||||
|
||||
#undef PREFERRED_DEBUGGING_TYPE
|
||||
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||
#define DBX_DEBUGGING_INFO
|
||||
#define DWARF_DEBUGGING_INFO
|
||||
|
||||
#if 0
|
||||
/* To maintain the binary compatibility with the m68k structures, we need
|
||||
to align 32-bit integers and pointers only to 16 bits in structures. */
|
||||
|
||||
#undef ADJUST_FIELD_ALIGN
|
||||
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
|
||||
(DECL_MODE (FIELD) != SImode ? (COMPUTED) : MIN ((COMPUTED), 16))
|
||||
#endif
|
||||
|
||||
/* Accesses to floats must be at least 4 bytes-aligned */
|
||||
#define GET_MIN_MODE_ALIGNMENT(mode) (mode == DImode || FLOAT_MODE_P(mode) ? 32 : 8)
|
||||
#define GET_MIN_TYPE_ALIGNMENT(type) (FLOAT_TYPE_P(type) ? 32 : 8)
|
||||
|
||||
/* Use sjlj exceptions until DWARF2 unwind info works */
|
||||
//#define DWARF2_UNWIND_INFO 0
|
||||
#undef DWARF2_UNWIND_INFO
|
||||
|
||||
/* If defined, 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, NAME, ARGS) \
|
||||
(morphos_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
|
||||
|
||||
#define EXTRA_STACK_INFO \
|
||||
if (morphos_restore_r13()) { \
|
||||
info_ptr->calls_p = 1; \
|
||||
info_ptr->lr_save_p = 1; \
|
||||
regs_ever_live[65] = 1; \
|
||||
if (info_ptr->first_gp_reg_save > 13) { \
|
||||
info_ptr->gp_size += reg_size; \
|
||||
if (info_ptr->first_gp_reg_save == 14) \
|
||||
--info_ptr->first_gp_reg_save; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EXTRA_PROLOG \
|
||||
if (morphos_restore_r13() && info->first_gp_reg_save > 14) \
|
||||
asm_fprintf (file, store_reg, \
|
||||
reg_names[13], \
|
||||
info->gp_save_offset + sp_offset + (32 - info->first_gp_reg_save) * reg_size, \
|
||||
reg_names[sp_reg]);
|
||||
|
||||
#define EXTRA_PROLOG_END \
|
||||
if (morphos_restore_r13()) \
|
||||
asm_fprintf (file, "\tbl __restore_r13\n");
|
||||
|
||||
#define EXTRA_EPILOG \
|
||||
if (morphos_restore_r13() && info->first_gp_reg_save > 14) \
|
||||
asm_fprintf (file, load_reg, \
|
||||
reg_names[13], \
|
||||
info->gp_save_offset + sp_offset + (32 - info->first_gp_reg_save) * info->reg_size, \
|
||||
reg_names[sp_reg]);
|
||||
|
||||
|
||||
#define CALL_VARARGS68K 0x80000000 /* Use 68k-style varargs */
|
||||
|
||||
|
||||
/* 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) \
|
||||
morphos_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE)
|
||||
|
||||
/* Similar, but when scanning the definition of a procedure. We always
|
||||
set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */
|
||||
|
||||
#undef INIT_CUMULATIVE_INCOMING_ARGS
|
||||
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
|
||||
morphos_init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE)
|
||||
|
||||
/* 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) \
|
||||
morphos_function_arg_advance (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Determine where to put an argument 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.
|
||||
NAMED is nonzero if this argument is a named parameter
|
||||
(otherwise it is an extra parameter matching an ellipsis).
|
||||
|
||||
On RS/6000 the first eight words of non-FP are normally in registers
|
||||
and the rest are pushed. The first 13 FP args are in registers.
|
||||
|
||||
If this is floating-point and no prototype is specified, we use
|
||||
both an FP and integer register (or possibly FP reg and stack). Library
|
||||
functions (when TYPE is zero) always have the proper types for args,
|
||||
so we can pass the FP value just in one register. emit_library_function
|
||||
doesn't support EXPR_LIST anyway. */
|
||||
|
||||
#undef FUNCTION_ARG
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
morphos_function_arg (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
/* Perform any needed actions needed for a function that is receiving a
|
||||
variable number of arguments.
|
||||
|
||||
CUM is as above.
|
||||
|
||||
MODE and TYPE are the mode and type of the current parameter.
|
||||
|
||||
PRETEND_SIZE is a variable that should be set to the amount of stack
|
||||
that must be pushed by the prolog to pretend that our caller pushed
|
||||
it.
|
||||
|
||||
Normally, this macro will push all remaining incoming registers on the
|
||||
stack and set PRETEND_SIZE to the length of the registers pushed. */
|
||||
|
||||
#undef SETUP_INCOMING_VARARGS
|
||||
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
|
||||
morphos_setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
|
||||
|
||||
/* If defined, is a C expression that produces the machine-specific
|
||||
code for a call to `__builtin_saveregs'. This code will be moved
|
||||
to the very beginning of the function, before any parameter access
|
||||
are made. The return value of this function should be an RTX that
|
||||
contains the value to use as the return of `__builtin_saveregs'.
|
||||
|
||||
The argument ARGS is a `tree_list' containing the arguments that
|
||||
were passed to `__builtin_saveregs'.
|
||||
|
||||
If this macro is not defined, the compiler will output an ordinary
|
||||
call to the library function `__builtin_saveregs'. */
|
||||
|
||||
#undef EXPAND_BUILTIN_SAVEREGS
|
||||
#define EXPAND_BUILTIN_SAVEREGS(ARGS) \
|
||||
morphos_expand_builtin_saveregs (ARGS)
|
||||
|
||||
|
||||
/* begin-GG-local: dynamic libraries */
|
||||
|
||||
/* This macro is used to check if all collect2 facilities should be used.
|
||||
We need a few special ones, like stripping after linking. */
|
||||
|
||||
#define DO_COLLECTING (do_collecting || morphos_do_collecting())
|
||||
|
||||
/* This macro is called in collect2 for every GCC argument name.
|
||||
ARG is a part of commandline (without '\0' at the end). */
|
||||
|
||||
#define COLLECT2_GCC_OPTIONS_HOOK(ARG) morphos_gccopts_hook(ARG)
|
||||
|
||||
/* This macro is called in collect2 for every ld's "-l" or "*.o" or "*.a"
|
||||
argument. ARG is a complete argument, with '\0' at the end. */
|
||||
|
||||
#define COLLECT2_LIBNAME_HOOK(ARG) morphos_libname_hook(ARG)
|
||||
|
||||
/* This macro is called at collect2 exit, to clean everything up. */
|
||||
|
||||
#define COLLECT2_EXTRA_CLEANUP morphos_collect2_cleanup
|
||||
|
||||
/* This macro is called just before the first linker invocation.
|
||||
LD1_ARGV is "char** argv", which will be passed to "ld". STRIP is an
|
||||
*address* of "strip_flag" variable. */
|
||||
|
||||
#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
|
||||
morphos_prelink_hook((LD1_ARGV), (STRIP))
|
||||
|
||||
/* This macro is called just after the first linker invocation, in place of
|
||||
"nm" and "ldd". OUTPUT_FILE is the executable's filename. */
|
||||
|
||||
#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) morphos_postlink_hook(OUTPUT_FILE)
|
||||
/* end-GG-local */
|
||||
|
||||
|
||||
extern void morphos_init_cumulative_args ();
|
||||
extern void morphos_function_arg_advance ();
|
||||
extern struct rtx_def *morphos_function_arg ();
|
||||
extern void morphos_setup_incoming_varargs ();
|
||||
extern struct rtx_def *morphos_expand_builtin_saveregs ();
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
--- gcc-2.95.3/gcc/config/rs6000/rs6000.c Thu Jan 25 15:03:34 2001
|
||||
+++ gcc/gcc/config/rs6000/rs6000.c Thu Sep 27 19:35:54 2001
|
||||
@@ -405,6 +405,7 @@
|
||||
case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
|
||||
case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
|
||||
case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
|
||||
+ case SDATA_BREL: fprintf (file, "%s -msdata=baserel", start); start = ""; break;
|
||||
}
|
||||
|
||||
if (rs6000_sdata && g_switch_value)
|
||||
@@ -1278,7 +1279,7 @@
|
||||
#if TARGET_ELF
|
||||
rtx sym_ref, const_part;
|
||||
|
||||
- if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
|
||||
+ if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA || rs6000_sdata == SDATA_BREL)
|
||||
return 0;
|
||||
|
||||
if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
|
||||
@@ -1317,6 +1318,44 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
+/* Return 1 for an operand in data memory on V.4/eabi */
|
||||
+
|
||||
+int
|
||||
+baserel_data_operand (op, mode)
|
||||
+ rtx op ATTRIBUTE_UNUSED;
|
||||
+ enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
+{
|
||||
+#if TARGET_ELF
|
||||
+ rtx sym_ref, const_part;
|
||||
+
|
||||
+ if (rs6000_sdata != SDATA_BREL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (GET_CODE (op) == SYMBOL_REF)
|
||||
+ sym_ref = op;
|
||||
+
|
||||
+ else if (GET_CODE (op) != CONST
|
||||
+ || GET_CODE (XEXP (op, 0)) != PLUS
|
||||
+ || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
|
||||
+ || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
|
||||
+ return 0;
|
||||
+
|
||||
+ else
|
||||
+ sym_ref = XEXP (XEXP (op, 0), 0);
|
||||
+
|
||||
+ if (*XSTR (sym_ref, 0) != '@')
|
||||
+ return 0;
|
||||
+
|
||||
+ return 1;
|
||||
+
|
||||
+#else
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
@@ -3388,6 +3427,9 @@
|
||||
&& GET_CODE (XEXP (x, 0)) == REG && CONSTANT_P (XEXP (x, 1)))
|
||||
{
|
||||
output_addr_const (file, XEXP (x, 1));
|
||||
+ if (baserel_data_operand(XEXP (x, 1)))
|
||||
+ fprintf (file, "@drell(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
|
||||
+ else
|
||||
fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
|
||||
}
|
||||
else
|
||||
@@ -3739,6 +3781,10 @@
|
||||
+ info_ptr->toc_size
|
||||
+ info_ptr->main_size, 8);
|
||||
|
||||
+#ifdef EXTRA_STACK_INFO
|
||||
+ EXTRA_STACK_INFO
|
||||
+#endif
|
||||
+
|
||||
/* Calculate the offsets */
|
||||
switch (abi)
|
||||
{
|
||||
@@ -4265,6 +4311,10 @@
|
||||
asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
|
||||
}
|
||||
|
||||
+#ifdef EXTRA_PROLOG
|
||||
+ EXTRA_PROLOG
|
||||
+#endif
|
||||
+
|
||||
/* NT needs us to probe the stack frame every 4k pages for large frames, so
|
||||
do it here. */
|
||||
if (DEFAULT_ABI == ABI_NT && info->total_size > 4096)
|
||||
@@ -4377,6 +4427,10 @@
|
||||
rs6000_output_load_toc_table (file, 30);
|
||||
}
|
||||
|
||||
+#ifdef EXTRA_PROLOG_END
|
||||
+ EXTRA_PROLOG_END
|
||||
+#endif
|
||||
+
|
||||
if (DEFAULT_ABI == ABI_NT)
|
||||
{
|
||||
assemble_name (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
|
||||
@@ -4437,6 +4491,10 @@
|
||||
if (info->lr_save_p)
|
||||
asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
|
||||
|
||||
+#ifdef EXTRA_EPILOG
|
||||
+ EXTRA_EPILOG
|
||||
+#endif
|
||||
+
|
||||
/* Restore gpr's. */
|
||||
if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
|
||||
{
|
||||
@@ -5858,7 +5916,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (rs6000_sdata != SDATA_NONE && (size > 0) && (size <= g_switch_value))
|
||||
+ if (rs6000_sdata != SDATA_NONE && rs6000_sdata != SDATA_BREL && (size > 0) && (size <= g_switch_value))
|
||||
{
|
||||
if (rs6000_sdata == SDATA_EABI)
|
||||
sdata2_section ();
|
||||
@@ -5924,9 +5982,16 @@
|
||||
abort ();
|
||||
}
|
||||
|
||||
- if ((size > 0 && size <= g_switch_value)
|
||||
+ if ((!name
|
||||
+ && (!TREE_READONLY (decl) || TREE_THIS_VOLATILE(decl))
|
||||
+ && (g_switch_value > 0xffff || (size > 0 && size <= g_switch_value)
|
||||
+ || rs6000_sdata == SDATA_BREL))
|
||||
|| (name
|
||||
- && ((len == sizeof (".sdata")-1 && strcmp (name, ".sdata") == 0)
|
||||
+ && ((rs6000_sdata == SDATA_BREL
|
||||
+ && ((len == sizeof (".data") && strcmp (name, ".data") == 0)
|
||||
+ || (len == sizeof (".data1") && strcmp (name, ".data1") == 0)
|
||||
+ || (len == sizeof (".bss") && strcmp (name, ".bss") == 0)))
|
||||
+ || (len == sizeof (".sdata")-1 && strcmp (name, ".sdata") == 0)
|
||||
|| (len == sizeof (".sdata2")-1 && strcmp (name, ".sdata2") == 0)
|
||||
|| (len == sizeof (".sbss")-1 && strcmp (name, ".sbss") == 0)
|
||||
|| (len == sizeof (".sbss2")-1 && strcmp (name, ".sbss2") == 0)
|
||||
@@ -1,10 +0,0 @@
|
||||
--- gcc-2.95.3/gcc/config/rs6000/rs6000.h Wed Mar 22 19:54:05 2000
|
||||
+++ gcc/gcc/config/rs6000/rs6000.h Thu Sep 27 19:35:54 2001
|
||||
@@ -3276,6 +3276,7 @@
|
||||
extern int current_file_function_operand ();
|
||||
extern int input_operand ();
|
||||
extern int small_data_operand ();
|
||||
+extern int baserel_data_operand ();
|
||||
extern void init_cumulative_args ();
|
||||
extern void function_arg_advance ();
|
||||
extern int function_arg_boundary ();
|
||||
@@ -1,49 +0,0 @@
|
||||
--- gcc-2.95.3/gcc/config/rs6000/rs6000.md Thu Jan 25 15:03:35 2001
|
||||
+++ gcc/gcc/config/rs6000/rs6000.md Thu Sep 27 19:35:54 2001
|
||||
@@ -5828,14 +5828,18 @@
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=b")
|
||||
(high:SI (match_operand 1 "" "")))]
|
||||
"TARGET_ELF && ! TARGET_64BIT"
|
||||
- "{liu|lis} %0,%1@ha")
|
||||
+ "*
|
||||
+ return (baserel_data_operand(operands[1]) ?
|
||||
+ \"{addiu|addis} %0,13,%1@drelha\" : \"{liu|lis} %0,%1@ha\");")
|
||||
|
||||
(define_insn "elf_low"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
|
||||
(match_operand 2 "" "")))]
|
||||
"TARGET_ELF && ! TARGET_64BIT"
|
||||
- "{cal|la} %0,%2@l(%1)")
|
||||
+ "*
|
||||
+ return (baserel_data_operand(operands[2]) ?
|
||||
+ \"{cal|la} %0,%2@drell(%1)\" : \"{cal|la} %0,%2@l(%1)\");")
|
||||
|
||||
;; Set up a register with a value from the GOT table
|
||||
|
||||
@@ -7742,10 +7746,24 @@
|
||||
|
||||
emit_move_insn (chain, stack_bot);
|
||||
|
||||
+ /* Under MorphOS, we may have to check/extend the stack. Do it via a
|
||||
+ call to an external function. */
|
||||
+ if (TARGET_MORPHOS && target_flags & (MASK_STACKCHECK | MASK_STACKEXTEND))
|
||||
+ {
|
||||
+ rtx tmp = gen_reg_rtx (Pmode);
|
||||
+ emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode,
|
||||
+ target_flags & MASK_STACKEXTEND ?
|
||||
+ \"__alloc_stk_ext\" : \"__alloc_stk_chk\"),
|
||||
+ tmp, 0, Pmode, 1, operands[1], Pmode);
|
||||
+ emit_insn (gen_set_sp (tmp));
|
||||
+ /*emit_move_insn (operands[0], tmp);*/
|
||||
+ emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
|
||||
+ DONE;
|
||||
+ }
|
||||
/* Under Windows NT, we need to add stack probes for large/variable
|
||||
allocations, so do it via a call to the external function alloca
|
||||
instead of doing it inline. */
|
||||
- if (DEFAULT_ABI == ABI_NT
|
||||
+ else if (DEFAULT_ABI == ABI_NT
|
||||
&& (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 4096))
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (Pmode);
|
||||
@@ -1,21 +0,0 @@
|
||||
--- gcc-2.95.3/gcc/config/rs6000/sysv4.h Thu Jan 25 15:03:37 2001
|
||||
+++ gcc/gcc/config/rs6000/sysv4.h Thu Sep 27 19:35:54 2001
|
||||
@@ -24,7 +24,8 @@
|
||||
SDATA_NONE, /* no small data support */
|
||||
SDATA_DATA, /* just put data in .sbss/.sdata, don't use relocs */
|
||||
SDATA_SYSV, /* Use r13 to point to .sdata/.sbss */
|
||||
- SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2 */
|
||||
+ SDATA_EABI, /* Use r13 like above, r2 points to .sdata2/.sbss2 */
|
||||
+ SDATA_BREL /* Use r13 to point to .data/.sdata/.sbss/.bss */
|
||||
};
|
||||
|
||||
extern enum rs6000_sdata_type rs6000_sdata;
|
||||
@@ -181,6 +182,8 @@
|
||||
rs6000_sdata = SDATA_SYSV; \
|
||||
else if (!strcmp (rs6000_sdata_name, "eabi")) \
|
||||
rs6000_sdata = SDATA_EABI; \
|
||||
+ else if (!strcmp (rs6000_sdata_name, "baserel")) \
|
||||
+ rs6000_sdata = SDATA_BREL; \
|
||||
else \
|
||||
error ("Bad value for -msdata=%s", rs6000_sdata_name); \
|
||||
} \
|
||||
@@ -1,63 +0,0 @@
|
||||
# Makefile fragment for MorphOS target.
|
||||
|
||||
# Do not build libgcc1.
|
||||
LIBGCC1 =
|
||||
CROSS_LIBGCC1 =
|
||||
#LIBGCC1_TEST =
|
||||
|
||||
# These are really part of libgcc1, but this will cause them to be
|
||||
# built correctly, so... [taken from t-sparclite]
|
||||
LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
|
||||
|
||||
# Extra object for cc1
|
||||
morphos.o: $(srcdir)/config/rs6000/morphos.c $(CONFIG_H)
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
dp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c > dp-bit.c
|
||||
|
||||
fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
# Build libgcc.a with different options.
|
||||
|
||||
MULTILIB_OPTIONS = mbaserel32
|
||||
|
||||
MULTILIB_DIRNAMES = libb32
|
||||
|
||||
MULTILIB_MATCHES = mbaserel32=mresident32 \
|
||||
mbaserel32=msdata=baserel
|
||||
|
||||
#LIBGCC = stmp-multilib
|
||||
#LIBGCC =
|
||||
#INSTALL_LIBGCC = install-multilib
|
||||
#INSTALL_LIBGCC =
|
||||
|
||||
# Each compilation environment (Dice, GCC, SAS/C, vbcc, 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
|
||||
OTHER_FIXINCLUDES_DIRS = GG:os-include
|
||||
|
||||
# Try to make it possible to build libgcc.a without an existing libc and
|
||||
# related include files (the default runtime of ixemul needs machine/ansi.h
|
||||
# to compile). This is useful since libc for this target isn't quite ready
|
||||
# yet. -rask
|
||||
|
||||
TARGET_LIBGCC2_CFLAGS = -mfixedstack #-Dinhibit_libc
|
||||
STMP_FIXPROTO =
|
||||
|
||||
### begin-GG-local: dynamic libraries
|
||||
# Extra objects that get compiled and linked to collect2
|
||||
|
||||
EXTRA_COLLECT2_OBJS = morphoscollect2.o
|
||||
|
||||
# Build supplimentary MorphOS target support file for collect2
|
||||
morphoscollect2.o: morphoscollect2.c
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||
-DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $(srcdir)/morphoscollect2.c
|
||||
### end-GG-local
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# Note: It doesn't do any good to try to define prefix or local_prefix
|
||||
# in the host overrides because configure will just change them back.
|
||||
# You either have to give an appropriate option to configure or live with
|
||||
# an Amiga specific patch to configure. See the note in configure. -fnf
|
||||
|
||||
# Building under AmigaOS almost certainly requires an already working gcc.
|
||||
# To bootstrap without "-pipe" do "make PIPE=".
|
||||
|
||||
CC = gcc $(PIPE)
|
||||
|
||||
# Disable -pipe for now since I had problems bootstrapping gcc 2.5.5 with
|
||||
# it. (fnf)
|
||||
#PIPE = -pipe
|
||||
|
||||
# Allow the user to override the default host optimization with gcc, or if the
|
||||
# host compiler is not gcc and doesn't understand -O<N>.
|
||||
|
||||
X_OPTIMIZE = -O2
|
||||
|
||||
# The standard additional host flags for the compiler.
|
||||
|
||||
X_CFLAGS = $(X_OPTIMIZE) -mstackextend
|
||||
|
||||
# Man pages get a wierd suffix...
|
||||
|
||||
manext = .0
|
||||
|
||||
# We really shouldn't specify CFLAGS from here, but there's no other way
|
||||
# to get rid of the `-g' indoctrinated by Makefile.in. Note this becomes
|
||||
# part of both the host compilation CFLAGS and the target compilation
|
||||
# CFLAGS.
|
||||
|
||||
CFLAGS =
|
||||
|
||||
# Ranlib does exist, but may not be in a path where the default RANLIB_TEST
|
||||
# expects it, so just force it to true.
|
||||
|
||||
RANLIB_TEST = true
|
||||
@@ -1,255 +0,0 @@
|
||||
/* Configuration for GNU C-compiler for Commodore Amiga, running AmigaOS.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
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 "rs6000/xm-sysv4.h"
|
||||
|
||||
/* Define various things that the Amiga host has. */
|
||||
|
||||
#undef HAVE_VPRINTF
|
||||
#define HAVE_VPRINTF
|
||||
#undef HAVE_PUTENV
|
||||
#define HAVE_PUTENV
|
||||
#undef HAVE_STRERROR
|
||||
#define HAVE_STRERROR
|
||||
#undef HAVE_ATEXIT
|
||||
#define HAVE_ATEXIT
|
||||
#undef HAVE_RENAME
|
||||
#define HAVE_RENAME
|
||||
|
||||
/* Amiga specific headers, such as from the Native Developer Update kits,
|
||||
go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of
|
||||
Unix "/usr/include". All other include paths are set in Makefile. */
|
||||
|
||||
#define SYSTEM_INCLUDE_DIR "GG:os-include"
|
||||
#define STANDARD_INCLUDE_DIR "GG:include"
|
||||
|
||||
#define STANDARD_EXEC_PREFIX "/gg/lib/gcc-lib/"
|
||||
#define STANDARD_EXEC_PREFIX_1 "/gg/lib/gcc/"
|
||||
#define STANDARD_STARTFILE_PREFIX "/gg/lib/"
|
||||
#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/"
|
||||
#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/"
|
||||
#define TOOLDIR_BASE_PREFIX "/gg/"
|
||||
|
||||
/* The AmigaOS stores file names with regard to upper/lower case, but actions
|
||||
on existing files are case independent on the standard filesystems.
|
||||
|
||||
A good example of where this causes problems is the conflict between the C
|
||||
include file <string.h> and the C++ include file <String.h>, where the C++
|
||||
include file dir is searched first and thus causes includes of <string.h>
|
||||
to include <String.h> instead.
|
||||
|
||||
In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as
|
||||
the name of the function that takes the same args as open() and does case
|
||||
dependent opens. */
|
||||
|
||||
#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE))
|
||||
|
||||
/* On the Amiga, there are two pathname separators, '/' (DIR_SEPARATOR)
|
||||
and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct
|
||||
character, so we don't have to explicitly set it. */
|
||||
|
||||
#define DIR_SEPARATOR '/'
|
||||
#define VOL_SEPARATOR ':'
|
||||
#define DIR_SEPARATOR_2 VOL_SEPARATOR
|
||||
|
||||
/* Determine whether a '\0'-terminated file name is absolute or not.
|
||||
|
||||
This checks for both, '/' as the first character, since we're running under
|
||||
ixemul.library which provides for this unix'ism, and for the usual
|
||||
logical-terminator, ':', somewhere in the filename. */
|
||||
|
||||
#define FILE_NAME_ABSOLUTE_P(NAME) ((NAME)[0] == '/' || index ((NAME), ':'))
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
/* Fork one piped subcommand. SEARCH_FLAG is the system call to use
|
||||
(either execv or execvp). ARGV is the arg vector to use.
|
||||
NOT_LAST is nonzero if this is not the last subcommand
|
||||
(i.e. its output should be piped to the next one.) */
|
||||
|
||||
#define PEXECUTE(SEARCH_FLAG,PROGRAM,ARGV,NOT_LAST) \
|
||||
({int (*_func)() = (SEARCH_FLAG ? execv : execvp); \
|
||||
int _pid; \
|
||||
int _pdes[2]; \
|
||||
int _input_desc = last_pipe_input; \
|
||||
int _output_desc = STDOUT_FILE_NO; \
|
||||
int _retries, _sleep_interval, _result; \
|
||||
\
|
||||
/* If this isn't the last process, make a pipe for its output, \
|
||||
and record it as waiting to be the input to the next process. */ \
|
||||
\
|
||||
if (NOT_LAST) \
|
||||
{ \
|
||||
if (pipe (_pdes) < 0) \
|
||||
pfatal_with_name ("pipe"); \
|
||||
_output_desc = _pdes[WRITE_PORT]; \
|
||||
last_pipe_input = _pdes[READ_PORT]; \
|
||||
} \
|
||||
else \
|
||||
last_pipe_input = STDIN_FILE_NO; \
|
||||
\
|
||||
/* Fork a subprocess; wait and retry if it fails. */ \
|
||||
_sleep_interval = 1; \
|
||||
for (_retries = 0; _retries < 4; _retries++) \
|
||||
{ \
|
||||
_pid = vfork (); \
|
||||
if (_pid >= 0) \
|
||||
break; \
|
||||
sleep (_sleep_interval); \
|
||||
_sleep_interval *= 2; \
|
||||
} \
|
||||
\
|
||||
switch (_pid) \
|
||||
{ \
|
||||
case -1: \
|
||||
pfatal_with_name ("vfork"); \
|
||||
/* NOTREACHED */ \
|
||||
_result = 0; \
|
||||
break; \
|
||||
\
|
||||
case 0: /* child */ \
|
||||
/* Move the input and output pipes into place, if nec. */ \
|
||||
if (_input_desc != STDIN_FILE_NO) \
|
||||
{ \
|
||||
close (STDIN_FILE_NO); \
|
||||
dup (_input_desc); \
|
||||
close (_input_desc); \
|
||||
} \
|
||||
if (_output_desc != STDOUT_FILE_NO) \
|
||||
{ \
|
||||
close (STDOUT_FILE_NO); \
|
||||
dup (_output_desc); \
|
||||
close (_output_desc); \
|
||||
} \
|
||||
\
|
||||
/* Close the parent's descs that aren't wanted here. */ \
|
||||
if (last_pipe_input != STDIN_FILE_NO) \
|
||||
close (last_pipe_input); \
|
||||
\
|
||||
/* Exec the program. */ \
|
||||
(*_func) (PROGRAM, ARGV); \
|
||||
perror_exec (PROGRAM); \
|
||||
exit (-1); \
|
||||
/* NOTREACHED */ \
|
||||
_result = 0; \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
/* In the parent, after forking. \
|
||||
Close the descriptors that we made for this child. */ \
|
||||
if (_input_desc != STDIN_FILE_NO) \
|
||||
close (_input_desc); \
|
||||
if (_output_desc != STDOUT_FILE_NO) \
|
||||
close (_output_desc); \
|
||||
\
|
||||
/* Return child's process number. */ \
|
||||
_result = _pid; \
|
||||
break; \
|
||||
} \
|
||||
_result; }) \
|
||||
|
||||
#define PEXECUTE_RESULT(STATUS, COMMAND) \
|
||||
({ wait (& STATUS); })
|
||||
|
||||
/* the following macros are stolen more or less from xm-vms.h ... */
|
||||
|
||||
/* This macro is used to help compare filenames in cp-lex.c.
|
||||
|
||||
We also need to make sure that the names are all lower case, because
|
||||
we must be able to compare filenames to determine if a file implements
|
||||
a class. */
|
||||
|
||||
#define FILE_NAME_NONDIRECTORY(C) \
|
||||
({ \
|
||||
extern char *rindex(); \
|
||||
char * pnt_ = (C), * pnt1_; \
|
||||
pnt1_ = pnt_ - 1; \
|
||||
while (*++pnt1_) \
|
||||
if ((*pnt1_ >= 'A' && *pnt1_ <= 'Z')) *pnt1_ |= 0x20; \
|
||||
pnt1_ = rindex (pnt_, '/'); \
|
||||
pnt1_ = (pnt1_ == 0 ? rindex (pnt_, ':') : pnt1_); \
|
||||
(pnt1_ == 0 ? pnt_ : pnt1_ + 1); \
|
||||
})
|
||||
|
||||
/* Macro to generate the name of the cross reference file. The standard
|
||||
one does not work, since it was written assuming that the conventions
|
||||
of a unix style filesystem will work on the host system.
|
||||
|
||||
Contrary to VMS, I'm using the original unix filename, there's no reason
|
||||
not to use this under AmigaOS. */
|
||||
|
||||
#define XREF_FILE_NAME(BUFF, NAME) \
|
||||
s = FILE_NAME_NONDIRECTORY (NAME); \
|
||||
if (s == NAME) sprintf(BUFF, ".%s.gxref", NAME); \
|
||||
else { \
|
||||
unsigned char ch = *s; /* could be Latin1 char.. */ \
|
||||
/* temporary: cut the filename from the directory */\
|
||||
*s = 0; \
|
||||
sprintf (BUFF, "%s.%c%s.gxref", NAME, ch, s+1); \
|
||||
/* and restore the filename */ \
|
||||
*s = ch; \
|
||||
} \
|
||||
|
||||
/* Macro that is used in cp-xref.c to determine whether a file name is
|
||||
absolute or not.
|
||||
|
||||
This checks for both, '/' as first character, since we're running under
|
||||
ixemul.library which provides for this unix'ism, and for the usual
|
||||
logical-terminator, ':', somewhere in the filename. */
|
||||
|
||||
#define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/' || index(NAME, ':'))
|
||||
|
||||
/* the colon conflicts with the name space of logicals */
|
||||
|
||||
#define PATH_SEPARATOR ','
|
||||
|
||||
/* Phil.B 17-Apr-95 Added stack checking code submitted by Kriton Kyrimis
|
||||
(kyrimis@theseas.ntua.gr) on 10-Feb-95, modified for inclusion into gcc
|
||||
|
||||
What stackcheck does is to add the following code at the beginning of
|
||||
each function:
|
||||
cmpl __StackBottom,sp
|
||||
bccs .+8
|
||||
jmp __StackOverflow
|
||||
|
||||
_StackBottom and _StackOverflow() are defined in stackchecksetup.c.
|
||||
_StackBottom is set to the bottom of the stack plus some leeway for
|
||||
subroutine arguments (128 bytes). _StackOverflow() sets the stack
|
||||
pointer to a sane value, prints an error message and exits.
|
||||
|
||||
Even with stack checking, you cannot be completely safe, as overflows
|
||||
are detected on function entry, rather than during function execution.
|
||||
E.g.,
|
||||
crash(){
|
||||
char scribble[100000];
|
||||
int i;
|
||||
for (i=0; i<100000; i++) scribble[i]=0;
|
||||
check(scribble);
|
||||
}
|
||||
check(char *x){}
|
||||
In the above example, stack overflow and its side-effects will occur in
|
||||
crash(), but it will be detected in check(), when it is too late. (The
|
||||
same thing happens with SAS/C's stack checking, BTW.)
|
||||
*/
|
||||
|
||||
/* #defined AMIGA_STACK_CHECKING */
|
||||
|
||||
#endif
|
||||
@@ -15,20 +15,3 @@
|
||||
m68k-*-coff*)
|
||||
tmake_file=m68k/t-m68kbare
|
||||
tm_file="m68k/m68k-coff.h dbx.h libgloss.h"
|
||||
@@ -5079,6 +6930,16 @@
|
||||
tmake_file=rs6000/t-beos
|
||||
xmake_file=rs6000/x-beos
|
||||
;;
|
||||
+ powerpc-*-morphos*)
|
||||
+ cpu_type=rs6000
|
||||
+ xm_file=rs6000/xm-morphos.h
|
||||
+ tm_file=rs6000/morphos.h
|
||||
+ tmake_file=rs6000/t-morphos
|
||||
+ xmake_file=rs6000/x-morphos
|
||||
+ extra_objs=morphos.o
|
||||
+ broken_install=cp
|
||||
+ install_headers_dir=install-headers-cp
|
||||
+ ;;
|
||||
powerpc-*-sysv* | powerpc-*-elf*)
|
||||
tm_file=rs6000/sysv4.h
|
||||
xm_file="xm-siglist.h rs6000/xm-sysv4.h"
|
||||
|
||||
@@ -15,20 +15,3 @@
|
||||
m68k-*-coff*)
|
||||
tmake_file=m68k/t-m68kbare
|
||||
tm_file="m68k/m68k-coff.h dbx.h libgloss.h"
|
||||
@@ -2763,6 +2790,16 @@
|
||||
tmake_file=rs6000/t-beos
|
||||
xmake_file=rs6000/x-beos
|
||||
;;
|
||||
+ powerpc-*-morphos*)
|
||||
+ cpu_type=rs6000
|
||||
+ xm_file=rs6000/xm-morphos.h
|
||||
+ tm_file=rs6000/morphos.h
|
||||
+ tmake_file=rs6000/t-morphos
|
||||
+ xmake_file=rs6000/x-morphos
|
||||
+ extra_objs=morphos.o
|
||||
+ broken_install=cp
|
||||
+ install_headers_dir=install-headers-cp
|
||||
+ ;;
|
||||
powerpc-*-sysv* | powerpc-*-elf*)
|
||||
tm_file=rs6000/sysv4.h
|
||||
xm_file="xm-siglist.h rs6000/xm-sysv4.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-#elif (defined _WIN32 && !defined CYGWIN && ! defined (_UWIN)) \
|
||||
- || defined __MSDOS__
|
||||
+#elif (defined (_WIN32) && !defined (CYGWIN) && ! defined (_UWIN)) \
|
||||
+ || defined (__MSDOS__) || defined (__amigaos__) || defined (__morphos__)
|
||||
+ || defined (__MSDOS__) || defined (__amigaos__)
|
||||
#define INO_T_EQ(a, b) 0
|
||||
#else
|
||||
#define INO_T_EQ(a, b) ((a) == (b))
|
||||
|
||||
@@ -1,344 +0,0 @@
|
||||
/* GG-local whole file: dynamic libraries */
|
||||
/* Supplimentary functions that get compiled and linked to collect2 for
|
||||
MorphOS target.
|
||||
Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
|
||||
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 <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* From collect2.c: */
|
||||
|
||||
void maybe_unlink(char *);
|
||||
char* xmalloc(unsigned);
|
||||
void fatal_perror(char *, ...);
|
||||
void fork_execute(char *, char **);
|
||||
void fatal(char*, ...);
|
||||
|
||||
extern char *c_file_name;
|
||||
extern int debug;
|
||||
|
||||
/* Names of temporary files we create. */
|
||||
#define XLIBS_C_NAME "xlibs.c"
|
||||
#define XLIBS_O_NAME "xlibs.o"
|
||||
#define SHARED_X_NAME "shared.x"
|
||||
|
||||
/* Suffix which is prepended to "-l" options for dynamic libraries. */
|
||||
#define DYNAMIC_LIB_SUFFIX "_ixlibrary"
|
||||
|
||||
/* Structure that holds library names. */
|
||||
struct liblist
|
||||
{
|
||||
struct liblist *next;
|
||||
char *name;
|
||||
char *cname;
|
||||
};
|
||||
|
||||
/* Not zero if "-static" was specified on GCC command line or if all the
|
||||
libraries are static. */
|
||||
static int flag_static=0;
|
||||
|
||||
/* Not zero if linking a base relative executable. This is recognized by
|
||||
presence of "-m amiga_bss" on the linker's commandline. */
|
||||
static int flag_baserel=0;
|
||||
|
||||
/* Not zero if some of the specified libraries are dynamic. */
|
||||
static int found_dynamic_libs=0;
|
||||
|
||||
/* List of linker libraries. */
|
||||
struct liblist *head = NULL;
|
||||
|
||||
/* Return 1 if collect2 should do something more apart from tlink. We want it
|
||||
to call "postlink" and "strip" if linking with dynamic libraries. */
|
||||
|
||||
int
|
||||
morphos_do_collecting(void)
|
||||
{
|
||||
return !flag_static;
|
||||
}
|
||||
|
||||
/* Check for presence of "-static" on the GCC command line. We should not do
|
||||
collecting if this flag was specified. */
|
||||
|
||||
void
|
||||
morphos_gccopts_hook(char* arg)
|
||||
{
|
||||
if (strncmp(arg, "-static", strlen("-static"))==0)
|
||||
flag_static=1;
|
||||
}
|
||||
|
||||
/* Replace unprintable characters with underscores. Used by "add_lib()". */
|
||||
|
||||
static void
|
||||
safename(char *p)
|
||||
{
|
||||
if (!isalpha(*p))
|
||||
*p = '_';
|
||||
p++;
|
||||
while (*p)
|
||||
{
|
||||
if (!isalnum(*p))
|
||||
*p = '_';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a library to the list of dynamic libraries. First make sure that the
|
||||
library is actually dynamic. Used by "amigaos_libname_hook()". */
|
||||
|
||||
static void
|
||||
add_lib(char *name)
|
||||
{
|
||||
struct liblist *lib;
|
||||
static char buf[256];
|
||||
|
||||
for (lib = head; lib; lib = lib->next)
|
||||
if (!strcmp(lib->name, name))
|
||||
return;
|
||||
|
||||
/* A2IXDIR_PREFIX is passed by "make". */
|
||||
sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", name);
|
||||
if (access(buf, R_OK))
|
||||
return;
|
||||
|
||||
lib = (struct liblist*)xmalloc(sizeof(struct liblist));
|
||||
lib->name = strdup(name);
|
||||
lib->cname = strdup(name);
|
||||
safename(lib->cname);
|
||||
lib->next = head;
|
||||
head = lib;
|
||||
|
||||
if (debug)
|
||||
fprintf(stderr, "found dynamic library, name: %s, cname: %s\n", lib->name,
|
||||
lib->cname);
|
||||
|
||||
found_dynamic_libs=1;
|
||||
}
|
||||
|
||||
/* Check if the argument is a linker library. Call "add_lib()" if yes. */
|
||||
|
||||
void
|
||||
morphos_libname_hook(char* arg)
|
||||
{
|
||||
int len = strlen(arg);
|
||||
if (flag_static)
|
||||
return;
|
||||
|
||||
if (len > 2 && !memcmp(arg, "-l", 2))
|
||||
add_lib(arg + 2);
|
||||
else if (len > 2 && !strcmp(arg + len - 2, ".a"))
|
||||
{
|
||||
char *lib;
|
||||
|
||||
arg[len - 2] = '\0';
|
||||
lib = strrchr(arg, '/');
|
||||
if (lib == NULL)
|
||||
lib = strrchr(arg, ':');
|
||||
if (lib == NULL)
|
||||
lib = arg - 1;
|
||||
if (!strncmp(lib + 1, "lib", 3))
|
||||
add_lib(lib + 4);
|
||||
arg[len - 2] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete temporary files. */
|
||||
|
||||
void
|
||||
morphos_collect2_cleanup(void)
|
||||
{
|
||||
if (flag_static)
|
||||
return;
|
||||
maybe_unlink(XLIBS_C_NAME);
|
||||
maybe_unlink(XLIBS_O_NAME);
|
||||
maybe_unlink(SHARED_X_NAME);
|
||||
}
|
||||
|
||||
/* Copy file named by FNAME to X. */
|
||||
|
||||
static void
|
||||
cat(char *fname, FILE *x)
|
||||
{
|
||||
#define BUFSIZE 16384
|
||||
FILE *in;
|
||||
static char buf[BUFSIZE];
|
||||
int bytes;
|
||||
|
||||
in = fopen(fname, "r");
|
||||
if (in == NULL)
|
||||
fatal_perror("%s", fname);
|
||||
while (!feof(in) && (bytes = fread(buf, 1, BUFSIZE, in)))
|
||||
fwrite(buf, 1, bytes, x);
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
/* If no dynamic libraries were found, perform like "-static". Otherwise,
|
||||
create "xlibs.c", "shared.x" and invoke "gcc" to create "xlibs.o". We also
|
||||
have to adjust the linker commandline. */
|
||||
|
||||
void
|
||||
morphos_prelink_hook(char** ld1_argv, int* strip_flag)
|
||||
{
|
||||
if (flag_static)
|
||||
return;
|
||||
|
||||
if (!found_dynamic_libs)
|
||||
{
|
||||
flag_static=1;
|
||||
/* If the user has not requested "-static", but has requested "-s",
|
||||
collect2 removes "-s" from the "ld1_argv", and calls "strip" after
|
||||
linking. However, this would not be efficient if we linked the
|
||||
executable without any dynamic library. In this case, we put "-s"
|
||||
back. */
|
||||
if (*strip_flag)
|
||||
{
|
||||
/* Add "-s" as the last argument on the command line. */
|
||||
while (*ld1_argv)
|
||||
ld1_argv++;
|
||||
*ld1_argv++="-s";
|
||||
*ld1_argv=0;
|
||||
*strip_flag=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *x, *out;
|
||||
struct liblist *lib;
|
||||
static char* argv[]={0, "-c", XLIBS_C_NAME, 0};
|
||||
char **ld1_end, **ld1;
|
||||
|
||||
/* Prepend suffixes to dynamic lib names. In addition, check if we are
|
||||
linking a base relative executable. */
|
||||
for (ld1=ld1_argv; *ld1; ld1++)
|
||||
{
|
||||
int len=strlen(*ld1);
|
||||
if (strncmp(*ld1, "-l", strlen("-l"))==0)
|
||||
{
|
||||
for (lib=head; lib; lib=lib->next)
|
||||
if (strcmp(*ld1+strlen("-l"), lib->name)==0)
|
||||
{
|
||||
char *newname=
|
||||
xmalloc(strlen(*ld1)+strlen(DYNAMIC_LIB_SUFFIX)+1);
|
||||
strcpy(newname, *ld1);
|
||||
strcat(newname, DYNAMIC_LIB_SUFFIX);
|
||||
*ld1=newname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (len > 2 && !strcmp(*ld1 + len - 2, ".a"))
|
||||
{
|
||||
char *libname;
|
||||
int substituted=0;
|
||||
|
||||
(*ld1)[len - 2] = '\0';
|
||||
libname = strrchr(*ld1, '/');
|
||||
if (libname == NULL)
|
||||
libname = strrchr(*ld1, ':');
|
||||
if (libname == NULL)
|
||||
libname = *ld1 - 1;
|
||||
if (!strncmp(libname + 1, "lib", 3))
|
||||
for (lib=head; lib; lib=lib->next)
|
||||
if (strcmp(libname+4, lib->name)==0)
|
||||
{
|
||||
char *newname=xmalloc(strlen(*ld1)+
|
||||
strlen(DYNAMIC_LIB_SUFFIX)+3);
|
||||
strcpy(newname, *ld1);
|
||||
strcat(newname, DYNAMIC_LIB_SUFFIX);
|
||||
strcat(newname, ".a");
|
||||
*ld1=newname;
|
||||
substituted=1;
|
||||
break;
|
||||
}
|
||||
if (!substituted)
|
||||
(*ld1)[len - 2] = '.';
|
||||
}
|
||||
else if (strcmp(ld1[0], "-m")==0 && ld1[1]
|
||||
&& strcmp(ld1[1], "morphos_baserel")==0)
|
||||
{
|
||||
flag_baserel=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out = fopen(XLIBS_C_NAME, "w");
|
||||
if (out == NULL)
|
||||
fatal_perror("%s", XLIBS_C_NAME);
|
||||
x = fopen(SHARED_X_NAME, "w");
|
||||
if (x == NULL)
|
||||
fatal_perror("%s", SHARED_X_NAME);
|
||||
|
||||
cat((flag_baserel ? A2IXDIR_PREFIX "/morphos_exe_baserel_script.x"
|
||||
: A2IXDIR_PREFIX "/morphos_exe_script.x"), x);
|
||||
for (lib = head; lib; lib = lib->next)
|
||||
{
|
||||
static char buf[256];
|
||||
sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", lib->name);
|
||||
fprintf(out, "extern long %sBase; long *__p%sBase = &%sBase;\n",
|
||||
lib->cname, lib->cname, lib->cname);
|
||||
cat(buf, x);
|
||||
} /* {{ */
|
||||
fprintf(x, "}}\n");
|
||||
fclose(out);
|
||||
fclose(x);
|
||||
argv[0]=c_file_name;
|
||||
fork_execute("gcc", argv);
|
||||
|
||||
/* Unfortunately, unlike "-s", "-T" cannot be specified as the last
|
||||
argument. We put it after "-L" args. */
|
||||
ld1_end=ld1_argv;
|
||||
while (*ld1_end)
|
||||
ld1_end++;
|
||||
ld1_end++;
|
||||
/* "ld1_end" now points after the terminating 0 of "ld1_argv". */
|
||||
|
||||
ld1=ld1_end-2;
|
||||
while (ld1>ld1_argv && strncmp(*ld1, "-L", strlen("-L")))
|
||||
ld1--;
|
||||
if (ld1==ld1_argv)
|
||||
fatal("no -L arguments");
|
||||
ld1++;
|
||||
/* "ld1" now points after "-L". */
|
||||
|
||||
/* Shift all the arguments after "-L" one position right. */
|
||||
memmove(ld1+1, ld1, (ld1_end-ld1)*sizeof(*ld1));
|
||||
/* Put -Tshared.x in the now empty space. */
|
||||
*ld1="-T" SHARED_X_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
/* Be lazy and just call "postlink". */
|
||||
|
||||
void
|
||||
morphos_postlink_hook(char* output_file)
|
||||
{
|
||||
static char* argv[]={"postlink", 0, 0, 0};
|
||||
if (flag_static)
|
||||
return;
|
||||
|
||||
if (flag_baserel)
|
||||
{
|
||||
argv[1]="-mbaserel";
|
||||
argv[2]=output_file;
|
||||
}
|
||||
else
|
||||
argv[1]=output_file;
|
||||
fork_execute("postlink", argv);
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
prefix = PREFIX;
|
||||
|
||||
/* Remove any trailing directory separator from what we got. */
|
||||
+#if defined (__amigaos__) || defined (__morphos__) /* Don't kill ':' on Amiga! */
|
||||
+#if defined (__amigaos__) /* Don't kill ':' on Amiga! */
|
||||
+ if (prefix[strlen (prefix) - 1] == DIR_SEPARATOR)
|
||||
+#else
|
||||
if (IS_DIR_SEPARATOR (prefix[strlen (prefix) - 1]))
|
||||
@@ -16,7 +16,7 @@
|
||||
path = translate_name (path);
|
||||
}
|
||||
|
||||
+#if !defined (__amigaos__) && !defined (__morphos__) /* Don't convert ':' on Amiga! */
|
||||
+#if !defined (__amigaos__) /* Don't convert ':' on Amiga! */
|
||||
#ifdef DIR_SEPARATOR_2
|
||||
/* Convert DIR_SEPARATOR_2 to DIR_SEPARATOR. */
|
||||
if (DIR_SEPARATOR != DIR_SEPARATOR_2)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
compile_file (filename);
|
||||
|
||||
-#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
|
||||
+#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX) && !defined (__amigaos__) && !defined (__morphos__)
|
||||
+#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX) && !defined (__amigaos__)
|
||||
if (flag_print_mem)
|
||||
{
|
||||
char *lim = (char *) sbrk (0);
|
||||
@@ -48,7 +48,7 @@
|
||||
#endif
|
||||
}
|
||||
-#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
|
||||
+#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX && ! __amigaos__ && ! __morphos__ */
|
||||
+#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX && ! __amigaos__ */
|
||||
|
||||
if (errorcount)
|
||||
exit (FATAL_EXIT_CODE);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN))
|
||||
#define DIR_SEPARATOR '\\'
|
||||
#endif
|
||||
+#if defined(__amigaos__) || defined(__morphos__)
|
||||
+#if defined(__amigaos__)
|
||||
+#define VOL_SEPARATOR ':'
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user