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

Reply via email to