[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