home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume13
/
gcc-os9_68k
/
part07
< prev
next >
Wrap
Text File
|
1990-05-27
|
27KB
|
648 lines
Newsgroups: comp.sources.misc
organization: Faculty of Sci. and Tech., Keio Univ., Yokohama, Japan.
subject: v13i011: GCC1.37 on OS-9/68000 (7/7) Doc in English
from: bignum@math.keio.ac.jp (NIIMI Makoto)
Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Posting-number: Volume 13, Issue 11
Submitted-by: bignum@math.keio.ac.jp (NIIMI Makoto)
Archive-name: gcc-os9_68k/part07
Here is a documentation of GCC Version 1.37 for OSK. The distributed
file is a compressed output from command `diff -rc2N'. Please
decompress it and patch original files of gcc 1.37. It contains a new
subdirectory `osksrc'. To boot and use GCC, you need OS-9/68000 (OSK)
of Version 2.2 or later and MicroWare's C compiler of Version 3.0 or
later.
I would like to thank Takao Shinohara, Takeshi Yamada, Makoto Niimi,
Akihiro Kosakada, Susumu Hara and Yoshinori Tanaka for their helpfull
advices and bug reports. Without their supports, it was difficult for
me to transport GCC to OSK.
90/05/07 Atsushi Seyama
5-7-20 HIGASHI MACHI, HOYA, TOKYO, JAPAN (Zip code 202)
[I] Summary of system
GCC for OSK is a system which uses gcc as a compiler driver, cccp as a
preprocessor, cc1 as a compiler (all porting from GNU C), r68(020) as an
assembler and l68 as a linker (these are standard Microware's commands).
It also uses Microware's standard header files and libraries.
Microware's OSK is distinguished from any other operating systems by
unique position independent coding and modular structure . This nature
of OSK required to introduce a new definition, DATA_REF referring to
data area into GNU's compiler cc1 for transporting GCC system. The rest
of work is concentrated to compromize the difference of the
specifications of two OSs and to overcome the original bugs in OSK
system itself.
[II] Install GCC
To compile GCC by Microware's C compiler (Version Version 3.0), you
take following steps.
1) At first, copy files from directory config as shown below.
$ copy config/m68osk.md md
$ copy config/tm_osk.h tm.h
$ copy config/out_osk.c aux_output.c
$ copy config/xm_osk.h config.h
2) Next generate source file cexp.c from cexp.y using Bison.
$ Bison -o cexp.c cexp.y
We need GNU's cccp even when compiling GCC by Micrware C. Cexp.c
is a one of source files of GNU's cccp.
If you don't have Bison, you must port it. Changes are simple.
a) change tmp_base in files.c for your system, and `unlink'
temporary files after `fclose' it.
b) #define bcopy via memcpy as in config/xm_osk.h.
c) assemble osksrc/alloca.a and link it.
d) change macro PARSERDIR in Makefile for your system. PARSERDIR
is a directory in which Bison assumes bison.simple and
bison.hairy to exist.
3) Change macros home_gcc and HOST_LIBDIR in Makefile.osk for your
system.
4) Finally, execute shell script bootosk.sh. Then bootosk.sh performs
three stages of compilation:
stage0 to compile GCC via Microware's C.
stage1 to compile GCC via GCC obtained by stage0.
stage2 to compile GCC via GCC obtained by stage1.
After the completion of the last stage, bootosk.sh compares
objects created at stage1 and at stage2 to ensure the validity.
If the objects coincide, bootsh.osk prints how to installe GCC.
Bootosk.sh requires about 2MB of free area in memory and about 5MB
of disk storage.
[III] Implementation of compiler
1) Predefined macros
Predefined macros of GCC for OSK are __GNUC__, __OSK__, __mc68000__.
If you don't specify option `-ansi', OSK and mc68000 are also
predefined. Macros __mc68020__ and mc68020 are not predefined
although you specify option -mc68020 (or -m68020) to generate codes
for 68020.
2) Size and format of fundamental data types
They are the same as in Microware C. `long double' of ANSI standard
C is the same as `double'. 64 bits integer `long long int' of GNU's
extension has little endian format, i.e., high 4 bytes in lower
address and low 4 bytes in higher address. Alignment of structure
and union is the same as in Microware C at least those in standard
header files are concerned.
3) Environment variables affecting the execution of GCC
a) TMPDIR
If an environment variable `TMPDIR' is defined, its value is
regarded as a path of directory in which gcc makes temporary
files. If not, gcc makes temporary files in the current working
directory. Using gcc's option `-T', you can specify another
directory for temporary files.
b) GCCDEF
If an environment variable GCCDEF is defined, its value is taken
as a path of directory in which gcc searches header files. If it
is not defined or if header files are not found in that directory,
gcc examines directories /DD/DEFS, /H0/DEFS, /D0/DEFS in this
order. You can use gcc's option `-I' to specify directories for
searching header files prior to any of above directories.
c) GCCLIB
If an environment variable GCCLIB is defined, its value is taken
as a path of directory in which gcc searches library files, e.g.,
system's standard library files, startup file `cstart.r' and files
specified by -l option. If it is not defined or if library files
are not found, gcc examines directories /DD/GNULIB, /H0/GNULIB,
/D0/GNULIB in this order. You can use gcc's option `-L' to
specify directories for searching library files prior to any of
above directories.
d) GCC_EXEC_PREFIX
The effect of environment variable GCC_EXEC_PREFIX is same as
original gcc. One exception is that if a module is in memory, gcc
uses it. Standard prefixes are /D0/CMDS/gcc_ and /H0/CMDS/gcc_.
4) Misc.
To define a variable, its definition is admitted only once
regardless of the existence of initializer.
[IV] Differences between GCC and Microware C
1) Register usages
Microware C generates codes which use d2 and d3 as temporary
registers. GCC generates codes which use d2 and d3 as registers
being alive across function call. If you need compatibility, you
can use gcc's options `-fcall-used-d2' and `-fcall-used-d3'. Then
GCC treats d2 and d3 as temporary registers, and codes generated are
less efficient.
2) Structure and union as function argument and return value
To get structure/union value, Microware C generates codes that
caller passes a pointer to static area, and callee sets the value on
the area which pointer points. GCC uses similar mechanism, but
passed pointer points automatic area, so that the callee is
reentrant. Microware's convention is the same as that of PCC, and
is not reentrant, but if you use gcc's option `-fpcc-struct-return',
then GCC uses PCC's convention and you get the compatibility.
In Microware C, structure/union arguments are always passed by
stack, and once an argument is passed by stack, subsequent arguments
are passed by stack. In contrast to the usual register calling
convention, the convention is hardly to understand for most users.
In GCC, structure/union arguments are also passed by registers if
registers are available and if the size is small enough to fit into
registers. So at this point, there is no compatibility between
Microware C and GCC.
3) Variable number of parameters (stdarg.h)
Function prototypes shall be declared before the use of functions
with variable number of parameters, except library functions,
printf, fprintf, sprintf, scanf, fscanf and sscanf. For these
functions, function prototypes should not be declared.
4) Sizeof
Sizeof of Microware C returns signed integer as described in K&R
first edition. That of GCC returns unsigned integer as described in
ANSI standard C.
5) Special extension of Microware C
The special features of Microware C are not available in GCC except
escape sequence `\l' representing linefeed character.
6) Float.h
There are bugs in Microware's libraries, so that float.h isn't
present. Bugs are that scanf reads floating points of small
absolute value incorrectly.
7) GCC's extension for OSK
Option `-mremote' allocates all data in `remote vsect'. It may help
to port a program which uses big array. The default is `-mnoremote'
and all data are allocated in `vsect'.
Option `-mgss' defines additional global symbol for static
function. The name of the global symbol is of the form
function_name@file_name. It may help your symbolic debugging. The
default is `-mnogss'.
Option `-mnostack-check' inhibits to generate codes that checks
stack overflow. The default is `-mstack-check'.
Other new options may be clear, and probably no misunderstanding
arises. You will find a brief description of options by `gcc -?'.
Cccp also accepts option `-?'.
[V] Changes and reason
Three categories of works were done to transport GCC to OSK.
1) Exptension of GCC's data type to fulfill the separate data area
access requirement of OSK.
2) To adapt the Microware OSK and C specification to that of GCC.
3) Detour the bugs of Microware C.
In principle, all changes are conditionalized by macro definitions.
Followings are new macros to be introduced for this perpose.
a) MWC68
It is used to enclose bugs of Microware C.
b) NO_BIT_FIELD
If it is defined, source files of GCC never use bit-field.
Microware C supports bit-field, but there are bugs, so that it is
defined if MWC68 is defined.
c) HAVE_SEPARATE_DATA_AREA
DATA_REF takes effects only if this macro is defined.
One exception against this principle is the common definition of
variables. In this case, except one definition, I add `extern' silently
to all other definitions of the variable.
1) Introduction of new DATA_REF
Fundamental problem of porting GCC on OSK is that one can't use
absolute addressing and one must use offset addressing from a6 to
access the data. To represent assembler label, GCC use two RTL
expressions, SYMBOL_REF and LABEL_REF. LABEL_REF represents
assembler label which is a target of (conditional) branch
instructions, and SYMBOL_REF is used to access the data. For OSK,
Mr. Shinohara introduces DATA_REF to resolve the problem. He uses
DATA_REF to access data in data area (vsect), and uses SYMBOL_REF
only for accessing data in text area (psect) such as string literal.
It is the only one major change for porting GCC on OSK.
As described above, in source codes independent of target machine,
changes concerning DATA_REF take effect only if macro
HAVE_SEPARATE_DATA_AREA is defined.
Folowings are the files containining DATA_REF and changes made;
i) varasm.c
Make_decl_rtl and output_constant_def generate RTL expressions
SYMBOL_REF and DATA_REF. Constant data allocated in text area are
string literal and arithmetic constants. No other constants are
allocated in text area. For example, although a pointer is declared
to be `const', it is allocated in data area.
ii) combine.c, cse.c, emit_rtl.c, explow.c, expmed.c, final.c, flow.c,
genconfig.c, genextract.c, integrate.c, jump.c, loop.c, recog.c,
regclass.c, reload.c, reload1.c, rtl.c, rtl.def, rtl.h, rtlanal.c,
stmt.c
In rtl.def, DEF_RTL_EXPR of DATA_REF is added. In other files,
codes for handling DATA_REF are added, those are almost all the same
as for SYMBOL_REF.
iii) m68osk.md, out_osk.c
In out_osk.c, osk_data_ref_p, osk_data_addr_p, osk_symbol_ref_p and
osk_symbol_addr_p are defined to detect SYMBOL_REF and DATA_REF in
an insn. Another new function modify_memref is defined to convert
%m in assembler output template to %p (resp. %v) if the
corresponding operand is a memory reference via SYMBOL_REF (resp.
DATA_REF). Modify_memref also supports code generation for the
option `-mremote', and this is the real reason that the new function
is needed.
M68osk.md is a machine description for OSK based on original
m68k.md. Almost all define-insn patterns are same as in m68k.md.
Sun's fpa is not supported. In the constraint string of SImode
(Pmode) operand, `s' and `i' which permit address calculations are
replaced by `n'. One anonymous define-insn is added to calculate
address.
The C codes to generate assembler output template are changed as
follows:
if an insn uses SYMBOL_REF, it generates codes with pc-relative
addressing mode.
if an insn uses DATA_REF, it generates codes with constant offset
addressing mode with base register a6.
To write template easily, three output formats `%mN', `%pN' and
`%vN' where N is a digit, are introduced. `%mN' indicates that the
operand N may be a memory reference using SYMBOL_REF or DATA_REF.
Such a template must be processed by modify_memref, and
modify_memref converts `%m' to `%p' or `%v' appropriately. `%pN' is
an abbreviation for `%N(pc)' and `%vN' is an abbreviation for
`%N(a6)' or `(%N,a6)'. Note that direct references of a6 still
remain in m68osk.md and in out_osk.c, and macro so called
BASE_REGISTER_REGNO is not yet introduced.
iv) rtl.h
CONSTANT_P is true if CODE of an insn is DATA_REF.
2) For adapting GCC to the Microware OSK and C.
First of all, character sets admitted for the file name are different
between OSK and Un*x. The problem is that Un*x admits `-' but OSK
does not admit `-'. So I replace all `-' in file names by `_', and
names of include files are also changed in source files.
i) xm_osk.h
I don't use __builtin_alloca. Because size of memory alloca
allocates is not predictable, for OSK which does not have virtual
memory mechanism, an implementation of alloca that uses malloc as
C-allcoa seems to be more flexible than __builtin_alloca that gets
memory directory from the stack area. Incidentally, maximum size of
memory allocated by alloca is about 25K when compiling GCC by GCC.
ii) tm_m68k.h
Since sun's fpa is not supported, `enum reg_class' is different from
other systems.
iii) tm_osk.h
It is based on the original tm_m68k.h, but many macros were changed
as follows;
PREFERRED_RELOAD_CLASS, CONST_COSTS
DATA_REF is taken into account.
FIXED_REGISTERS, CALL_USED_REGISTER, CONDITIONAL_REGISTER_USAGE,
FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM
Fundamental usage of hardware registers is described. A6 and a7
are fixed-registers; d0, d1, a0, a1, a6 and a7 are
call-used-registers; a5 is the frame-pointer and the
argument-pointer. If you specify -mremote,
CONDITIONAL_REGISTER_USAGE marks d2 and d3 as fixed registers and
call-used registers. In this case, d2 and d3 are used for loading
32bit constant offset.
LIBCALL_VALUE, FUNCTION_ARG_REGNO_P, FUNCTION_ARG,
FUNCTION_ARG_PARTIAL_NREGS
On GCC for OSK, function's arguments are passed by registers d0
and d1. No argument is passed partly in register and partly in
stack.
FUNCTION_PROLOGUE, FUNCTION_EPILOGUE
Output codes are adapted for the use of r68. No support of fpa
simplifies macros. In FUNCTION_PROLOGUE, __stack_check is called,
which is a function to check stack overflow and is defined in
gnulibosk.c. In FUNCTION_EPILOGUE, function free_allocaed is
called if alloca is used in the function. It frees memory alloca
allocates.
FUNCTION_PROFILER, FUNCTION_BLOCK_PROFILER, BLOCK_PROFILER
The profiling is based on basic block profiler. No standard
profiler is present on OSK, so codes are my own.
SDB_DEBUGGING_INFO, DBX_DEBUGGING_INFO
These debugging information is useless in OSK, so flags are
undefined.
TARGET_NEWLINE, TARGET_LF
TARGET_NEWLINE is defined to be 015. The code is the same as
TARGET_CR, and there is no code for linefeed. TARGET_LF exists
only for OSK, and its value is defined to be 012. TARGET_LF
provides the value of the escape sequence `\l' representing
linefeed character.
CPP_PREDEFINES, LINK_SPEC, STARTFILE_SPEC, LIB_SPEC
Predefined macros are `OSK' and `mc68000'. Other specs are
defined appropriately. You can't use math trap handler from GCC.
TARGET_SWITCHES
OSK specific switches (no)remote, (no)stack-check and (no)gss are
defined. For effects of these switches, see below.
OVERRIDE_OPTIONS
It forces `flag_shared_data' to be 1.
DOLLARS_IN_IDENTIFIER
It is defined to be 1.
TARGET_MEM_FUNCTIONS
It is defined to use memcpy memset and memcmp that are included in
OSK libraries.
ASM_FILE_START, ASM_FILE_END, ASM_IDENTIFY_GCC ASM_APP_ON, ASM_APP_OFF,
TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP, ASM_OUTPUT_LABELREF,
ASM_OUTPUT_DOUBLE, ASM_OUTPUT_FLOAT, ASM_OUTPUT_INT, ASM_OUTPUT_SHORT,
ASM_OUTPUT_CHAR, ASM_OUTPUT_BYTE, ASM_OUTPUT_REG_PUSH,
ASM_OUTPUT_REG_POP, ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT,
ASM_OUTPUT_ALIGN, ASM_OUTPUT_SKIP, ASM_OUTPUT_LOCAL,
ASM_OUTPUT_FLOAT_OPERAND, ASM_OUTPUT_DOUBLE_OPERAND,
PRINT_OPERAND_ADDRESS
These macros are changed so as to output a text suitable for
r68(020), Microware's standard relocatable assembler.
ASM_OUTPUT_LABEL, ASM_GLOBALIZE_LABEL
For a label to be global, r68 requires that the label name in
definition ends with `:'. The convention is different from Unix,
and original ASM_OUTPUT_LABEL/ASM_GLOBALIZE_LABEL do not work
well. A global variable label_is_global defined in varasm.c is
introduced to recover the difference.
ASM_DECLARE_FUNCTION_NAME
It is defined to support the option `-mgss'.
ASM_OUTPUT_INTERNAL_LABEL, ASM_GENERATE_INTERNAL_LABEL
To avoid the name conflicts, internal labels generated by the
compiler end with `.'.
PRINT_OPERAND
It processes new output formats %pN and %vN. It does not support
%d for absolute addressing. Also it does not support sun's fpa.
ASM_OUTPUT_ASCII
It outputs strings for the use of r68. It is never defined in
tm_m68k.h.
TARGET_FPA, REGNO_OSK_FOR_FPA_P, FPA_REG_P
Because sun's fpa is not supported, these macros are undefined.
FIRST_PSEUDO_REGISTER, HARD_REGNO_MODE_OK, REG_CLASS_NAMES,
REG_CLASS_CONTENTS, REGNO_REG_CLASS, REG_CLASS_FROM_LETTER,
CONST_DOUBLE_OK_FOR_LETTER_P, CLASS_MAX_NREGS, NOTICE_UPDATE_CC,
REGISTER_NAMES
Because sun's fpa is not supported, these macros are simplified.
iv) c_parse.y, c_exp.y
Parse_escape in c_exp.y and skip_white_space, readescape, yylex in
c_parse.y support special escape sequence `\l' which represents
linefeed. The code is taken from the macro TARGET_LF defined in
tm_osk.h.
v) expr.c, stmt.c
Stack check codes are generated at three points; at the entry of
function; at the entry of a block in which array of dynamic size is
defined; and at the call of __builtin_alloca. FUNCTION_PROLOGUE
generates stack check codes at the entry of function. In stmt.c,
expand_decl generates stack check insns at the entry of a block. In
expr.c, expand_builtin generates stack check insns at the call of
__builtin_alloca. Note that gen_probe is not suitable because it is
called after stack grows.
vi) gccosk.c
It is a source file of compiler driver gcc for OSK. It is provided
only for the use of OSK, because there are many changes as follows.
As a first difference, OSK's system call fork is something like
Un*x's fork plus exec, so that gcc's codes to create process are
changed. Similarly usage of pipe in OSK is different from Un*x, and
corresponding codes are changed. Next, OSK's syntax of option with
an argument looks like -o=output and it is different from Un*x's
style. So gcc is changed to generate both style of options.
Other changes are OSK specific. At first, OSK's gcc removes
temporary files as soon as possible. Secondarily, OSK's linker
lacks option to specify directories to be searched for libraries, so
OSK's gcc processes the option `-LDIR' for users' sake. Thirdly,
linker l68 sometimes aborts by stack overflow, so an option `-F' is
added to specify additional stack size of processes forked by OSK's
gcc. By this option you can specify also their priority.
vii) cccp.c
Microware's preprocessor can't expand long macro, and Microware C
compiler c68 can't process long lines. Thus Microware C compiler
system can't compile GCC by itself, and we use additionally GNU's
cccp to compile GCC. A special option `-K' is added to cccp, and
under `-K', cccp outputs text suitable for the input of c68.
viii) gnulibosk.c
It is a gnulib.c for OSK. New function __stack_check is added,
which detects runtime stack overflow. Other functions are the same
as in the original gnulib.c. The reason of rewriting is as follows.
1) GCC's register usage is different from Microware C.
Microware C generates codes that use d2 and d3 as temporary
registers, but GCC for OSK generates codes that use d2 and d3 as
register to live across function call. So gnulib.c compiled by
Microware C may clobber d2 and d3, and it must be rewritten.
2) GCC's argument passing convention is different from Microware C.
Although Microware C generates codes which use registers to pass
arguments, structure/union arguments are passed by stack and once
an argument is passed by stack, subsequent arguments are also
passed by stack. On the other hand, GCC generates codes which use
registers to pass structure/union arguments if its sizeof is small
enough. Since original gnulib.c use arguments of union type, it
must be rewritten.
ix) final.c
It supports profile code generation. Because OSK does not provide
OS level profiling, Un*x's style of profiler is not supported.
Option `-p' generates profile codes to count the number of function
calls. It is implemented as a part basic block profiler. The basic
block profiler is now in stage of experiment, and no report command
nor libraries for profiling are included in the distribution.
x) bootosk.sh, Makefile.osk
These are Shell script and makefile to boot GCC. Makefile got dirty
because it supports both Un*x style options and those of OSK.
xi) osksrc/
It is a new directory used to boot GCC for OSK. It contains source
file of library functions, and a makefile to make cccp and cppcccp.
xi-1) osksrc/Makefile
It is a makefile to make objects cppcccp, cccp, move_if_change and
really_new. Cppcccp and cccp are used in stage0 booting, where cccp
helps Microware C to compile GCC. Other objects move_if_change and
really_new are used in all stages of booting GCC. (Do you believe
me if I say Microware's make needs "really_new"? Oh! trust me,
please.)
xi-2) osksrc/cppcccp.c
Cppcccp is a name of an executable file, which contains executable
module named cpp. When compiling GCC by Microware C, it is loaded
into memory. Then Microware cc forks cpp and cpp forks GNU's cccp
to preprocess source files.
xi-3) osksrc/config.h
It is needed to compile cccp by pure Microware C compiler. As
stated before, Microware's preprocessor does not expand long macros,
so the proper config.h can't be used. It contains minimum number of
#defines for compiling cccp.
xi-4) osksrc/alloca.a
It is an alloca based on alloca.c and adapted to OSK. The reason
that original alloca.c is not adequate to OSK is as follows. Codes
generated by Microware C use the stack-pointer as base register to
access local variables, and local variables in a block are allocated
dynamically. So a call of alloca in a block of a function may free
a memory segment allocated by alloca in an inner block of the same
function. It is undesirable since memory allocated by alloca must
be alive until the function returns.
The adaptaion is done by using frame-pointer a5 instead of
stack-pointer a7 to mark level of alloca to be called, so it is safe
to use both in Microware C and GCC.
xi-5) osksrc/getcd.c
It is a replacement of getwd. Getcd is a function returning current
working/execution directory.
xi-6) osksrc/move_if_change.c
OSK's shell is so poor and it can't execute original move-if-change.
Move_if_change.c is a substitution of move-if-change written by C.
xi-7) osksrc/really_new.c
Really_new is a command used in Makefile.osk. Function is
self-explanatory from its name. It is worth nothing to try to
understand why such command is needed in a makefile. So please
simply accept it. I have nothing to say about brain-damaged
Microware's make.
xi-8) osksrc/ldexp.c, osksrc/perror.c, osksrc/qsort.c, osksrc/stat.c,
osksrc/stat.h, osksrc/varargs.h
These are OSK specific standard Un*x library functions and header
file. Qsort.c is taken from tahoe library. Qsort.c is needed
because register usage is different between Microware C and GCC.
You can use varargs.h both in Microware C and GCC.
3) To avoid bugs of Microware C and OSK
i) tm_osk.h (ASM_OUTPUT_COMMON)
Microware's assembler and linker support `com.b' for common
definition, but there are bugs, so it can't be used. Instead,
`ds.b' is used.
ii) genoutput.c
There is a bug in kernel (Version 2.2) which does not allow to
execute modules with data size beyond 64KB. If you compile GCC
Version 1.37 without changes, its data size exceeds 64KB, and you
can't execute cc1. Thus the types of elements of tables which
genoutput generates are changed to `short' where it is possible.
iii) recog.h
Corresponding to the change of types of elements of tables described
above, declarations of tables are changed.