Initial revision

From-SVN: r11477
This commit is contained in:
Richard Kenner 1996-03-05 18:43:19 -05:00
parent 4991a34375
commit e22a31dae7
8 changed files with 659 additions and 0 deletions

207
gcc/config/m68k/a-ux.h Normal file
View File

@ -0,0 +1,207 @@
/* Definitions for Motorola 680x0 running A/UX
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. */
/*===================================================================*/
/* Execution environment */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT 7 /* 68020, 68881 */
#define CPP_PREDEFINES "-Dunix -Dm68k -DAUX -DmacII \
-Asystem(unix) -Asystem(AUX) -Acpu(m68k) -Amachine(m68k) -Amachine(macII)"
#define CPP_SPEC \
"%{!msoft-float:%{!ansi:-Dmc68881 }-D__HAVE_68881__ }\
-Acpu(mc68000) -D__mc68000__ %{!ansi:-Dmc68000 }\
%{!mc68000:%{!m68000:-Acpu(mc68020) -D__mc68020__ %{!ansi:-Dmc68020 }}}\
%{m68030:-Acpu(mc68030) -D__mc68030__ %{!ansi:-Dmc68030 }}\
%{m68040:-Acpu(mc68040) -D__mc68040__ %{!ansi:-Dmc68040 }}\
%{!ansi:%{!traditional:-D__STDC__=2 }}\
%{sbsd:-D_BSD_SOURCE -DBSD }%{ZB:-D_BSD_SOURCE -DBSD }\
%{ssysv:-D_SYSV_SOURCE -DSYSV -DUSG }%{ZS:-D_SYSV_SOURCE -DSYSV -DUSG }\
%{sposix:-D_POSIX_SOURCE -DPOSIX }%{ZP:-D_POSIX_SOURCE -DPOSIX }\
%{sposix+:-D_POSIX_SOURCE -DPOSIX }\
%{saux:-D_AUX_SOURCE }%{ZA:-D_AUX_SOURCE }\
%{!sbsd:%{!ZB:%{!ssysv:%{!ZS:%{!sposix:%{!ZP:%{!snone:\
-D_BSD_SOURCE -D_SYSV_SOURCE -D_AUX_SOURCE }}}}}}}"
#define LIB_SPEC \
"%{sbsd:-lbsd }%{ZB:-lbsd }\
%{ssysv:-lsvid }%{ZS:-lsvid }\
%{sposix:-lposix }%{ZP:-lposix }%{sposix+:-lposix }\
%{!static:%{smac:-lmac_s -lat -lld -lmr }-lc_s }\
%{static:%{smac:-lmac -lat -lld -lmr }-lc }"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{pg:mcrt0.o%s }%{!pg:%{p:mcrt1.o%s }\
%{!p:%{smac:maccrt1.o%s low.o%s }%{!smac:crt1.o%s }}}\
crt2.o%s "
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtn.o%s "
/*===================================================================*/
/* Compilation environment -- mostly */
#define NO_SYS_SIGLIST
/* We provide atexit(), A/UX does not have it */
#define HAVE_ATEXIT
/* Generate calls to memcpy, memcmp and memset, as opposed to bcopy, bcmp,
and bzero */
#define TARGET_MEM_FUNCTIONS
/* Provide support for pascal strings */
#define SUPPORT_PASCAL_STRINGS
/* Resize standard types */
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef WCHAR_TYPE
#define WCHAR_TYPE "unsigned int"
/* Every structure or union's size must be a multiple of 2 bytes. */
#define STRUCTURE_SIZE_BOUNDARY 16
/* Bits needed by collect */
#define OBJECT_FORMAT_COFF
#define MY_ISCOFF(m) ((m) == M68TVMAGIC || \
(m) == M68MAGIC || \
(m) == MC68TVMAGIC || \
(m) == MC68MAGIC || \
(m) == M68NSMAGIC)
#ifndef USE_COLLECT2
/* For .ctor/.dtor sections for collecting constructors */
/* We have special start/end files for defining [cd]tor lists */
#define CTOR_LISTS_DEFINED_EXTERNALLY
#endif
/*======================================================================*/
/* Calling convention and library support changes */
/* Define how to generate (in the callee) the output value of a function
and how to find (in the caller) the value returned by a function. VALTYPE
is the data type of the value (as a tree). If the precise function being
called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
For A/UX generate the result in d0, a0, or fp0 as appropriate. */
#undef FUNCTION_VALUE
#define FUNCTION_VALUE(VALTYPE, FUNC) \
(TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_68881 \
? gen_rtx (REG, TYPE_MODE (VALTYPE), 16) \
: (TREE_CODE (VALTYPE) == POINTER_TYPE \
? gen_rtx (REG, TYPE_MODE (VALTYPE), 8) \
: gen_rtx (REG, TYPE_MODE (VALTYPE), 0)))
#undef LIBCALL_VALUE
#define LIBCALL_VALUE(MODE) \
gen_rtx (REG, (MODE), ((TARGET_68881 && \
((MODE) == SFmode || (MODE) == DFmode)) ? 16 : 0))
/* 1 if N is a possible register number for a function value.
For A/UX allow d0, a0, or fp0 as return registers, for integral,
pointer, or floating types, respectively. Reject fp0 if not using a
68881 coprocessor. */
#undef FUNCTION_VALUE_REGNO_P
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == 0 || (N) == 8 || (TARGET_68881 && (N) == 16))
/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
more than one register. */
#undef NEEDS_UNTYPED_CALL
#define NEEDS_UNTYPED_CALL 1
/* For compatibility with the large body of existing code which does not
always properly declare external functions returning pointer types, the
A/UX convention is to copy the value returned for pointer functions
from a0 to d0 in the function epilogue, so that callers that have
neglected to properly declare the callee can still find the correct return
value. */
#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \
{ \
extern int current_function_returns_pointer; \
if ((current_function_returns_pointer) && \
! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \
asm_fprintf (FILE, "\t%s %Ra0,%Rd0\n", ASM_MOV_INSN); \
}
/* How to call the function profiler */
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
asm_fprintf (FILE, "\t%Olea %LLP%d,%Ra0\n\t%Ojbsr %s\n", \
(LABELNO), FUNCTION_PROFILER_SYMBOL)
/* Finalize the trampoline by flushing the insn cache */
#undef FINISH_INIT_TRAMPOLINE
#define FINISH_INIT_TRAMPOLINE(TRAMP) \
emit_library_call(gen_rtx(SYMBOL_REF, Pmode, "__clear_cache"), \
0, VOIDmode, 2, TRAMP, Pmode, \
plus_constant(TRAMP, TRAMPOLINE_SIZE), Pmode);
/* Clear the instruction cache from `beg' to `end'. This makes an
inline system call to SYS_sysm68k. The arguments are as follows:
sysm68k(105, addr, scope, cache, len)
105 - the subfunction code to clear the cache
addr - the start address for the flush
scope - the scope of the flush (see the cpush insn)
cache - which cache to flush (see the cpush insn)
len - a factor relating to the number of flushes to perform :
len/16 lines, or len/4096 pages.
While all this is only really relevant to 040's, the system call
will just return an error (which we ignore) on other systems. */
#define CLEAR_INSN_CACHE(beg, end) \
{ \
unsigned _beg = (unsigned)(beg), _end = (unsigned)(end); \
unsigned _len = ((_end / 16) - (_beg / 16) + 1) * 16; \
__asm __volatile( \
ASM_MOV_INSN " %1, %-\n\t" /* nr lines */ \
ASM_MOV_INSN " %#3, %-\n\t" /* insn+data caches */ \
ASM_MOV_INSN " %#1, %-\n\t" /* clear lines */ \
ASM_MOV_INSN " %0, %-\n\t" /* beginning of buffer */ \
ASM_MOV_INSN " %#105, %-\n\t" /* cache sub-function nr */ \
ASM_MOV_INSN " %#0, %-\n\t" /* dummy return address */ \
ASM_MOV_INSN " %#38, %/d0\n\t" /* system call nr */ \
"trap %#0\n\t" \
"add%.l %#24, %/sp" \
: /* no outputs */ \
: "g"(_beg), "g"(_len) \
: "%d0"); \
}

134
gcc/config/m68k/aux-crt1.c Normal file
View File

@ -0,0 +1,134 @@
/* Startup code for A/UX
Copyright (C) 1996 Free Software Foundation, Inc.
This file 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.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file with other programs, and to distribute
those programs without any restriction coming from the use of this
file. (The General Public License restrictions do apply in other
respects; for example, they cover modification of the file, and
distribution when not linked into another program.)
This file 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 this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* This file is compiled three times to produce crt1.o, mcrt1.o, and
maccrt1.o. The final two are created by defining MCRT1 and MACCRT1
respectively. */
#include <stdlib.h>
#ifdef MCRT1
#include <unistd.h>
#include <mon.h>
#endif
/* Extern function declarations */
extern void initfpu(void);
extern void __istart(void);
extern void __compatmode(void);
extern void _cleanup(void);
extern int main(int, char **, char **);
extern void exit(int) __attribute__((noreturn));
extern void _exit(int) __attribute__((noreturn));
#ifdef MACCRT1
extern void InitMac(void);
#endif
#ifdef MCRT1
static void monitor_start(void);
#endif
/* Global variables */
char **environ;
char *__splimit; /* address of top of stack */
/* Initialize system and run */
void _start() __attribute__((noreturn));
void _start()
{
register int *fp __asm__("%a6");
register char *d0 __asm__("%d0");
char **argv;
int argc;
__splimit = d0;
argc = fp[1];
argv = (char **)&fp[2];
environ = &argv[argc+1];
initfpu();
__istart();
__compatmode();
atexit(_cleanup);
#ifdef MCRT1
monitor_start();
#endif
#ifdef MACCRT1
InitMac();
#endif
exit(main(argc, argv, environ));
}
#ifdef MCRT1
/* Start/Stop program monitor */
extern void monitor(void *, void *, WORD *, int, int);
static WORD *monitor_buffer;
static void monitor_cleanup(void)
{
monitor(NULL, NULL, NULL, 0, 0);
free(monitor_buffer);
}
static void monitor_start(void)
{
extern int etext;
extern int stext __asm__(".text");
/* Choice of buffer size should be "no more than a few times
smaller than the program size" -- I don't believe that there
are any (useful) functions smaller than two insns (4 bytes)
so that is the scale factor used here */
int len = (&etext - &stext + 1) / 4;
monitor_buffer = (WORD *)calloc(len, sizeof(WORD));
if (monitor_buffer == NULL)
{
static const char msg[] = "mcrt1: could not allocate monitor buffer\n";
write(2, msg, sizeof(msg)-1);
_exit(-1);
}
/* I'm not sure why the count cap at 600 -- but that is what A/UX does */
monitor(&stext, &etext, monitor_buffer, len, 600);
atexit(monitor_cleanup);
}
#endif /* MCRT1 */

View File

@ -0,0 +1,42 @@
/* More startup code for A/UX */
#include "tm.h"
#ifdef USE_BIN_AS
file "crt2.s"
/* The init section is used to support shared libraries */
init
global __istart
__istart:
link %fp,&-4
#else
.file "crt2.s"
/* The init section is used to support shared libraries */
.section .init, "x"
.even
.globl __istart
__istart:
link %fp,#-4
#ifndef USE_COLLECT2
/* The ctors and dtors sections are used to support COFF collection of
c++ constructors and destructors */
.section .ctors, "d"
.even
.globl __CTOR_LIST__
__CTOR_LIST__:
.long -1
.section .dtors, "d"
.even
.globl __DTOR_LIST__
__DTOR_LIST__:
.long -1
#endif /* USE_COLLECT2 */
#endif /* USE_BIN_AS */

View File

@ -0,0 +1,26 @@
/* More startup code for A/UX */
#include "tm.h"
#ifdef USE_BIN_AS
file "crtn.s"
init
unlk %fp
rts
#else
.file "crtn.s"
.section .init, "x"
unlk %fp
rts
#ifndef USE_COLLECT2
.section .ctors, "d"
.long 0
.section .dtors, "d"
.long 0
#endif /* USE_COLLECT2 */
#endif /* USE_BIN_AS */

View File

@ -0,0 +1,99 @@
/* Generic atexit()
Copyright (C) 1996 Free Software Foundation, Inc.
This file 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.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file with other programs, and to distribute
those programs without any restriction coming from the use of this
file. (The General Public License restrictions do apply in other
respects; for example, they cover modification of the file, and
distribution when not linked into another program.)
This file 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 this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* Rather than come up with some ugly hack to make mcrt1 work, it is
better to just go ahead and provide atexit(). */
#include <stdlib.h>
void exit(int) __attribute__((noreturn));
void _exit(int) __attribute__((noreturn));
void _cleanup(void);
#define FNS_PER_BLOCK 32
struct atexit_fn_block
{
struct atexit_fn_block *next;
void (*fns[FNS_PER_BLOCK])(void);
short used;
};
/* staticly allocate the first block */
static struct atexit_fn_block atexit_fns;
static struct atexit_fn_block *current_block = &atexit_fns;
int atexit(void (*fn)(void))
{
if (current_block->used >= FNS_PER_BLOCK)
{
struct atexit_fn_block *new_block =
(struct atexit_fn_block *)malloc(sizeof(struct atexit_fn_block));
if (new_block == NULL)
return -1;
new_block->used = 0;
new_block->next = current_block;
current_block = new_block;
}
current_block->fns[current_block->used++] = fn;
return 0;
}
void exit(int status)
{
struct atexit_fn_block *block = current_block, *old_block;
short i;
while (1)
{
for (i = block->used; --i >= 0 ;)
(*block->fns[i])();
if (block == &atexit_fns)
break;
/* I know what you are thinking -- we are about to exit, why free?
Because it is friendly to memory leak detectors, that's why. */
old_block = block;
block = block->next;
free(old_block);
}
_exit(status);
}

View File

@ -0,0 +1,38 @@
/* GLD link script for building mac-compatible executables */
OUTPUT_FORMAT("coff-m68k")
SEARCH_DIR(@tooldir@/lib);
SEARCH_DIR(@libdir@);
SEARCH_DIR(/lib);
SEARCH_DIR(/usr/lib);
SEARCH_DIR(@local_prefix@/lib);
ENTRY(_start)
SECTIONS
{
.lowmem 0 (DSECT) : {
/usr/lib/low.o (.data)
}
.text 0x10000000 : {
*(.text)
*(.init)
*(.fini)
etext = .;
_etext = .;
}
.data ALIGN(0x40000) : {
*(.data)
*(.ctors)
*(.dtors)
edata = .;
_edata = .;
}
.bss : {
*(.bss)
*(COMMON)
end = .;
_end = .;
}
}

View File

@ -0,0 +1,69 @@
/* Profiling support code for A/UX
Copyright (C) 1996 Free Software Foundation, Inc.
This file 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.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file with other programs, and to distribute
those programs without any restriction coming from the use of this
file. (The General Public License restrictions do apply in other
respects; for example, they cover modification of the file, and
distribution when not linked into another program.)
This file 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 this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with files
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
/* This routine is called at the beginning of functions compiled with -p
or -pg. The A/UX libraries call mcount%, but gas cannot generate
symbols with embedded percent signs. Previous ports of GCC to A/UX
have done things like (1) assemble a stub routine with the native
assembler, or (2) assemble a stub routine with gas and edit the object
file. This solution has the advantage that it can interoperate with
the A/UX version and can be used in an eventual port of glibc to A/UX. */
#ifndef __GNUC__
#error This file uses GNU C extensions
#endif
#include <mon.h>
#ifdef IN_GCC
#include "tm.h"
#endif
struct cnt *_countbase;
#ifdef FUNCTION_PROFILER_SYMBOL
void __mcount() __asm__(FUNCTION_PROFILER_SYMBOL);
#endif
void __mcount()
{
register long **pfncnt __asm__("%a0");
register long *fncnt = *pfncnt;
if (!fncnt)
{
struct cnt *newcnt = _countbase++;
newcnt->fnpc = (char *)__builtin_return_address(0);
*pfncnt = fncnt = &newcnt->mcnt;
}
*fncnt += 1;
}

44
gcc/config/m68k/t-aux Normal file
View File

@ -0,0 +1,44 @@
# Makefile additions for A/UX
LIB2FUNCS_EXTRA=aux-mcount.c aux-exit.c
FIXPROTO_DEFINES=-D_POSIX_SOURCE
# Only really needed for collect2
CLIB=-lld
# Needed to support builds for multiple versions of A/UX
# LDFLAGS=-static
# Make sure we get the right assembler by letting gcc choose
AS = $(GCC_FOR_TARGET) -xassembler-with-cpp -D__ASSEMBLY__ $(INCLUDES) -c
aux-mcount.c: $(srcdir)/config/m68k/aux-mcount.c
cp $(srcdir)/config/m68k/aux-mcount.c aux-mcount.c
aux-exit.c: $(srcdir)/config/m68k/aux-exit.c
cp $(srcdir)/config/m68k/aux-exit.c aux-exit.c
crt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o crt1.o -c \
-fno-omit-frame-pointer $(srcdir)/config/m68k/aux-crt1.c
mcrt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o mcrt1.o -c \
-fno-omit-frame-pointer -DMCRT1 $(srcdir)/config/m68k/aux-crt1.c
maccrt1.o: $(srcdir)/config/m68k/aux-crt1.c $(GCC_PASSES)
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -o maccrt1.o -c \
-fno-omit-frame-pointer -DMACCRT1 $(srcdir)/config/m68k/aux-crt1.c
crt2.o: $(srcdir)/config/m68k/aux-crt2.asm $(GCC_PASSES)
$(AS) -o crt2.o $(srcdir)/config/m68k/aux-crt2.asm
crtn.o: $(srcdir)/config/m68k/aux-crtn.asm $(GCC_PASSES)
$(AS) -o crtn.o $(srcdir)/config/m68k/aux-crtn.asm
low.gld: $(srcdir)/config/m68k/aux-low.gld
sed -e 's|@libdir@|$(libdir)|' -e 's|@tooldir@|$(tooldir)|' \
-e 's|@local_prefix@|$(local_prefix)|' \
$(srcdir)/config/m68k/aux-low.gld > tmp-low.gld
mv tmp-low.gld low.gld