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),®_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 */
|