[m-dev.] diff: changes to runtime/machdeps

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Dec 26 17:04:41 AEDT 1999


I did this stuff when I was trying to get things to work with
`-mflat' on SPARCs.

----------

Estimated hours taken: 1

runtime/machdeps/regtest.c:
runtime/machdeps/regtest2.c:
runtime/machdeps/doregtest:
	Add some more tests.

runtime/machdeps/SPARC_REGS:
	Update the commentary here to reflect more a recent version
	of GNU C.

Workspace: /mount/munkora/mercury1/fjh/mercury-sparc
Index: runtime/machdeps/SPARC_REGS
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/machdeps/SPARC_REGS,v
retrieving revision 1.2
diff -u -d -r1.2 SPARC_REGS
--- SPARC_REGS	1995/09/09 03:51:29	1.2
+++ SPARC_REGS	1999/10/17 11:38:46
@@ -14,12 +14,33 @@
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
-   g0 is used for the condition code and not to represent %g0, which is
-   hardwired to 0, so reg 0 is *not* fixed.
-   g1 through g4 are free to use as temporaries.
-   g5 through g7 are reserved for the operating system.  */
+
+   On non-v9 systems:
+   g1 is free to use as temporary.
+   g2-g4 are reserved for applications.  Gcc normally uses them as
+   temporaries, but this can be disabled via the -mno-app-regs option.
+   g5 through g7 are reserved for the operating system.
+
+   On v9 systems:
+   g1,g5 are free to use as temporaries, and are free to use between calls
+   if the call is to an external function via the PLT.
+   g4 is free to use as a temporary in the non-embedded case.
+   g4 is reserved in the embedded case.
+   g2-g3 are reserved for applications.  Gcc normally uses them as
+   temporaries, but this can be disabled via the -mno-app-regs option.
+   g6-g7 are reserved for the operating system (or application in
+   embedded case).
+   ??? Register 1 is used as a temporary by the 64 bit sethi pattern, so must
+   currently be a fixed register until this pattern is rewritten.
+   Register 1 is also used when restoring call-preserved registers in large
+   stack frames.
+
+   Registers fixed in arch32 and not arch64 (or vice-versa) are marked in
+   CONDITIONAL_REGISTER_USAGE in order to properly handle -ffixed-.
+*/
+
 #define FIXED_REGISTERS  \
- {0, 0, 0, 0, 0, 1, 1, 1,	\
+ {1, 0, 0, 0, 0, 0, 1, 1,	\
   0, 0, 0, 0, 0, 0, 1, 0,	\
   0, 0, 0, 0, 0, 0, 0, 0,	\
   0, 0, 0, 0, 0, 0, 1, 1,	\
@@ -27,7 +48,14 @@
   0, 0, 0, 0, 0, 0, 0, 0,	\
   0, 0, 0, 0, 0, 0, 0, 0,	\
   0, 0, 0, 0, 0, 0, 0, 0,	\
-  0, 0, 0, 0, 0, 0, 0, 0}
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+  0, 0, 0, 0, 0, 0, 0, 0,	\
+				\
+  0, 0, 0, 0, 0}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -35,6 +63,7 @@
    The latter must include the registers where values are returned
    and the register where structure-value addresses are passed.
    Aside from that, you can include as many other registers as you like.  */
+
 #define CALL_USED_REGISTERS  \
  {1, 1, 1, 1, 1, 1, 1, 1,	\
   1, 1, 1, 1, 1, 1, 1, 1,	\
@@ -44,4 +73,73 @@
   1, 1, 1, 1, 1, 1, 1, 1,	\
   1, 1, 1, 1, 1, 1, 1, 1,	\
   1, 1, 1, 1, 1, 1, 1, 1,	\
-  1, 1, 1, 1, 1, 1, 1, 1}
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+  1, 1, 1, 1, 1, 1, 1, 1,	\
+				\
+  1, 1, 1, 1, 1}
+
+/* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
+   they won't be allocated.  */
+
+#define CONDITIONAL_REGISTER_USAGE				\
+do								\
+  {								\
+    if (TARGET_ARCH32)						\
+      {								\
+	fixed_regs[5] = 1;					\
+      }								\
+    else							\
+      {								\
+	fixed_regs[1] = 1;					\
+      }								\
+    if (! TARGET_V9)						\
+      {								\
+	int regno;						\
+	for (regno = SPARC_FIRST_V9_FP_REG;			\
+	     regno <= SPARC_LAST_V9_FP_REG;			\
+	     regno++)						\
+	  fixed_regs[regno] = 1;				\
+	/* %fcc0 is used by v8 and v9.  */			\
+	for (regno = SPARC_FIRST_V9_FCC_REG + 1;		\
+	     regno <= SPARC_LAST_V9_FCC_REG;			\
+	     regno++)						\
+	  fixed_regs[regno] = 1;				\
+      }								\
+    if (! TARGET_FPU)						\
+      {								\
+	int regno;						\
+	for (regno = 32; regno < SPARC_LAST_V9_FCC_REG; regno++) \
+	  fixed_regs[regno] = 1;				\
+      }								\
+    /* Don't unfix g2-g4 if they were fixed with -ffixed-.  */	\
+    fixed_regs[2] |= ! TARGET_APP_REGS;				\
+    fixed_regs[3] |= ! TARGET_APP_REGS;				\
+    fixed_regs[4] |= ! TARGET_APP_REGS || TARGET_CM_EMBMEDANY;	\
+    if (TARGET_FLAT)						\
+      {								\
+	/* Let the compiler believe the frame pointer is still	\
+	   %fp, but output it as %i7.  */			\
+	fixed_regs[31] = 1;					\
+	reg_names[FRAME_POINTER_REGNUM] = "%i7";		\
+	/* ??? This is a hack to disable leaf functions.  */	\
+	global_regs[7] = 1;					\
+      }								\
+    if (profile_block_flag)					\
+      {								\
+	/* %g1 and %g2 must be fixed, because BLOCK_PROFILER	\
+	    uses them.  */					\
+	fixed_regs[1] = 1;					\
+	fixed_regs[2] = 1;					\
+      }								\
+    if (flag_pic != 0)						\
+      {								\
+        fixed_regs[23] = 1;					\
+        call_used_regs[23] = 1;					\
+      }								\
+  }								\
+while (0)
+
Index: runtime/machdeps/doregtest
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/machdeps/doregtest,v
retrieving revision 1.2
diff -u -d -r1.2 doregtest
--- doregtest	1995/07/21 09:45:09	1.2
+++ doregtest	1999/12/26 06:00:01
@@ -8,10 +8,30 @@
     exit 1
 fi
 
-if ../../scripts/mgnuc "-DREG=\"$1\"" regtest.c -o /tmp/regtest$$ -lm &&
+CFLAGS=
+PIC_CFLAGS=	$CFLAGS -fpic
+
+echo Trying register "$1"...
+if ../../scripts/mgnuc $CFLAGS "-DREG=\"$1\"" regtest.c regtest2.c -o /tmp/regtest$$ -lm &&
    [ -x /tmp/regtest$$ ] && /tmp/regtest$$
 then
-	true
+	if ../../scripts/mgnuc $PIC_CFLAGS "-DREG=\"$1\"" regtest.c regtest2.c \
+		-o /tmp/regtest$$ -lm &&
+	   [ -x /tmp/regtest$$ ] && /tmp/regtest$$
+	then
+		echo "Register $1 seems to work OK"
+	else
+		if ../../scripts/mgnuc -g $CFLAGS "-DREG=\"$1\"" -c regtest.c &&
+		   ../../scripts/mgnuc -g $PIC_CFLAGS -c regtest2.c &&
+		   ../../scripts/mgnuc -g regtest.o regtest2.o -o /tmp/regtest$$ -lm &&
+		   [ -x /tmp/regtest$$ ] && /tmp/regtest$$
+		then
+			echo "Register $1 can't be used in PIC mode"
+		else
+			echo "Register $1 can't be used in PIC mode, and"
+			echo "register $1 also gets clobbered when you merely call PIC code."
+		fi
+	fi
 else
 	echo "Register $1 can't be used"
 fi
Index: runtime/machdeps/regtest.c
===================================================================
RCS file: /home/staff/zs/imp/mercury/runtime/machdeps/regtest.c,v
retrieving revision 1.4
diff -u -d -r1.4 regtest.c
--- regtest.c	1997/11/13 11:12:18	1.4
+++ regtest.c	1999/10/17 11:32:29
@@ -24,9 +24,40 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
+#include <assert.h>
 
 FILE *f;
 
+/* defined in regtest2.c */
+extern void extern_clobber_regs_in_func(void);
+extern void extern_call_func_with_args(
+	int x1, int x2, int x3, int x4,
+	int y1, int y2, int y3, int y4,
+	double f1, double f2, double f3, double f4
+);
+
+static void 
+call_func_with_args(
+	int x1, int x2, int x3, int x4,
+	int y1, int y2, int y3, int y4,
+	double f1, double f2, double f3, double f4
+) {
+	assert(
+		x1 == 1 &&
+		x2 == 2 &&
+		x3 == 3 &&
+		x4 == 4 &&
+		y1 == 5 &&
+		y2 == 6 &&
+		y3 == 7 &&
+		y4 == 8 &&
+		f1 == 10.0 &&
+		f2 == 20.0 &&
+		f3 == 30.0 &&
+		f4 == 40.0
+	);
+}
+
 /* Do a variety of stuff that might clobber the registers */
 
 #define clobber_regs()				\
@@ -38,6 +69,8 @@
 	x = sin(x);				\
 	x = pow(x,1.5);				\
 	malloc(100);				\
+	call_func_with_args(1,2,3,4,5,6,7,8,10.0,20.0,30.0,40.0); \
+	extern_call_func_with_args(1,2,3,4,5,6,7,8,10.0,20.0,30.0,40.0); \
 	system("/bin/true");			\
 } while (0)
 
@@ -75,6 +108,18 @@
 		return 0;
 	}
 
+	r = 0x12345678u;
+	extern_clobber_regs_in_func();
+	if (r != 0x12345678u) {
+		return 0;
+	}
+
+	r = 0x87654321u;
+	extern_clobber_regs_in_func();
+	if (r != 0x87654321u) {
+		return 0;
+	}
+
 	return 1;
 }
 
@@ -84,14 +129,14 @@
 	f = fopen("/dev/null", "w");
 	if (!f) {
 		printf("can't open /dev/null?\n");
-		return 0;
+		return 1;
 	}
 
 	if (test_reg()) {
-		printf("Register %s seems to work ok.\n", REG);
+		printf("Test of register %s passed.\n", REG);
+		return 0;
 	} else {
 		printf("Register %s got clobbered.\n", REG);
+		return 1;
 	}
-
-   return 0;
 }
Index: runtime/machdeps/regtest2.c
===================================================================
RCS file: regtest2.c
diff -N regtest2.c
--- /dev/null	Sun Dec 26 16:57:40 1999
+++ regtest2.c	Sun Oct 17 21:09:39 1999
@@ -0,0 +1,68 @@
+/*
+** Copyright (C) 1993, 1997 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** regtest2.c - part of the regtest.c program.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+
+extern FILE *f;
+int global;
+
+void extern_clobber_regs_in_func(void);
+void extern_call_func_with_args(
+	int x1, int x2, int x3, int x4,
+	int y1, int y2, int y3, int y4,
+	double f1, double f2, double f3, double f4
+);
+
+void 
+extern_call_func_with_args(
+	int x1, int x2, int x3, int x4,
+	int y1, int y2, int y3, int y4,
+	double f1, double f2, double f3, double f4
+) {
+	assert(
+		x1 == 1 &&
+		x2 == 2 &&
+		x3 == 3 &&
+		x4 == 4 &&
+		y1 == 5 &&
+		y2 == 6 &&
+		y3 == 7 &&
+		y4 == 8 &&
+		f1 == 10.0 &&
+		f2 == 20.0 &&
+		f3 == 30.0 &&
+		f4 == 40.0
+	);
+}
+
+/* Do a variety of stuff that might clobber the registers */
+
+#define clobber_regs()				\
+do {						\
+	double x = 1.5;				\
+	int i = 35;				\
+						\
+	fprintf(f, "Hello, world %d\n", i);	\
+	x = sin(x + global);			\
+	global = (int) x;			\
+	x = pow(x,1.5);				\
+	malloc(100);				\
+	extern_call_func_with_args(1,2,3,4,5,6,7,8,10.0,20.0,30.0,40.0); \
+	system("/bin/true");			\
+} while (0)
+
+void 
+extern_clobber_regs_in_func(void) {
+	clobber_regs();
+}
+

-- 
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list