Bernd Oppolzer schrieb:
Am 20.08.2013 16:54, schrieb Mark Morgan Lloyd:
> Just to name a few: you'll need to get parameter passing for functions
> correctly
Which leads to another issue: the 370 is a register-based system
without a stack as understood today. Parameters are mostly passed in
registers, but this is largely hidden since supervisor calls etc. are
usually hidden in macros.
My own feeling is that it would be best to start targeting a
late-model 390, which does have a stack etc., and to use the standard
GNU assembler and linker (as and ld) /initially/ targeting Linux. Any
other combination (i.e. a proprietary assembler etc. with an antique
MVS as target) is going to cause nothing but grief, since it makes it
very difficult for developers skilled with FPC but not with IBM
mainframes to give any practical help.
Sorry, I don't follow some of the comments in this thread.
First, what is a stack? A stack IMO consists of a stack pointer provided
by the
hardware, that is, a register. And even the old IBM machines have many
registers
that can be seen as stack pointers; you only have to select one.
You are not free to select one register for that purpose, unless it's
guaranteed (by calling conventions) that all software preserves this
register.
That is
in fact the
way that the stack has been implemented in "old" compilers on "old" IBM
hardware,
be it Fortran, Pascal, PL/1 or C. All those languages needed kind of
stacks for
local variables of procedures etc. So IMO there is no need to target new
hardware;
this will be very expensive and excludes the use of Hercules simulators and
free versions of IBM operating systems for first tests. Even todays IBM
compilers
don't use the "new" hardware stack.
Such subroutines deserve 3 addresses, to their parameters, local
variables, and a return address. The latter can not be choosen freely,
it's implemented in machine CALL/RETURN instructions, which manage kind
of an *return stack*. When these instructions predate the hardware
stack, the return addresses obviously have been managed in some
different way, not using the new hardware stack. This means that a
calling convention must be established, for passing subroutine arguments
and return values, for local storage allocation, and for stack
unwinding. Some convention may already exist, for calling system
services or library functions. Apart from that every compiler can choose
its own model, for further (private) calling conventions. In most cases
a single register (Base or Frame Pointer) is used for that purpose,
which *can* point to some stack location, but it also can point to any
other convenient memory frame. Let's call it the *data stack* for
disambiguation.
Both kinds of stacks become very important when a debugger is added. The
debugger must not only know about the return stack, which is machine
specific, but it also must know about the calling conventions, how to
access subroutine parameters and local variables, and how these frames
are linked together during subroutine calls. This means that, when an
already existing debugger shall be used, the available calling
conventions are already specified!
DoDi
_______________________________________________
fpc-devel maillist - [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel