[m-dev.] for review: add MR_virtual_hp, MR_virtual_sp, etc.

Fergus Henderson fjh at cs.mu.OZ.AU
Wed May 6 18:31:34 AEST 1998


On 15-Apr-1998, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> 
> > +#ifdef USE_CONSERVATIVE_GC
> > +  #define incr_saved_hp(A, B) incr_hp(A, B)
> > +  #define incr_saved_hp_atomic(A, B) incr_hp_atomic(A, B)
> 
> Make the macro bodies line up, and add a comment saying that the
> reason why the "saved" part has no effect is that there is in fact
> no hp registers.

Actually there was another problem with this part of my change:
incr_saved_hp actually increments the saved hp iff the hp is
in a transient register; otherwise, it increments the register.

So I just removed that part of the change.

> There is a subtle problem with your diff. The purpose of these changes
> is to fix the XXX problem in mercury_trace_util.c, but defining MR_virtual*
> to refer to fake_reg is not what is wanted there. Instead that code wants to
> refer to MR_saved_regs, because this has the values from the event, and
> fake_reg will not, except when displaying the value of the first variable
> (since fake_reg will be overwritten by the display routine itself).

In addition to the MR_virtual_<foo> macros (which access fake_reg),
I have also added MR_saved_<foo> macros, which take the save_area as
a parameter.  The MR_virtual_<foo> macros are defined in terms
of the MR_saved_<foo> ones.

Here's a new diff.

Estimated hours taken: 3

runtime/mercury_regorder.h:
	Add macros MR_saved_sp(save_area), MR_saved_hp(save_area) etc.
	which access the underlying slot in the specified save_area
	rather than the real machine register.

runtime/mercury_regs.h:
	Add definitions for MR_virtual_sp, MR_virtual_hp, etc.
	which access the underlying slot in fake_reg
	rather than the real machine register.
	Add some more comments and move some code around, so as to
	clearly delineate between the different abstraction layers.

cvs diff: Diffing .
Index: mercury_regorder.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regorder.h,v
retrieving revision 1.3
diff -u -u -r1.3 mercury_regorder.h
--- mercury_regorder.h	1998/04/08 11:34:01	1.3
+++ mercury_regorder.h	1998/05/06 08:09:56
@@ -22,6 +22,10 @@
 #ifndef MERCURY_REGORDER_H
 #define MERCURY_REGORDER_H
 
+/*
+** If you modify the r<N> to mr<N> mapping, make sure that you update
+** the definition of MR_VIRTUAL_REG_MAP_BODY below.
+*/
 #define r1		count_usage(R_RN(1), mr2)
 #define r2		count_usage(R_RN(2), mr3)
 #define r3		count_usage(R_RN(3), mr4)
@@ -57,33 +61,49 @@
 
 /*
 ** If you modify the following block, make sure that you update
-** the definitions of MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR.
+** the definitions of MR_NUM_SPECIAL_REG, MR_MAX_SPECIAL_REG_MR,
+** and MR_saved_*.
 */
-
 #define MR_succip	LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
-#define succip		MR_succip
 #define MR_hp		LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
-#define hp		MR_hp
 #define MR_sp		LVALUE_CAST(Word *, count_usage(MR_SP_RN, mr0))
-#define sp		MR_sp
 #define MR_curfr	LVALUE_CAST(Word *, count_usage(MR_CF_RN, mr8))
-#define curfr		MR_curfr
 #define MR_maxfr	LVALUE_CAST(Word *, count_usage(MR_MF_RN, mr9))
-#define maxfr		MR_maxfr
 #define MR_sol_hp	LVALUE_CAST(Word *, count_usage(MR_SOL_HP_RN, mr(37)))
 #define MR_min_hp_rec	LVALUE_CAST(Word *, count_usage(MR_MIN_HP_REC, mr(38)))
 #define MR_min_sol_hp_rec	LVALUE_CAST(Word *,	\
 			count_usage(MR_MIN_HP_REC, mr39))
-
 #define MR_trail_ptr	count_usage(MR_TRAIL_PTR_RN, MR_trail_ptr_var)
 #define MR_ticket_counter	 \
 		count_usage(MR_TICKET_COUNTER_RN, MR_ticket_counter_var)
 
+/* for backwards compatibility */
+#define succip		MR_succip
+#define hp		MR_hp
+#define sp		MR_sp
+#define curfr		MR_curfr
+#define maxfr		MR_maxfr
+
 /* the number of special, non rN registers */
 #define MR_NUM_SPECIAL_REG	10
 
 /* the maximum mrN number of special, non rN registers */
 #define	MR_MAX_SPECIAL_REG_MR	39
+
+/*
+** The MR_saved_foo macros are like MR_foo except that
+** they access the underlying fake_reg slot rather than
+** the real machine register.
+*/
+
+#define MR_saved_succip(save_area)	LVALUE_CAST(Code *, save_area[1])
+#define MR_saved_hp(save_area)		LVALUE_CAST(Word *, save_area[5])
+#define MR_saved_sp(save_area)		LVALUE_CAST(Word *, save_area[0])
+#define MR_saved_curfr(save_area)	LVALUE_CAST(Word *, save_area[8])
+#define MR_saved_maxfr(save_area)	LVALUE_CAST(Word *, save_area[9])
+#define MR_saved_sol_hp(save_area)	LVALUE_CAST(Word *, save_area[37])
+#define MR_saved_min_hp_rec(save_area)	LVALUE_CAST(Word *, save_area[38])
+#define MR_saved_min_sol_hp_rec(save_area) LVALUE_CAST(Word *, save_area[39])
 
 #define VIRTUAL_REG_MAP_BODY	{ \
 	2, \
Index: mercury_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regs.h,v
retrieving revision 1.5
diff -u -u -r1.5 mercury_regs.h
--- mercury_regs.h	1998/02/04 03:55:27	1.5
+++ mercury_regs.h	1998/05/06 08:21:00
@@ -10,6 +10,7 @@
 #include "mercury_conf.h"
 #include "mercury_types.h"
 
+/*---------------------------------------------------------------------------*/
 /*
 ** GNU C allows lvalue casts, so if we have gcc, use them.
 ** If we don't have gcc, then we can use *(type *)&lval,
@@ -28,33 +29,60 @@
   #define LVALUE_COND(expr, x, y)	(*((expr)?&(x):&(y)))
 #endif
 
+/*---------------------------------------------------------------------------*/
 /*
 ** The registers of the Mercury virtual machine are built up using
 ** three levels of abstraction.
 **
-** The first level defines the first NUM_REAL_REGS register variables
-** mr0, mr1, etc. as the physical machine registers, and defines an
-** array fake_regs[n] of pseudo registers.
+** The bottom level is the hardware description layer. 
+** This layer is defined separately for each architecture,
+** in the header files in the machdeps subdirectory.
+** The hardware description layer defines the first NUM_REAL_REGS register
+** variables mr0, mr1, etc. as the physical machine registers, and defines an
+** array fake_regs[n] of pseudo registers, with the remaining "registers"
+** mr<NUM_REAL_REGS>, ..., mr36 defined as corresponding slots in
+** this fake_reg array. 
+** This level also provides the macros save_regs_to_mem(),
+** save_transient_regs_to_mem(), restore_regs_from_mem(),
+** and restore_transient_regs_from_mem().
+**
+** The next level is the hardware abstraction layer.
+** The hardware abstraction layer is at a similar level to the
+** hardware description layer, and includes that as a subset,
+** but in addition it provides a few more conveniences.
+** This layer defines macros mr(n) for n>36, and the macros
+** save_registers(), restore_registers(), save_transient_registers(),
+** and restore_transient_registers().
+** This layer is defined here in mercury_regs.h.
 **
-** The next level defines macros mr0 through mr36 and also mr(n) for
-** n>36.  The lower the number,
+** The hardware abstraction layer thus provides a very large number
+** of registers, which may be either real or fake.  The lower the number,
 ** the greater the probability that the storage referred to will be
 ** a real machine register, and not a simulated one. The number of
 ** real machine registers is given by the macro NUM_REAL_REGS.
 **
-** The final level maps the Mercury virtual machine registers
+** The final level is the Mercury abstract machine registers layer.
+** This layer maps the Mercury virtual machine registers
 **
-**	succip, hp, sp, curfr, maxfr and
+**	MR_succip, MR_hp, MR_sp, MR_curfr, MR_maxfr and
 **	r1, ..., r32, r(33), ..., r(MAX_VIRTUAL_REG)
 **
 ** to the set mr0..mr36, mr(37), mr(38), ..., mr(MAX_FAKE_REG-1)
+** which were provided by the hardware abstraction layer.
+** It also provides MR_virtual_r(), MR_virtual_succip, MR_virtual_hp, etc.,
+** which are similar to mr<N>, MR_succip, MR_hp, etc. except that they
+** always map to the underlying fake_reg rather than to the physical register.
 **
 ** Since the set of most frequently used Mercury virtual machine
-** registers can be different for each program, we want to make
+** registers can be different for each program or grade, we want to make
 ** this mapping as easy to change as possible. This is why the
 ** map is in a minimal header file, mercury_regorder.h.
 */
 
+/*---------------------------------------------------------------------------*/
+/*
+** The hardware description layer
+*/
 #if defined(USE_GCC_GLOBAL_REGISTERS)
   #ifndef __GNUC__
     #error "You must use gcc if you define USE_GCC_GLOBAL_REGISTERS."
@@ -79,24 +107,17 @@
     #include "machdeps/no_regs.h"
 #endif
 
+/*---------------------------------------------------------------------------*/
+/*
+** Extra stuff for the hardware abstraction layer
+*/
+
 /* The machdeps header defines mr0 .. mr36; now define mr(n) for n > 36 */
 
 #define mr(n) LVALUE_SEQ(MR_assert((n) >= MAX_REAL_REG + NUM_SPECIAL_REG && \
-				(n) < MAX_FAKE_REG),\
+				(n) < MAX_FAKE_REG), \
 		fake_reg[n])
 
-#ifdef MEASURE_REGISTER_USAGE
-  #define count_usage(num,reg)		LVALUE_SEQ(num_uses[num]++, reg)
-#else
-  #define count_usage(num,reg)		(reg)
-#endif
-
-#include	"mercury_regorder.h"
-
-/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
-
-#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
-
 /* 
 ** the save_registers() macro copies the physical machine registers
 ** to their corresponding slots in the fake_reg array 
@@ -122,20 +143,44 @@
 #define save_transient_registers()    save_transient_regs_to_mem(fake_reg)
 #define restore_transient_registers() restore_transient_regs_from_mem(fake_reg)
 
-/* virtual_reg(n) accesses the underlying fake_reg for register n */
+/*---------------------------------------------------------------------------*/
+/*
+** The Mercury abstract machine registers layer
+*/
 
-#define virtual_reg(n)	\
-	LVALUE_COND((n) > MAX_REAL_REG, \
-		r(n), \
-		fake_reg[virtual_reg_map[(n) - 1]])
+#ifdef MEASURE_REGISTER_USAGE
+  #define count_usage(num,reg)		LVALUE_SEQ(num_uses[num]++, reg)
+#else
+  #define count_usage(num,reg)		(reg)
+#endif
+
+#include	"mercury_regorder.h"
 
-/* saved_reg(save_area, n) is like virtual_reg, except in that */
-/* it accesses the given save area instead of the machine regs and fake_reg */
+/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
 
+#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
+
+/*
+** saved_reg(save_area, n) accesses the underlying slot in save_area
+** for register n
+*/
 #define saved_reg(save_area, n)	\
 	LVALUE_COND((n) > MAX_REAL_REG, \
 		save_area[(n) + NUM_SPECIAL_REG - 1], \
 		save_area[virtual_reg_map[(n) - 1]])
+
+/* virtual_reg(n) accesses the underlying fake_reg for register n */
+/* similarly MR_virtual_foo access the underlying fake_reg slot for foo */
+
+#define virtual_reg(n) 			saved_reg(fake_reg, n)
+#define MR_virtual_succip 		MR_saved_succip(fake_reg)
+#define MR_virtual_hp 			MR_saved_hp(fake_reg)
+#define MR_virtual_sp 			MR_saved_sp(fake_reg)
+#define MR_virtual_curfr 		MR_saved_curfr(fake_reg)
+#define MR_virtual_maxfr 		MR_saved_maxfr(fake_reg)
+#define MR_virtual_sol_hp 		MR_saved_sol_hp(fake_reg)
+#define MR_virtual_min_hp_rec 		MR_saved_min_hp_rec(fake_reg)
+#define MR_virtual_min_sol_hp_rec 	MR_saved_min_sol_hp_rec(fake_reg)
 
 /*
 ** get_reg() and set_reg() provide a different way of addressing
cvs diff: Diffing machdeps


-- 
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