[gclist] gclist-digest V1 #40

Fergus Henderson fjh@cs.mu.OZ.AU
Thu, 2 May 1996 01:30:34 +1000 (EST)


This mail doesn't have much to do with garbage collection.

Paul R. Wilson, you wrote:
> 
> Hi Fergus
> 
>   I understand that your compiler compiles to C and uses label addresses
> for jumps (with GCC).  Is that correct?

Yes.

>   How did you do it?  

With much angst! ;-)

This technique is not entirely portable, and it can require a bit of
fooling around to get it working.

> We've had problems with using label addresses,
> apparently because GCC doesn't support jumps to labels that aren't in
> scope.  This appears to cause problems on SPARC and RS6000's, at least.

We've got it working on sparc, although not on rs6000.  I also got it
working on alpha, i386 and mips.  The details are mostly spelt out in
the following paper:

	Compiling logic programs to C using GNU C as a portable assembler. 
	FJ Henderson, TC Conway, and Z Somogyi.  Proceedings of the ILPS '95
	Postconference Workshop on Sequential Implementation Technologies for
	Logic Programming, 1995, Portland, Oregon. pp. 1-15.  Available via
	<http://www.cs.mu.oz.au/mercury/papers/mercury_to_c.ps.gz> (65K).

>   (On RS6000's, a function pointer isn't a raw code pointer.  It's
> a pointer to a little dictionary vector that contains the code pointer
> and other stuff the procedure may use.  When you call the procedure,
> the address of the little dictionary vector is put in a register,
> so that register-relative addressing can be used to access the stuff
> in the vector.  Then the code pointer is extracted and jumped to,
> after setting up that context.  The problem with label jumps may
> be that this register is not being set with the vector address the
> way it is at a procedure call, so if you jump out of context, you're
> toast.)

There is a related problem on the alpha, where the gp (global pointer)
register needs to be set up correctly, and jumping from the middle of
one function to the middle of another can cause trouble.  To solve this
problem, I added some inline assembler code to put the target address
in a register (t12) before the jump, and added inline assembler to do
"ldgp $gp, $t12" at the start of each label, which loads the global
pointer with the correct value.  This is in Mercury 0.6, which has not
yet been publically released; if you want to see the code, contact me.
The Mercury compiler bootstraps fine using these tricks on alpha, but
there are some niggling problems with the coexistence of inter-function
jumps and the use of gcc global registers that I'm not sure we've
solved yet.

The same problem occurs on mips or sparc if you try to use
position-independent code; our solution there was simply to not use pic.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.