cvs diff: SPARC position-indepenent code

Fergus Henderson fjh at cs.mu.oz.au
Sat Feb 8 01:42:51 AEDT 1997


Hi,

(Um, who's turn is it next?  Eeny, meeny, miny, mo... Tyson.)

Tyson, here's another cvs diff for review.

-----------------------------------------------------------------------------

Add support for generation position-independent code on SPARCs.
(Currently we use non-PIC .so files, which means that although
they're shared on disk, they're not shared at runtime.)
Note that this change is not yet enabled -- the code I've added
will only be used if you compile with `-fpic', but the default
is still to compile without `-fpic'.

runtime/goto.h:
	Add code to set the global offset table pointer register
	(register `l7') to the correct value when entering or
	re-entering a procedure, when using PIC on SPARCs.

	Also, add a couple of comments to the code for doing
	the same thing on Intel x86.

-----------------------------------------------------------------------------

Index: goto.h
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/goto.h,v
retrieving revision 1.23
diff -u -r1.23 goto.h
--- goto.h	1997/02/06 19:09:30	1.23
+++ goto.h	1997/02/07 09:33:12
@@ -138,13 +138,28 @@
     ** Note that `0f' means the label `0:' following the current
     ** instruction, and `0b' means the label `0:' before the current
     ** instruction.
+    **
+    ** Note: this code clobbers `ebx', which is a callee-save
+    ** register.  That means that it is essential that call_engine()
+    ** save `ebx' before entering Mercury code, and restore it
+    ** before returning to C code.  However, gcc and/or
+    ** setjmp()/longjmp() will do that for us automatically,
+    ** precisely because it is a callee-save register.
     */
     #define INLINE_ASM_FIXUP_REGS     				\
     	"	call 0f\n"     					\
     	"0:\n"       						\
     	"	popl %%ebx\n"     				\
     	"	addl $_GLOBAL_OFFSET_TABLE_+[.-0b],%%ebx\n\t"	\
-    		: : : "memory"
+    		: :
+#if 0
+	/*
+	** The following doesn't seem to be necessary, and
+	** leaving it out might make gcc generate slightly better code.
+	*/
+		/* tell gcc we clobber ebx and memory */	\
+    		: : : "%ebx", "memory"
+#endif
 
     /*
     ** It is safe to fall through into INLINE_ASM_FIXUP_REGS,
@@ -169,6 +184,56 @@
 	"	.type entry_" stringify(label) ", at function\n"
 
 #elif defined (__sparc)
+
+  /*
+  ** If we're using position-independent code on the SPARC, then we need to
+  ** set up the correct value of the GOT register (l7).
+  */
+
+  #if (defined(__pic__) || defined(__PIC__)) && !defined(PIC)
+    #define PIC 1
+  #endif
+
+  #if PIC
+
+    /*
+    ** At each entry point, where we may have been jump to from
+    ** code in a difference C file, we need to set up `l7'. 
+    ** We do this by getting the value the of the IP register using a `call'
+    ** instruction whose target is the very next label; this will
+    ** put the address of the call instruction in register `o7'.
+    ** We then use the value obtained in register `o7' to compute the correct
+    ** value of register `l7' by doing something with _GLOBAL_OFFSET_TABLE_
+    ** (I don't understand the details exactly, this code is
+    ** basically copied from the output of `gcc -fpic -S'.)
+    ** Note that `1f' means the label `1:' following the current
+    ** instruction, and `0b' means the label `0:' before the current
+    ** instruction.
+    */
+    #define INLINE_ASM_FIXUP_REGS     				\
+    	"0:\n"     						\
+    	"	call 1f\n"     					\
+    	"	nop\n"     					\
+    	"1:\n"       						\
+	"	sethi %hi(_GLOBAL_OFFSET_TABLE_-(0b-.)),%l7\n"	\
+	"	or %l7,%lo(_GLOBAL_OFFSET_TABLE_-(0b-.)),%l7\n"	\
+	"	add %l7,%o7,%l7\n"				\
+		/* tell gcc we clobber l7, o7, and memory */	\
+    		: : : "%l7", "%o7", "memory"
+
+    /*
+    ** It is safe to fall through into INLINE_ASM_FIXUP_REGS,
+    ** but it might be more efficient to branch past it.
+    ** We should really measure both ways and find out which is
+    ** better... for the moment, we just fall through, since
+    ** that keeps the code smaller.
+    */
+    #if 0
+      #define ASM_FALLTHROUGH(label) \
+  	goto skip(label);
+    #endif
+
+  #endif /* PIC */
 
   /* For Solaris 5.5.1, we need to declare that the type of labels is
      #function (i.e. code, not data), otherwise the dynamic linker seems


-- 
Fergus Henderson <fjh at 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 at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list