						September 25, 1992

Howdy, the files enclosed here comprise the latest GCC release for
the Atari ST. The compiler, assembler, linker, and other associated
utilities are included, but no C++ or Objective C compiler is in
this archive. The compiler corresponds to GCC 2.2.2, patchlevel 3
for ST/TOS, with additional enhancements by me. The assembler is
GAS 1.38.1, patchlevel 3, with additional bug fixes by me. The linker
also contains enhancements, but otherwise the linker and other
utility programs correspond to patchlevel 31.

The compiler supports two new options, "-mbaserel" and "-mpcrel".

The -mpcrel option makes the compiler use PC-relative addressing
to reference most constants. Unfortunately it's not too smart about
using this mode; if the constant's location is more than 32K away
from the reference, the linker will complain and the resulting
program will probably be useless. This situation generally arises
when the source code has declarations like "extern const blah;"
For local constants, it's rare to have a single function use up
32K of code, so it's less likely to be a problem.

The -mbaserel option makes the compiler use base-relative mode to
reference global and static variables. Both PC-relative and base-
relative addressing modes save 2 bytes of code space and 4 cycles
of execution time per reference, compared to the long absolute
addressing mode that is normally used, which is one reason why it's
desirable to use these options. However, both of these modes are
limited to addressing +/-32K from the base (the PC or the given
address register). Again, the compiler can't do anything to help
if the resulting program uses too much global and static variable
space, and the linker will complain about the resulting program
file.

With these limitations in mind, there are additional advantages
besides the obvious space/speed advantage. By eliminating absolute
address references, programs can be made to be almost completely
position-independent. ("Almost" - the compiler doesn't use pc-
relative for function references, since they are most likely to
be too far much of the time.) In particular, programs can be made to
be "sharable." The current version of MiNT (0.96) has the feature
that multiple invocations of a sharable program will only load the
text/code once, sharing the code between multiple processes. This
sharing means you can run more copies of a program simultaneously
than you could otherwise, and each invocation will load faster than
before since only the data region needs to be loaded instead of
loading both text and data again.

Why would you ever want to invoke any particular program multiple
times, at the same time? Best example - a shell program, in a typical
C programming environment. You start a shell, edit some code, then
run "make" to get the program built. Make has to fire off a new shell
to process every command given in the makefile. With a shared shell,
the entire make will proceed much more quickly. Or, if you happen to
have multiple users on your system, if they all run the same shell,
you get a savings there as well.

When the "-mbaserel" option is given, the C preprocessor defines
two new macros which you can use as needed. __MBASE__ is defined as
the name of the register being used as a base register, and __MBASESTR__
is the same name surrounded by double-quotes (i.e., stringified).
If you tend to mix assembly language in with your C code, you may
find it necessary to check for these macros. Most of the time you
shouldn't have to worry about it, though.

Also, when linking with "-mbaserel," the linker will be invoked
with the "-n" option, which normally means to make the text section
read-only. The ST can't do much about that, but in this case the
linker sets a bit in the program flag word that tells MiNT that the
program is sharable.

Note, gcc always puts anything you declare as "const" into the text
segment, and regular variables go into data or bss. You can get
into trouble using -mbaserel if you declare a symbol as e.g.

foo.c:
	const int blah;

in one file, but reference it as

bar.c:
	extern int blah;

in another file. When the linker gets to bar.o, it will look for
the address of blah in the data segment even though the symbol lives
in the text segment, and you'll get a "relocation out of range" error.

In this situation you can either delete the "const" keyword in foo.c or
add it in bar.c.

Finally - you also need a C library that's compiled for base-relative
mode. Mixing base-relative object files with regular object files is
a pretty sure way of creating a program that crashes soon after it's
started. Gcc will look for library files with a 'b' prepended to the
usual name when linking with -mbaserel, so instead of crt0.o it will
try to link bcrt0.o, gnu.olb becomes bgnu.olb, etc.

Whew, sorry for being so long-winded. Final note - these files don't
represent an official patchlevel of the software. An official release
will be coming out soon, maybe after GCC 2.3 is released.

I probably beat a couple subjects into the ground here, and glossed too
lightly over some others. Feel free to send me any questions or comments.
Happy hacking...

  -- Howard Chu, hyc@hanauma.jpl.nasa.gov

PS: just remembered another addition: I added ".cpp" to the list of
suffixes that GCC recognizes, meaning "assembler with preprocessor."
Just makes it a little more convenient to deal with some of the
assembly code in the GCC and MiNT libraries...
