File: regs.h

package info (click to toggle)
rscheme 0.7.2-1.1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 10,672 kB
  • ctags: 12,430
  • sloc: lisp: 37,104; ansic: 29,763; cpp: 2,630; sh: 1,677; makefile: 568; yacc: 202; lex: 175; perl: 33
file content (218 lines) | stat: -rw-r--r-- 7,163 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*-----------------------------------------------------------------*-C-*---
 * File:    handc/runtime/regs.h
 *
 *          Copyright (C)1997 Donovan Kolbly <d.kolbly@rscheme.org>
 *          as part of the RScheme project, licensed for free use.
 *          See <http://www.rscheme.org/> for the latest information.
 *
 * File version:     1.8
 * File mod date:    1997.11.29 23:10:49
 * System build:     v0.7.2, 97.12.21
 *
 * Purpose:          virtual machine register declarations
 *------------------------------------------------------------------------*/

#ifndef _H_REGS
#define _H_REGS

#include <rscheme/obj.h>

void init_regs( void );

#define IMPL_ARG_LIMIT (1000)

#ifdef M68K_REGS
    register obj envt_reg asm( "a5" );		/* any_reg 0 */
    register obj literals_reg asm( "a3" );	/* any_reg 1 */
    register obj dynamic_state_reg asm( "d4" );	/* any_reg 2 */
    register obj continuation_reg asm( "a4" );	/* any_reg 3 */
    extern obj thread_state_reg;                /* any_reg 4 */
    register unsigned arg_count_reg asm( "d5" );

    register obj REG0 asm( "d7" );
    register obj REG1 asm( "d6" );
    extern obj REG2, REG3, REG4, REG5, REG6, REG7, REG8, REG9;
#else
#ifdef MIPS_REGS
    register obj envt_reg asm( "$16" );		/* any_reg 0 */
    register obj literals_reg asm( "$17" );	/* any_reg 1 */
    register obj dynamic_state_reg asm( "$18" );/* any_reg 2 */
    register obj continuation_reg asm( "$19" );	/* any_reg 3 */
    extern obj thread_state_reg;                /* any_reg 4 */
    register unsigned arg_count_reg asm( "$20" );

    register obj REG0 asm( "$21" );
    register obj REG1 asm( "$22" );
    extern obj REG2, REG3;
    extern obj REG4, REG5, REG6;
    extern obj REG7, REG8, REG9;
#else
#ifdef RS6000_REGS
    register obj envt_reg asm( "13" );          /* any_reg 0 */
    register obj literals_reg asm( "14" );      /* any_reg 1 */
    extern obj dynamic_state_reg;               /* any_reg 2 */
    register obj continuation_reg asm( "16" );  /* any_reg 3 */
    extern obj thread_state_reg;                /* any_reg 4 */
    register unsigned arg_count_reg asm( "17" );

    register obj REG0 asm( "18" );
    register obj REG1 asm( "19" );
    register obj REG2 asm( "20" );
    register obj REG3 asm( "21" );
    register obj REG4 asm( "22" );
    register obj REG5 asm( "23" );
    register obj REG6 asm( "24" );
    register obj REG7 asm( "25" );
    register obj REG8 asm( "26" );
    register obj REG9 asm( "15" );
#else
#ifdef SPARC_REGS
    extern obj envt_reg;		        /* any_reg 0 */
    extern obj literals_reg;	                /* any_reg 1 */
    extern obj dynamic_state_reg;	        /* any_reg 2 */
    register obj continuation_reg asm( "%g7" );	/* any_reg 3 */
    extern obj thread_state_reg;                /* any_reg 4 */
    register unsigned arg_count_reg asm( "%g5" );

    register obj REG0 asm( "%g6" );
    extern obj REG1, REG2, REG3;
    extern obj REG4, REG5, REG6;
    extern obj REG7, REG8, REG9;
#else
#ifdef RS_PROFILE
    extern obj envt_reg;		/* any_reg 0 */
    extern obj literals_reg;		/* any_reg 1 */
    extern obj dynamic_state_reg;	/* any_reg 2 */
    extern obj continuation_reg;	/* any_reg 3 */
    extern obj thread_state_reg;        /* any_reg 4 */
    extern unsigned arg_count_reg;
    
    extern obj _REG0;
    extern obj _REG1, _REG2, _REG3;
    extern obj _REG4, _REG5, _REG6;
    extern obj _REG7, _REG8, _REG9;

#define REG0 (*(rs_profile1("reg",0),&_REG0))
#define REG1 (*(rs_profile1("reg",1),&_REG1))
#define REG2 (*(rs_profile1("reg",2),&_REG2))
#define REG3 (*(rs_profile1("reg",3),&_REG3))
#define REG4 (*(rs_profile1("reg",4),&_REG4))
#define REG5 (*(rs_profile1("reg",5),&_REG5))
#define REG6 (*(rs_profile1("reg",6),&_REG6))
#define REG7 (*(rs_profile1("reg",7),&_REG7))
#define REG8 (*(rs_profile1("reg",8),&_REG8))
#define REG9 (*(rs_profile1("reg",9),&_REG9))
#else
    extern obj envt_reg;		/* any_reg 0 */
    extern obj literals_reg;		/* any_reg 1 */
    extern obj dynamic_state_reg;	/* any_reg 2 */
    extern obj continuation_reg;	/* any_reg 3 */
    extern obj thread_state_reg;        /* any_reg 4 */
    extern unsigned arg_count_reg;
    
    extern obj REG0;
    extern obj REG1, REG2, REG3;
    extern obj REG4, REG5, REG6;
    extern obj REG7, REG8, REG9;
#endif
#endif /* SPARC_REGS */
#endif /* RS6000_REGS */
#endif /* MIPS_REGS */
#endif /* M68K_REGS */

/* use these at the EXIT from Scheme into system code */
/* (currently, we only use nonvolatile regs, no nothing to be done) */

#define SAVE_HW_REGS		/* nothing to save */
#define RESTORE_HW_REGS		/* and nothing to restore */


/* use these at the ENTRY into Scheme */

#ifdef USE_HW_REGS
void switch_hw_regs_into_scheme( void );
void switch_hw_regs_back_to_os( void );
#else
#define switch_hw_regs_into_scheme()  do {} while (0)
#define switch_hw_regs_back_to_os()   do {} while (0)
#endif

/*
For example, if we were using 5 hardware registers...

    extern obj HW_REGS_save_area[5];
    
    Note that we only need to save registers in this way
    that the system's
    calling convention does not mark as "callee saves"
    
    #define SAVE_HW_REGS	save_area[0] = REG1;
    				save_area[1] = REG2;
				save_area[2] = envt_reg;
				save_area[3] = arg_count_reg;
				save_area[4] = continuation_reg;
*/

/* this macro is used to save/restore the registers
   on certain calls out of the system which may clobber
   said registers.  The GC is considered to be INSIDE
   the system in this sense, so it has to be compiled
   with these register decls in scope and making use of
   OUT_CALL when calling outside the system (ie, sbrk()
   or malloc())
*/


#define OUT_CALL(body)	do { SAVE_HW_REGS  \
			     body \
			     RESTORE_HW_REGS } while (0)

extern obj reg_array[IMPL_ARG_LIMIT];
extern obj temp_space[IMPL_ARG_LIMIT+10];	/* not part of root set,
						   so invalid across 
						   gc_safe_point's */

/*
 *  NOTE: the argument to REG() may be evaluated multiple times,
 *  so it should be a simple expression (constant or variable reference)
 */

#define REG(i)	(*(rs_profile1("reg",i),&reg_array[i]))
/* #define REG(i)	reg_array[i] */


/* These functions are pretty slow, so use only when it
   saves significantly on development time */

/* these access the arg-passing registers... */

obj reg_ref( unsigned arg_reg_num );
void reg_set( unsigned arg_reg_num, obj value );

/* these access any register (used for scanning the roots) */

#define NUM_FIXED_REGS (5)

/* the number of valid registers is, at any safe point:
		NUM_FIXED_REGS+arg_count_reg
   note that this may not return an actual value for
   the continuation reg -- returns ZERO if the current
   continuation is in the stack cache
*/

#define NUM_REGS (NUM_FIXED_REGS + arg_count_reg)

obj any_reg_ref( unsigned reg_num );

/*
 *   root variable processing
 */

typedef int process_root_fn( obj *root, void *info );

int process_register_roots( process_root_fn *fn, void *info );
int process_stack_roots( process_root_fn *fn, void *info );
int process_module_roots( process_root_fn *fn, void *info );
int process_all_roots( process_root_fn *fn, void *info );

#endif /* _H_REGS */