[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