[fpc-devel] Re. z370 Cross Compilation, Pass 2 of ....
Hans-Peter Diettrich
DrDiettrich1 at aol.com
Sun Sep 1 07:10:49 CEST 2013
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
More information about the fpc-devel
mailing list