[kaffe] CVS kaffe (stack): Checkpoint of jitter for linux/ppc. It still doesn't fully work, but

Kaffe CVS cvs-commits at kaffe.org
Mon Dec 20 16:19:43 PST 2004


PatchSet 5686 
Date: 2004/12/21 00:15:25
Author: stack
Branch: HEAD
Tag: (none) 
Log:
Checkpoint of jitter for linux/ppc.  It still doesn't fully work, but
it passes the internal tests and you can run HelloWorld if it is in
the BOOTCLASSPATH.  Exception handling and many other things are a
joke and need to be fixed up eventually.  Oh, and I've probably broken
something with this checkin, sorry.

Members: 
	ChangeLog:1.3232->1.3233 
	config/powerpc/jit-labels.h:INITIAL->1.1 
	config/powerpc/jit.h:1.1->1.2 
	config/powerpc/jit3-icode.h:1.1->1.2 
	config/powerpc/jit3-powerpc.def:1.1->1.2 
	config/powerpc/ppc_isa.h:1.1->1.2 
	config/powerpc/ppc_macros.h:1.1->1.2 
	config/powerpc/ppc_stack_frame.h:1.1->1.2 
	config/powerpc/sysdepCallMethod.h:1.6->1.7 
	config/powerpc/trampolines.c:1.1->1.2 
	config/powerpc/darwin/jit3-md.h:1.1->1.2 
	config/powerpc/linux/jit3-md.h:INITIAL->1.1 
	config/powerpc/linux/md.c:1.1->1.2 
	config/powerpc/linux/md.h:1.11->1.12 
	developers/mnemonicizer.awk:1.1->1.2 
	kaffe/kaffevm/classMethod.h:1.70->1.71 
	kaffe/kaffevm/stackTrace.c:1.43->1.44 
	kaffe/kaffevm/jit/native-wrapper.c:1.3->1.4 
	kaffe/kaffevm/jit3/machine.c:1.62->1.63 
	kaffe/kaffevm/jit3/machine.h:1.21->1.22 
	test/internal/ControlFlowMethods.java:1.2->1.3 
	test/internal/Exceptions.java:INITIAL->1.1 
	test/internal/Makefile.am:1.10->1.11 
	test/internal/Makefile.in:1.83->1.84 
	test/internal/NativeMethodCall.java:INITIAL->1.1 
	test/internal/ObjectFields.java:1.2->1.3 
	test/internal/StaticFields.java:1.1->1.2 
	test/internal/System.java:INITIAL->1.1 
	test/internal/TypeConversion.java:1.2->1.3 
	test/internal/jitBasic.c:1.4->1.5 
	test/internal/jit_stub.c:1.9->1.10 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3232 kaffe/ChangeLog:1.3233
--- kaffe/ChangeLog:1.3232	Mon Dec 20 21:16:49 2004
+++ kaffe/ChangeLog	Tue Dec 21 00:15:25 2004
@@ -1,3 +1,72 @@
+2004-12-20  Timothy S. Stack  <stack at cs.utah.edu>
+
+	* config/powerpc/jit-labels.h:
+	Moved label handling code into here so it's easier to change
+	without having to recompile the whole tree.
+
+	* config/powerpc/jit.h:
+	Linux-specific changes, will probably break OS X compat.  Moved
+	out label handling macros.  Fixed SLOT2LOCALOFFSET macro for
+	linux.
+
+	* config/powerpc/jit3-icode.h: 
+	Fix broken I26const_rangecheck macro.  Don't undef HAVE_call_ref.
+
+	* config/powerpc/jit3-powerpc.def:
+	Updates for linux/ppc.
+
+	* config/powerpc/ppc_isa.h:
+	Macros now print the current function name.
+
+	* config/powerpc/ppc_macros.h:
+	Add ppc_b26 macro.
+
+	* config/powerpc/ppc_stack_frame.h:
+	Add linux specific stack frame structure.
+
+	* config/powerpc/sysdepCallMethod.h:
+	Break sysdepCallMethod function into __APPLE__ and non-Apple
+	functions, so I can wrap my puny brain around what's going on.
+
+	* config/powerpc/trampolines.c, config/powerpc/linux/jit3-md.h,
+	config/powerpc/linux/md.h, config/powerpc/linux/md.c:
+	Updates for linux/ppc.
+
+	* developers/mnemonicizer.awk:
+	Add the function name to the debugging printfs.
+
+	* kaffe/kaffevm/classMethod.h, kaffe/kaffevm/stackTrace.c,
+	kaffe/kaffevm/jit3/machine.h, kaffe/kaffevm/jit3/machine.c:
+	Add an explicit header structure to jitted code.
+
+	* kaffe/kaffevm/jit/native-wrapper.c:
+	Must call initFakeCalls() to reinitialize fake-call state.
+
+	* test/internal/ControlFlowMethods.java,
+	test/internal/Exceptions.java:
+	Move stuff that throws exceptions to Exceptions.java since they
+	require more things to work correctly.
+
+	* test/internal/Makefile.am, test/internal/Makefile.in:
+	Add NativeMethodCall and Exceptions tests.
+
+	* test/internal/NativeMethodCall.java, test/internal/System.java:
+	Test for calling native methods.
+
+	* test/internal/ObjectFields.java:
+	More test cases.
+
+	* test/internal/TypeConversion.java:
+	Add critical comment so that certain dummies don't make changes
+	that distort the test case.
+
+	* test/internal/jitBasic.c:
+	Deal better with endianess when comparing things.
+
+	* test/internal/jit_stub.c:
+	Statically load java.lang.System (our stripped version atleast),
+	java.lang.Float, and java.lang.Double.
+
 2004-12-20  Adam Heath  <doogie at brainfood.com>
 
 	* TODO:
===================================================================
Checking out kaffe/config/powerpc/jit-labels.h
RCS:  /home/cvs/kaffe/kaffe/config/powerpc/jit-labels.h,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/config/powerpc/jit-labels.h	Tue Dec 21 00:19:42 2004
@@ -0,0 +1,163 @@
+/*
+ * powerpc/jit-labels.h
+ *
+ * Copyright (c) 2002, 2004 The University of Utah and the Flux Group.
+ * All rights reserved.
+ *
+ * @JANOSVM_KAFFE_JANOSVM_LICENSE@
+ */
+
+#ifndef __powerpc_jit_labels_h
+#define __powerpc_jit_labels_h
+
+/* Extra label types. */
+
+/* 26 bit displacement */
+#define Llong26  (Larchdepend + 0)
+/* 16 bit displacement */
+#define Llong16  (Larchdepend + 1)
+/* 16 bit displacement, no alignment restrictions.  */
+#define Llong16noalign  (Larchdepend + 2)
+/* 32 bit displacement broken into two instructions. */
+#define Llong16x16 (Larchdepend + 3)
+/* XXX not very different from Lnegframe... */
+#define Lsavedregs (Larchdepend + 4)
+/* Update the source register in a stmw. */
+#define Lreg_s (Larchdepend + 5)
+
+#define FILL_LABEL_Llong16x16(P, V, L) \
+{ \
+	ppc_code_t *_code = (ppc_code_t *)(P); \
+	ppc_code_t _disp = (V); \
+\
+	_code[0] |= ppc_lo16(_disp); \
+	_code[1] |= ppc_ha16(_disp); \
+	/* \
+	 *                 ^^^^^^^^^^^^ Need to clear out the high order bits \
+	 * if the offset is negative. \
+	 */ \
+}
+
+#define FILL_LABEL_Llong26(P, V, L) \
+{ \
+	ppc_code_t *_code = (ppc_code_t *)(P); \
+	ppc_code_t _disp = (V); \
+\
+	assert(((_disp & ~PPC_LI_MASK) == 0x00000000) || \
+	       ((_disp & ~PPC_LI_MASK) == 0xFC000000)); \
+\
+	_code[0] |= (_disp & PPC_LI_MASK); \
+	/* \
+	 *                 ^^^^^^^^^^^^ Need to clear out the high order bits \
+	 * if the offset is negative. \
+	 */ \
+}
+
+#define FILL_LABEL_Llong16(P, V, L) \
+{ \
+	ppc_code_t *_code = (ppc_code_t *)(P); \
+	ppc_code_t _disp = (V); \
+\
+	assert(((_disp & ~PPC_BD_MASK) == 0x00000000) || \
+	       ((_disp & ~PPC_BD_MASK) == 0xFFFF0000)); \
+\
+	_code[0] |= (_disp & PPC_BD_MASK); \
+}
+
+#define FILL_LABEL_Llong16noalign(P, V, L) \
+{ \
+	ppc_code_t *_code = (ppc_code_t *)(P); \
+	int _disp = (V); \
+\
+	assert(((_disp & ~PPC_D_MASK) == 0x00000000) || \
+	       ((_disp & ~PPC_D_MASK) == ~PPC_D_MASK)); \
+\
+	_code[0] |= (_disp & PPC_D_MASK); \
+}
+
+#define FILL_LABEL_Lsavedregs(P, V, L) \
+{ \
+	int frame_size = 0, saved_registers; \
+\
+	saved_registers = maxLocal - PPC_ARG_REGISTER_COUNT; \
+	if( saved_registers < 0 ) \
+		saved_registers = 0; \
+	saved_registers = maxStack + maxTemp + 18; \
+	if( (firstConst != currConst) || maxLocal || maxTemp ) \
+	{ \
+		saved_registers += 1; /* r31 */ \
+	} \
+	frame_size += -SLOTSIZE * saved_registers; \
+	if( ((L)->type & Lfrommask) == Lrelative ) \
+	{ \
+		frame_size += (L)->from; \
+	} \
+	FILL_LABEL_Llong16noalign(P, frame_size, L); \
+}
+
+#define FILL_LABEL_Lframe(P, V, L, neg) \
+{ \
+	int frame_size = sizeof(ppc_stack_frame_t), saved_registers; \
+\
+	saved_registers = maxLocal - PPC_ARG_REGISTER_COUNT; \
+	if( saved_registers < 0 ) \
+		saved_registers = 0; \
+	saved_registers += maxStack + maxTemp; \
+	if( (firstConst != currConst) || maxLocal || maxTemp ) \
+	{ \
+		saved_registers += 1; /* r31 */ \
+	} \
+	saved_registers += (saved_registers * 2) + 18; \
+	frame_size += SLOTSIZE * saved_registers; \
+	if( ((L)->type & Lfrommask) == Lrelative ) \
+	{ \
+		frame_size += (L)->from; \
+	} \
+	if( neg ) \
+		frame_size = -frame_size; \
+	FILL_LABEL_Llong16noalign(P, frame_size, L); \
+}
+
+#define FILL_LABEL_Lreg_s(P, V, L) \
+{ \
+	ppc_code_t *_code = (ppc_code_t *)(P); \
+	int saved_registers; \
+\
+	saved_registers = maxLocal - PPC_ARG_REGISTER_COUNT; \
+	if( saved_registers < 0 ) \
+		saved_registers = 0; \
+	saved_registers = maxStack + maxTemp; \
+	if( (firstConst != currConst) || maxLocal || maxTemp ) \
+	{ \
+		saved_registers += 1; /* r31 */ \
+	} \
+	_code[0] |= PPC_SET_RS((32 - saved_registers)); \
+}
+
+#define EXTRA_LABELS(P, V, L) \
+	case Lframe: \
+		FILL_LABEL_Lframe(P, V, L, 0); \
+		break; \
+	case Lnegframe: \
+		FILL_LABEL_Lframe(P, V, L, 1); \
+		break; \
+	case Llong26: \
+		FILL_LABEL_Llong26(P, V, L); \
+		break; \
+	case Llong16: \
+		FILL_LABEL_Llong16(P, V, L); \
+		break; \
+	case Llong16noalign: \
+		FILL_LABEL_Llong16noalign(P, V, L); \
+		break; \
+	case Llong16x16: \
+		FILL_LABEL_Llong16x16(P, V, L); \
+		break; \
+	case Lsavedregs: \
+		FILL_LABEL_Lsavedregs(P, V, L); \
+		break; \
+	case Lreg_s: \
+		FILL_LABEL_Lreg_s(P, V, L); \
+		break;
+
+#endif
Index: kaffe/config/powerpc/jit.h
diff -u kaffe/config/powerpc/jit.h:1.1 kaffe/config/powerpc/jit.h:1.2
--- kaffe/config/powerpc/jit.h:1.1	Fri Sep 17 18:48:40 2004
+++ kaffe/config/powerpc/jit.h	Tue Dec 21 00:15:28 2004
@@ -2,7 +2,7 @@
  * powerpc/jit.h
  * Contains the powerpc trampoline and dcache flush macros.
  *
- * Copyright (c) 2002 The University of Utah and the Flux Group.
+ * Copyright (c) 2002, 2004 The University of Utah and the Flux Group.
  * All rights reserved.
  *
  * @JANOSVM_KAFFE_JANOSVM_LICENSE@
@@ -94,8 +94,10 @@
  * Call a jitted java exception handler.
  */
 #define CALL_KAFFE_EXCEPTION(frame, handler, object) \
-	asm volatile ("mr r1, %0\n" \
-		      "\tmr r3, %1\n" \
+	asm volatile ("mr 1, %0\n" \
+		      "\tlwz 10, 0(1)\n" \
+		      "\tlmw 14, -72(10)\n" \
+		      "\tmr 3, %1\n" \
 		      "\tmtctr %2\n" \
 		      "\tbctr\n" \
 		      : : "r" (frame), "r" (object), "r" (handler) : "r3")
@@ -106,148 +108,6 @@
  */
 #define CALL_KAFFE_C_EXCEPTION(F, P, H, O)
 
-/* Extra label types. */
-
-/* 26 bit displacement */
-#define Llong26  (Larchdepend + 0)
-/* 16 bit displacement */
-#define Llong16  (Larchdepend + 1)
-/* 16 bit displacement, no alignment restrictions.  */
-#define Llong16noalign  (Larchdepend + 2)
-/* 32 bit displacement broken into two instructions. */
-#define Llong16x16 (Larchdepend + 3)
-/* XXX not very different from Lnegframe... */
-#define Lsavedregs (Larchdepend + 4)
-/* Update the source register in a stmw. */
-#define Lreg_s (Larchdepend + 5)
-
-#define FILL_LABEL_Llong16x16(P, V, L) \
-{ \
-	ppc_code_t *_code = (ppc_code_t *)(P); \
-	ppc_code_t _disp = (V); \
-\
-	_code[0] |= ppc_lo16(_disp); \
-	_code[1] |= ppc_ha16(_disp); \
-	/* \
-	 *                 ^^^^^^^^^^^^ Need to clear out the high order bits \
-	 * if the offset is negative. \
-	 */ \
-}
-
-#define FILL_LABEL_Llong26(P, V, L) \
-{ \
-	ppc_code_t *_code = (ppc_code_t *)(P); \
-	ppc_code_t _disp = (V); \
-\
-	assert(((_disp & ~PPC_LI_MASK) == 0x00000000) || \
-	       ((_disp & ~PPC_LI_MASK) == 0xFC000000)); \
-\
-	_code[0] |= (_disp & PPC_LI_MASK); \
-	/* \
-	 *                 ^^^^^^^^^^^^ Need to clear out the high order bits \
-	 * if the offset is negative. \
-	 */ \
-}
-
-#define FILL_LABEL_Llong16(P, V, L) \
-{ \
-	ppc_code_t *_code = (ppc_code_t *)(P); \
-	ppc_code_t _disp = (V); \
-\
-	assert(((_disp & ~PPC_BD_MASK) == 0x00000000) || \
-	       ((_disp & ~PPC_BD_MASK) == 0xFFFF0000)); \
-\
-	_code[0] |= (_disp & PPC_BD_MASK); \
-}
-
-#define FILL_LABEL_Llong16noalign(P, V, L) \
-{ \
-	ppc_code_t *_code = (ppc_code_t *)(P); \
-	int _disp = (V); \
-\
-	assert(((_disp & ~PPC_D_MASK) == 0x00000000) || \
-	       ((_disp & ~PPC_D_MASK) == ~PPC_D_MASK)); \
-\
-	_code[0] |= (_disp & PPC_D_MASK); \
-}
-
-#define FILL_LABEL_Lsavedregs(P, V, L) \
-{ \
-	int frame_size, saved_registers; \
-\
-	saved_registers = (maxLocal + maxStack + maxTemp) - \
-		PPC_ARG_REGISTER_COUNT; \
-	if( saved_registers < 0 ) \
-		saved_registers = 0; \
-	if( (firstConst != currConst) || maxLocal || maxTemp ) \
-	{ \
-		saved_registers += 1; /* r31 */ \
-	} \
-	frame_size = -SLOTSIZE * saved_registers; \
-	if( ((L)->type & Lfrommask) == Lrelative ) \
-	{ \
-		frame_size += (L)->from; \
-	} \
-	FILL_LABEL_Llong16noalign(P, frame_size, L); \
-}
-
-#define FILL_LABEL_Lframe(P, V, L, neg) \
-{ \
-	int frame_size = 0; \
-\
-	if( (firstConst != currConst) || maxLocal || maxTemp ) \
-	{ \
-		frame_size += SLOTSIZE; /* r31 */ \
-	} \
-	if( ((L)->type & Lfrommask) == Lrelative ) \
-		frame_size += (L)->from; \
-	if( neg ) \
-		frame_size = -frame_size; \
-	FILL_LABEL_Llong16noalign(P, frame_size, L); \
-}
-
-#define FILL_LABEL_Lreg_s(P, V, L) \
-{ \
-	ppc_code_t *_code = (ppc_code_t *)(P); \
-	int saved_registers; \
-\
-	saved_registers = (maxLocal + maxStack + maxTemp) - \
-		PPC_ARG_REGISTER_COUNT; \
-	if( saved_registers < 0 ) \
-		saved_registers = 0; \
-	if( (firstConst != currConst) || maxLocal || maxTemp ) \
-	{ \
-		saved_registers += 1; /* r31 */ \
-	} \
-	_code[0] |= PPC_SET_RS((32 - saved_registers)); \
-}
-
-#define EXTRA_LABELS(P, V, L) \
-	case Lframe: \
-		FILL_LABEL_Lframe(P, V, L, 0); \
-		break; \
-	case Lnegframe: \
-		FILL_LABEL_Lframe(P, V, L, 1); \
-		break; \
-	case Llong26: \
-		FILL_LABEL_Llong26(P, V, L); \
-		break; \
-	case Llong16: \
-		FILL_LABEL_Llong16(P, V, L); \
-		break; \
-	case Llong16noalign: \
-		FILL_LABEL_Llong16noalign(P, V, L); \
-		break; \
-	case Llong16x16: \
-		FILL_LABEL_Llong16x16(P, V, L); \
-		break; \
-	case Lsavedregs: \
-		FILL_LABEL_Lsavedregs(P, V, L); \
-		break; \
-	case Lreg_s: \
-		FILL_LABEL_Lreg_s(P, V, L); \
-		break;
-
 #define SLOTSIZE 4
 
 /* XXX */
@@ -256,7 +116,7 @@
 #define REGISTERS_SAVED 21
 
 #define SLOT2LOCALOFFSET(N) \
-	(-(SLOTSIZE * ((N) + 2)))
+	(unsigned long)(&((ppc_stack_frame_t *)0)->scratch[(N) - PPC_ARG_REGISTER_COUNT])
 
 #define SLOT2ARGOFFSET(N) \
 	(unsigned long)(&((ppc_stack_frame_t *)0)->args[(N)])
Index: kaffe/config/powerpc/jit3-icode.h
diff -u kaffe/config/powerpc/jit3-icode.h:1.1 kaffe/config/powerpc/jit3-icode.h:1.2
--- kaffe/config/powerpc/jit3-icode.h:1.1	Fri Sep 17 18:48:40 2004
+++ kaffe/config/powerpc/jit3-icode.h	Tue Dec 21 00:15:28 2004
@@ -1,7 +1,7 @@
 /* ppc/jit-icode.h
  * Define the instructions which are present on the PPC.
  *
- * Copyright (c) 2002 The University of Utah and the Flux Group.
+ * Copyright (c) 2002, 2004 The University of Utah and the Flux Group.
  * All rights reserved.
  *
  * @JANOSVM_KAFFE_JANOSVM_LICENSE@
@@ -25,7 +25,9 @@
 //
 #define	__U5const_rangecheck(v)		((v) >= 0 && (v) < 32)
 
-#define __I26const_rangecheck(x) ((((x) & 0xfc000000) == 0xffc000000) || (((x) & 0xffc000000) == 0))
+#define __I26const_rangecheck(x) \
+	(((((x) >> 2) & 0xfc000000) == 0xfc000000) || \
+	 ((((x) >> 2) & 0xfc000000) == 0))
 
 #define __S16const_rangecheck(v) ((-32768 <= (v)) && ((v) <= 32767))
 
@@ -118,7 +120,7 @@
 //
 #define	HAVE_call_ref			call_xCC
 #define	HAVE_call_ref_rangecheck(v)	__I26const_rangecheck(v)
-#undef HAVE_call_ref
+// #undef HAVE_call_ref
 
 #define	HAVE_call			call_xRC
 #define	HAVE_branch_indirect		branch_indirect_xRC
Index: kaffe/config/powerpc/jit3-powerpc.def
diff -u kaffe/config/powerpc/jit3-powerpc.def:1.1 kaffe/config/powerpc/jit3-powerpc.def:1.2
--- kaffe/config/powerpc/jit3-powerpc.def:1.1	Fri Sep 17 18:48:40 2004
+++ kaffe/config/powerpc/jit3-powerpc.def	Tue Dec 21 00:15:28 2004
@@ -2,13 +2,14 @@
 /*
  * jit3-powerpc.def
  *
- * Copyright (c) 2002 The University of Utah and the Flux Group.
+ * Copyright (c) 2002, 2004 The University of Utah and the Flux Group.
  * All rights reserved.
  *
  * @JANOSVM_KAFFE_JANOSVM_LICENSE@
  */
 
 #include "jit.h"
+#include "jit-labels.h"
 #include "icode.h"
 #include "ppc_isa.h"
 #include "code-analyse.h"
@@ -30,12 +31,12 @@
 #define ppc_op_ctxt CODEPC
 #undef ppc_op_debug
 #define ppc_op_debug(args) my_op_debug args
-int my_op_debug(int ctxt, char *fmt, ...)
+int my_op_debug(int ctxt, const char *fmt, ...)
 {
     va_list args;
     
     va_start(args, fmt);
-    fprintf(stderr, "%x\t", ctxt - 4);
+    fprintf(stderr, "%d\t", ctxt);
     vfprintf(stderr, fmt, args);
     fprintf(stderr, "\n");
     va_end(args);
@@ -44,7 +45,7 @@
 }
 #define DBOUT stderr
 
-#define debug(x) fprintf##x
+#define debug(x) fprintf x
 #else
 #define debug(x)
 #endif
@@ -99,12 +100,12 @@
 
 		localRegs = maxLocal + maxTemp + 1;
 		/*
-		 * We atleast need to save R31 because its used to hold the
+		 * We atleast need to save R31 because it's used to hold the
 		 * function base and thus the base for the constpool.
 		 */
 		if( localRegs == 1 )
 		{
-			LOUT(ppc_op_stw(PPC_R31, PPC_RSP, -SLOTSIZE));
+			LOUT(ppc_op_stw(PPC_R31, PPC_RSP, -SLOTSIZE-72));
 		}
 		else
 		{
@@ -121,15 +122,21 @@
 		}
 
 		/* Stuff the LR in the caller's linkage area. */
-		LOUT(ppc_op_stw(PPC_R0, PPC_RSP, PPC_FRAME_LR));		
-	}
-	if( has_pool )
-	{
+		LOUT(ppc_op_stw(PPC_R0, PPC_RSP, PPC_FRAME_LR));
+		
+		pl->type = Lnegframe | Labsolute | Lgeneral;
+		pl->at = CODEPC;
+		/*
+		 * Only update the stack pointer if we're not a
+		 * leaf.
+		 */
+		LOUT(ppc_op_stwu(PPC_RSP, PPC_RSP, 0)); // XXX
+		
 		/* Branch to the next instruction (no cost... i think) */
 		LOUT(ppc_op_bc(PPC_BO_ALWAYS,
-				 0,
-				 ppc_bd16(sizeof(ppc_code_t))) |
-			PPC_OPTION_LK);
+			       0,
+			       ppc_bd16(sizeof(ppc_code_t))) |
+		     PPC_OPTION_LK);
 		/*
 		 * The link register points to the internals of this method
 		 * save it and the offset from the start of the function.
@@ -148,6 +155,12 @@
 		int dbl_skip = 0, limit = PPC_ARG_REGISTER_COUNT;
 		int lpc, gpr_off = 0, fpr_off;
 
+		
+	{
+		void printSlots(FILE *file);
+
+		// printSlots(stderr);
+	}
 		if( !isStatic )
 		{
 			/* Prepend "this" argument. */
@@ -159,6 +172,8 @@
 		/* Figure out the number of arguments in registers. */
 		if( METHOD_NARGS(meth) < limit )
 			limit = METHOD_NARGS(meth);
+
+#if defined(__APPLE__)
 		/*
 		 * Force argument slots to correspond to the appropriate
 		 * registers.  On darwin, this means we skip gpr's when floats
@@ -205,6 +220,52 @@
 				break;
 			}
 		}
+#else
+		for( lpc = 0, fpr_off = 0; lpc < limit; lpc++ )
+		{
+			switch( *METHOD_ARG_TYPE(meth, lpc) )
+			{
+			case 'D':
+				preloadRegister(localinfo[lpc + dbl_skip].slot,
+						Rdouble,
+						PPC_FPRARG0 + fpr_off);
+				dbl_skip++;
+				fpr_off++;
+				break;
+			case 'F':
+				preloadRegister(localinfo[lpc + dbl_skip].slot,
+						Rfloat,
+						PPC_FPRARG0 + fpr_off);
+				fpr_off++;
+				break;
+			case 'L':
+			case '[':
+				preloadRegister(localinfo[lpc + dbl_skip].slot,
+						Rref,
+						PPC_RARG0 + gpr_off);
+				gpr_off++;
+				break;
+			case 'J':
+				preloadRegister(localinfo[lpc + dbl_skip].slot,
+						Rint,
+						PPC_RARG0 + gpr_off);
+				gpr_off++;
+				dbl_skip++;
+				/* FALLTHROUGH */
+			default:
+				preloadRegister(localinfo[lpc + dbl_skip].slot,
+						Rint,
+						PPC_RARG0 + gpr_off);
+				gpr_off++;
+				break;
+			}
+		}
+#endif
+	{
+		void printSlots(FILE *file);
+
+		// printSlots(stderr);
+	}
 	}
 }
 
@@ -212,6 +273,14 @@
 {
 	if( r31FunctionStartOffset > 0 )
 	{
+#if 1
+#elif 1
+		label *l = newLabel();
+
+		l->type = Lframe | Labsolute | Lgeneral;
+		l->at = CODEPC;
+		LOUT(ppc_op_lmw(14, PPC_RSP, 0));
+#else
 		label *l = const_label(1);
 
 		l->type = Linternal | Labsolute | Llong16x16;
@@ -220,15 +289,14 @@
 		l->to = r31FunctionStartOffset;
 		LOUT(ppc_op_li(PPC_RCONST_POOL, 0));
 		LOUT(ppc_op_addis(PPC_RCONST_POOL, PPC_RCONST_POOL, 0));
+#endif
 
-		debug((DBOUT,"epilogue %s\n",getLabelName(l)));
+		// debug((DBOUT,"exception_prologue %s\n",getLabelName(l)));
 	}
 }
 
 define_insn(epilogue, epilogue_xxx)
 {
-	extern label *getLastEpilogueLabel(void);
-	
 	label *el;
 
 	if( (el = getLastEpilogueLabel()) && (el->at == (CODEPC - 4)) )
@@ -246,6 +314,51 @@
 	}
 	setEpilogueLabel(CODEPC);
 	
+	if( (firstConst != currConst) ||
+	    maxLocal ||
+	    maxTemp )
+	{
+		int lrOffset = 0, localRegs;
+		label *fl;
+
+		fl = newLabel();
+		fl->type = Lframe | Lrelative | Lgeneral;
+		fl->at = CODEPC;
+		fl->from = PPC_FRAME_LR;
+		fl->to = 0;
+
+		/*
+		 * Load the original LR back into R0.
+		 *
+		 * Note: We do the load early so it can run in parallel while
+		 * we readjust the stack pointer.
+		 */
+		LOUT(ppc_op_lwz(PPC_R0, PPC_RSP, lrOffset));
+		fl = newLabel();
+		fl->type = Lframe | Labsolute | Lgeneral;
+		fl->at = (uintp)CODEPC;
+		LOUT(ppc_op_addi(PPC_RSP, PPC_RSP, 0));
+		LOUT(ppc_op_mtlr(PPC_R0));
+		/* Restore and local registers. */
+		localRegs = maxLocal + maxTemp + 1;
+		if( localRegs == 1 )
+		{
+			LOUT(ppc_op_lwz(PPC_R31, PPC_RSP, -4-72));
+		}
+		else
+		{
+			label *l;
+
+			l = newLabel();
+			l->type = Lsavedregs | Labsolute | Lgeneral;
+			l->at = CODEPC;
+			l->to = 0;
+			l = newLabel();
+			l->type = Lreg_s | Labsolute | Lgeneral;
+			l->at = CODEPC;
+			LOUT(ppc_op_lmw(0, PPC_RSP, 0));
+		}
+	}
 	/* Branch back to the caller. */
 	LOUT(ppc_op_blr());
 }
@@ -281,14 +394,18 @@
 	int r = sreg_int(0);
 	int o = const_int(1);
 	label *l;
-
+	
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	LOUT(ppc_op_stw(r, PPC_RSP, 0));
-
+	
+	{
+		void printSlots(FILE *file);
+		
+		// printSlots(stderr);
+	}
 	debug((DBOUT,"spill_int %d, [FP, %d(%p)]\n", r, o,
 	       seq_slot(s, 1)));
 }
@@ -300,10 +417,9 @@
 	label *l;
 
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	LOUT(ppc_op_stfs(r, PPC_RSP, 0));
 
 	debug((DBOUT,"spill_float %d, [FP, %d]\n", r, o));
@@ -316,10 +432,9 @@
 	label *l;
 
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	/* XXX Alignment needed here?  e.g. o >> 2 */
 	LOUT(ppc_op_stfd(r, PPC_RSP, 0));
 
@@ -331,12 +446,11 @@
 	int r = lreg_int(0);
 	int o = const_int(1);
 	label *l;
-
+		
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	LOUT(ppc_op_lwz(r, PPC_RSP, 0));
 	
 	debug((DBOUT,"reload_int %d, [FP, %d(%p)]\n", r, o,
@@ -350,10 +464,9 @@
 	label *l;
 
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	LOUT(ppc_op_lfs(r, PPC_RSP, 0));
 
 	debug((DBOUT,"reload_float %d, [FP, %d]\n", r, o));
@@ -366,10 +479,9 @@
 	label *l;
 
 	l = newLabel();
-	l->type = Lframe | Lrelative | Lgeneral;
+	l->type = Llong16noalign | Lexternal | Labsolute;
 	l->at = CODEPC;
-	l->to = 0;
-	l->from = o;
+	l->to = o;
 	LOUT(ppc_op_lfd(r, PPC_RSP, 0));
 	
 	debug((DBOUT,"reload_double %d, [FP, %d]\n", r, o));
@@ -1231,8 +1343,8 @@
 	tmp_gpr = tmp_si_gpr->slot;
 	slot_alloc2tmp(tmp_si_fpr);
 	tmp_fpr = tmp_si_fpr->slot;
-	hi_offset = 0;
-	lo_offset = 0;
+	hi_offset = -8;
+	lo_offset = -4;
 	/* Build the most significant bits. */
 	LOUT(ppc_op_lis(PPC_R0, 0x4330));
 	/* Store them as if making a double. */
@@ -1302,8 +1414,8 @@
 	tmp_gpr = tmp_si_gpr->slot;
 	slot_alloc2tmp(tmp_si_fpr);
 	tmp_fpr = tmp_si_fpr->slot;
-	hi_offset = 0;
-	lo_offset = 0;
+	hi_offset = -8;
+	lo_offset = -4;
 	LOUT(ppc_op_lis(PPC_R0, 0x4330));
 	if( !hi_offset )
 	{
@@ -1365,8 +1477,8 @@
 	/* Allocate a temporary float to store the converted number. */
 	slot_alloc2tmp(tmp_si);
 	tmp = tmp_si->slot;
-	hi_offset = 0;
-	lo_offset = 0;
+	hi_offset = -8;
+	lo_offset = -4;
 
 	/* Bind to a register. */
 	i = slotRegister(tmp, Rdouble, rwrite, NOREG);
@@ -1418,8 +1530,8 @@
 	/* Allocate a temporary float to store the converted number. */
 	slot_alloc2tmp(tmp_si);
 	tmp = tmp_si->slot;
-	hi_offset = 0;
-	lo_offset = 0;
+	hi_offset = -8;
+	lo_offset = -4;
 
 	/* Bind to a register. */
 	i = slotRegister(tmp, Rdouble, rwrite, NOREG);
@@ -1603,36 +1715,36 @@
 		 * be the case.
 		 */
 		LOUT(ppc_op_bc(PPC_BO_TRUE(0),
-				 PPC_BI_CR_0 | PPC_BI_EQ,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_EQ,
+			       0) | PPC_OPTION_LK);
 		break;
 	case bne:
 		LOUT(ppc_op_bc(PPC_BO_FALSE(0),
-				 PPC_BI_CR_0 | PPC_BI_EQ,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_EQ,
+			       0) | PPC_OPTION_LK);
 		break;
 	case blt:
 	case bult:
 		LOUT(ppc_op_bc(PPC_BO_TRUE(0),
-				 PPC_BI_CR_0 | PPC_BI_LT,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_LT,
+			       0) | PPC_OPTION_LK);
 		break;
 	case ble:
 		LOUT(ppc_op_bc(PPC_BO_FALSE(0),
-				 PPC_BI_CR_0 | PPC_BI_GT,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_GT,
+			       0) | PPC_OPTION_LK);
 		break;
 	case bgt:
 	case bugt:
 		LOUT(ppc_op_bc(PPC_BO_TRUE(0),
-				 PPC_BI_CR_0 | PPC_BI_GT,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_GT,
+			       0) | PPC_OPTION_LK);
 		break;
 	case bge:
 	case buge:
 		LOUT(ppc_op_bc(PPC_BO_FALSE(0),
-				 PPC_BI_CR_0 | PPC_BI_LT,
-				 0) | PPC_OPTION_LK);
+			       PPC_BI_CR_0 | PPC_BI_LT,
+			       0) | PPC_OPTION_LK);
 		break;
 	default:
 		ABORT();
@@ -1647,46 +1759,33 @@
 //
 define_insn(call_ref, call_xCC)
 {
-#if 1
-#else
-	label* l = const_label(1);
-	unsigned long dest = 0;
-	long relative = CODEPC-dest;
-	long highpart = relative & 0xffffff;
-	
-	assert(const_int(2) == dest);
-
-	//
-	// Determine if the relative address will fit in a 24-bit displacement
-	//
-	if (  highpart == 0xff000000 || highpart == 0 ) {
-	  //
-	  // Yes, it's likely to fit
-	  //
-	  l->type |= Llong26|Lrelative;
-	  l->at = CODEPC;
-	  l->from = CODEPC + 8;
-	  op_branch_linked(CC_AL, 0);
-	} else {
-	  int w = 0;
-	  assert("Should not happen");
-	  //
-	  // No, it's not going to fit..
-	  //
-	  op_mov_c(w, dest & 0x000000FF, 0);
-	  op_add_c(w, w, (dest >> 8) & 0x000000FF, 24);
-	  op_add_c(w, w, (dest >> 16) & 0x000000FF, 16);
-	  op_add_c(w, w, (dest >> 24) & 0x000000FF, 8);
-	}
-#endif
-	debug((DBOUT,"call_ref\n"));
+	label *sl, *l = const_label(1);
+
+	sl = newLabel();
+	sl->type = Lframe | Lrelative | Lgeneral;
+	sl->at = CODEPC;
+	sl->from = -72;
+	LOUT(ppc_op_stmw(14, PPC_RSP, 0));
+
+	l->type |= Lrelative | Llong26;
+	l->at = CODEPC;
+	l->from = CODEPC;
+	LOUT(ppc_op_b(0) | PPC_OPTION_LK);
+	
+	debug((DBOUT,"call_ref %p\n",l->to));
 }
 
 define_insn(call, call_xRC)
 {
+	label *l = newLabel();
 	int r = rreg_int(1);

*** Patch too long, truncated ***



More information about the kaffe mailing list