00001 /* RIC (Russell Intermediate Code) Op codes */ 00002 00003 /* The first group has a single string argument */ 00004 #define BR 1 /* branch unconditionally */ 00005 #define BRT 2 /* branch if value in TL is true. */ 00006 #define BRF 3 /* branch if value in TL is false. */ 00007 #define CLL 4 /* call routine with given label */ 00008 /* Needs to do any cleanup (e.g. stack pops) */ 00009 /* necessitated by the preceding ARG instr that */ 00010 /* passed the activation record pointer. */ 00011 #define LBL 5 /* attach the given label to the next instruction */ 00012 #define EXT 6 /* declare the label to be external */ 00013 /* All labels that need to be known to the */ 00014 /* outside are marked in this way. All labels */ 00015 /* not beginning with an 'L' are intended to be */ 00016 /* unique, and thus may be made globally visible. */ 00017 #define LBA 7 /* supply a label argument to immediately */ 00018 /* following instruction */ 00019 #define BFN 9 /* begin named function */ 00020 /* function temporaries may be reserved on the */ 00021 /* stack at this point */ 00022 /* FP should be set to point to one below return */ 00023 /* address. AR should be set to first (and only) */ 00024 /* argument. Other locations are set explicitly. */ 00025 /* Locations (incl. AR) are implicitly saved */ 00026 /* during a procedure call. */ 00027 #define TFB 10 /* trace function entry */ 00028 #define TFE 11 /* trace function exit */ 00029 #define PRO 12 /* record function entry for profiling */ 00030 #define ADT 13 /* character string data. A label for the */ 00031 /* location of the data may be supplied by a */ 00032 /* preceding LBA instruction OBSOLETE */ 00033 #define ERR 14 /* branch to error routine with indicated label */ 00034 /* Arguments may have been pushed. */ 00035 #define BSF 15 /* begin short function. Identical to BFN, */ 00036 /* except that AR should neither be set, nor does */ 00037 /* the old value need to be saved. */ 00038 /* Arguments to BSF functions are passed */ 00039 /* individually using ARG, rather than passing a */ 00040 /* a single argument containing the activation */ 00041 /* record. If the name of the function does not */ 00042 /* start with Ffn, the generated function must be */ 00043 /* C callable. (Typically it will be, in any */ 00044 /* case.) */ 00045 #define LBR 16 /* Attach a symbolic name to the virtual register */ 00046 /* declared by the immediately following DCL */ 00047 #define DDT 17 /* Generate double precision floating point data. */ 00048 /* May be labelled with an LBA instruction. */ 00049 /* The argument is actually a string representing */ 00050 /* representing a floating point constant. */ 00051 /* Such data is read-only. */ 00052 #define FDT 18 /* Analogous to FDT, but for single precision */ 00053 /* constants. */ 00054 00055 #define MAX_LABEL_OP 19 00056 00057 /* The remainder has up to 3 integer arguments. Unless otherwise */ 00058 /* specified, they refer to temporary locations (virtual */ 00059 /* registers). An offset is a signed integer value. */ 00060 /* An object is considered accessible only if there is an */ 00061 /* accessible pointer to its beginning. */ 00062 /* Pointers in any active temporary or on the stack are accessible */ 00063 /* args */ 00064 #define DCL 20 /* loc type -- declare temporary location */ 00065 /* (i.e. virtual register) */ 00066 /* The following types are allowed: */ 00067 # define DCL_ADDR 1 00068 # define DCL_INT 2 /* 32 bit integer */ 00069 # define DCL_FLOAT 3 00070 # define DCL_DBL_FLOAT 4 00071 /* DCL_ADDR and DCL_INT, are assumed to be the */ 00072 /* same size. The distinction is only a hint */ 00073 /* to the machine code generator. */ 00074 /* DCL_FLOAT is unlikely to be used in the */ 00075 /* near future. */ 00076 00077 /* In the following, size is a location: */ 00078 #define UDC 21 /* loc -- free temporary location */ 00079 /* If applied to a predefined location, this */ 00080 /* constitutes a declaration that the value it */ 00081 /* contains is dead at this point. */ 00082 /* Duplicate UDC's for the same location may */ 00083 /* occasionally appear. All but the first can be */ 00084 /* safely ignored. */ 00085 #define ALH 22 /* size loc -- loc := ptr to new heap object */ 00086 #define GAR 23 /* i loc -- Get the ith argument (passed with */ 00087 /* ARG) into loc */ 00088 #define ALS 24 /* size -- allocate new stack object containing */ 00089 /* pointer data */ 00090 /* Both ALS and ALH are assumed to clear the */ 00091 /* allocated space. This is necessary only for */ 00092 /* garbage collection, and may frequently be */ 00093 /* eliminated by an optimizer */ 00094 #define LDI 25 /* index offset loc -- loc := index[offset] */ 00095 #define STI 26 /* index offset loc -- index[offset] := loc */ 00096 #define CLI 27 /* index offset -- jsr index[offset] */ 00097 /* Needs cleanup similar to CLL */ 00098 #define LDN 28 /* signed_value loc -- loc := signed_value */ 00099 #define RTN 29 /* -- return from function w/ value at loc RL */ 00100 #define LDL 30 /* loc -- load value of label provided */ 00101 /* by immediately preceding LBA instruction */ 00102 /* The label must have been previously defined. */ 00103 #define MOV 31 /* loc1 loc2 -- loc2 := loc1 */ 00104 #define TAR 32 /* arg put_fn -- save passed argument for trace */ 00105 #define PSH 33 /* loc -- push contents of loc onto stack */ 00106 /* equivalent to ALS 1; STI SP, 0, loc */ 00107 /* #define MVI 34 loc1 loc2 -- *loc2++ := *loc1++ */ 00108 #define ADP 35 /* loc1 offset loc2 -- loc2 := &loc1[offset] */ 00109 /* Add a (word) offset to a pointer value */ 00110 /* Unlike LDI and STI, offset here is a location */ 00111 #define CLC 36 /* nargs -- Call to a non-Russell routine or a BSF */ 00112 /* style Russell routine. Nargs */ 00113 /* is an integer. The routine name is given by */ 00114 /* a preceding LBA instruction. The arguments */ 00115 /* are supplied in reverse order by prior */ 00116 /* ARG instructions. */ 00117 00118 #define ALA 37 /* size loc -- loc := ptr to new atomic heap */ 00119 /* object. Object should never contain pointer */ 00120 /* data. */ 00121 #define HINT 38 /* kind arg1 arg2 -- Code generator hint. */ 00122 #define OPT 1 /* n -- The next n instructions perform */ 00123 /* runtime checks, and may be discarded at */ 00124 /* suitably high levels of optimization. */ 00125 #define NP 2 /* The following ARG instruction refers to a */ 00126 /* pointer to an object that may be on the */ 00127 /* heap. The called procedure does not */ 00128 /* preserve references to this object. Thus */ 00129 /* the ARG instruction may be disregarded for */ 00130 /* purposes of static ref. counting */ 00131 #define AL 3 /* size atom -- (size is a constant). The */ 00132 /* following procedure call (CLC, CLL, CLI) */ 00133 /* returns a new object of the indicated */ 00134 /* size. If size is != 0 the object may */ 00135 /* be deallocated by attaching it directly */ 00136 /* to the free list of the indicated size. */ 00137 /* If size is = 0, the size of the object */ 00138 /* is unknown, and the object could be */ 00139 /* statically allocated; rfree should be */ 00140 /* called to release it. */ 00141 /* Atom is either 0 or 1, and */ 00142 /* specifies whether the allocated object is */ 00143 /* atomic, and thus should be returned to the */ 00144 /* atomic object free list. */ 00145 #define DEA 4 /* loc size -- Indicates that */ 00146 /* the object pointed to by loc may be freed. */ 00147 /* This type of hint is inserted by the */ 00148 /* static reference counter for the benefit */ 00149 /* of the code generator. */ 00150 /* A negative size indicates the object is */ 00151 /* atomic; a positive size means composite, */ 00152 /* and a 0 size means unknown. */ 00153 /* Size is a constant, not a location. */ 00154 #define NSC 5 /* The following CLL or CLI instruction */ 00155 /* does not result in a saved continuation. */ 00156 /* Thus the reference counts of objects */ 00157 /* pointed to only by virtual registers */ 00158 /* is unchanged across the call. */ 00159 /* (This is always the case for CLC calls.) */ 00160 #define STSZ 6 /* loc -- The following STI instruction */ 00161 /* should store the size of loc if it's known */ 00162 /* that loc has exactly one reference, and 0 */ 00163 /* otherwise. Loc contains a pointer to a */ 00164 /* composite object. */ 00165 #define PT 7 /* Analogous to NP, but a single reference is */ 00166 /* preserved (passed through) as the function */ 00167 /* result. */ 00168 #define DEAD 8 /* loc -- The value in loc will not be used */ 00169 /* again. (The location itself may be reused.*/ 00170 /* Thus UDC would be inappropriate.) */ 00171 #define GFU 9 /* GF is about to be updated, or AR is about */ 00172 /* to be updated inside a BSF function. */ 00173 /* Such a hint always precedes the first such */ 00174 /* update in a routine. */ 00175 #define LIVE 10 /* loc -- The value in loc should be viewed */ 00176 /* as live up to this point. Such a hint is */ 00177 /* included whenever a location (other than */ 00178 /* GF and AR) could appear to be dead, but a */ 00179 /* derived pointer is not. A value in such a */ 00180 /* location needs to be retained, so as not */ 00181 /* to confuse the garbage collector. */ 00182 /* We do not generate such HINTs if it is */ 00183 /* known that the value in question is also */ 00184 /* stored in an accessible memory location. */ 00185 /* Similarly, we do not generate such a HINT */ 00186 /* if the derived pointer is only implicit */ 00187 /* in an LDI or STI instruction. */ 00188 #define ET 11 /* Defines the type of the following item */ 00189 /* declared by an EXT. All EXTs that do not */ 00190 /* refer to functions are preceded by such a */ 00191 /* hint. The second argument is a type */ 00192 /* specifier, as for the DCL instruction. */ 00193 #define ONS 12 /* The following allocation instruction may */ 00194 /* be implemented as a stack allocation. */ 00195 /* This is used only if the comipler is not */ 00196 /* allowed to generate ALS instructions (-f */ 00197 /* or -F flag). Each allocation instruction */ 00198 /* preceded by a HINT ONS is eventually */ 00199 /* followed by a corresponding HINT ONS; */ 00200 /* HINT DEA sequence. All such pairs are */ 00201 /* properly nested. There are no branches */ 00202 /* into or our of such a pair. */ 00203 #define ARG 39 /* n loc -- Pass loc as the nth argument to CLC */ 00204 /* ARG instructions always occur in reverse order, */ 00205 /* with highest numbered argument first. The */ 00206 /* lowest numbered argument is numbered 1. */ 00207 /* Also used to pass the activation record pointer */ 00208 /* through CLL and CLI calls. */ 00209 /* MAY reserve space on the stack. */ 00210 00211 /* Integer operations */ 00212 #define ADI 40 /* op1 op2 result -- result := (int)op1 + (int)op2 */ 00213 #define SBI 41 /* op1 op2 result -- result := (int)op1 - (int)op2 */ 00214 #define MLI 42 /* op1 op2 result -- result := (int)op1 * (int)op2 */ 00215 #define DVI 43 /* op1 op2 result -- result := (int)op1 / (int)op2 */ 00216 #define NGI 44 /* op result -- result := -op */ 00217 #define IDT 45 /* data -- generate integer data. May be labeled */ 00218 /* with an LBA */ 00219 /* Consecutive IDTs w/o intervening LBAs generate */ 00220 /* consecutive data. */ 00221 /* Data is read-only. */ 00222 #define EQI 46 /* op1 op2 result -- result := (int)op1 = (int)op2 */ 00223 #define LTI 47 /* op1 op2 result -- result := (int)op1 < (int)op2 */ 00224 #define GTI 48 /* op1 op2 result -- result := (int)op1 > (int)op2 */ 00225 #define NEI 49 /* op1 op2 result -- result := (int)op1 != (int)op2 */ 00226 #define LEI 50 /* op1 op2 result -- result := (int)op1 <= (int)op2 */ 00227 #define GEI 51 /* op1 op2 result -- result := (int)op1 >= (int)op2 */ 00228 #define SHI 52 /* op1 op2 result -- result := arith_shift(op1, op2) */ 00229 #define ABI 53 /* op1 result -- result := abs(op1) */ 00230 00231 /* Boolean operations */ 00232 #define TRU 60 /* loc -- load the constant true into the */ 00233 /* indicated location. */ 00234 #define FLS 61 /* loc -- load the constant false into the */ 00235 /* indicated location. */ 00236 /* The following instructions are assumed to work on */ 00237 /* both Booleans and bit vectors: */ 00238 #define AND 62 /* op1 op2 result -- result := op1 & op2 */ 00239 #define OR 63 /* op1 op2 result -- result := op1 | op2 */ 00240 /* The following applies only to Booleans: */ 00241 #define NOT 64 /* op result -- result := ~ op */ 00242 00243 /* String operations */ 00244 #define LDS 70 /* loc -- put a pointer to the string given by the */ 00245 /* preceding LBA instruction into loc */ 00246 #define LDC 71 /* index offset loc -- loc := index[offset] */ 00247 /* Differs from LDI in that offset is a virtual */ 00248 /* register (location) and it is a BYTE rather than */ 00249 /* word displacement from index. Used to access */ 00250 /* individual characters in a string. */ 00251 00252 /* Operations on single precision floating point numbers */ 00253 #define ADF 80 /* op1 op2 result -- result := (float)op1 + (float)op2 */ 00254 #define SBF 81 /* op1 op2 result -- result := (float)op1 - (float)op2 */ 00255 #define MLF 82 /* op1 op2 result -- result := (float)op1 * (float)op2 */ 00256 #define DVF 83 /* op1 op2 result -- result := (float)op1 / (float)op2 */ 00257 #define NGF 84 /* op result -- result := - (float) op */ 00258 #define EXF 85 /* op1 result -- result := (int) x s.t. */ 00259 /* 2 **(x-1) <= op1 < 2**x */ 00260 #define EQF 86 /* op1 op2 result -- result := (float)op1 = (float)op2 */ 00261 #define LTF 87 /* op1 op2 result -- result := (float)op1 < (float)op2 */ 00262 #define GTF 88 /* op1 op2 result -- result := (float)op1 > (float)op2 */ 00263 #define NEF 89 /* op1 op2 result -- result := (float)op1 != (float)op2 */ 00264 #define LEF 90 /* op1 op2 result -- result := (float)op1 <= (float)op2 */ 00265 #define GEF 91 /* op1 op2 result -- result := (float)op1 >= (float)op2 */ 00266 #define SHF 92 /* op1 op2 result -- result := (float)op1 * 2** (int)op2 */ 00267 00268 #define N_OP_CODES 100 00269 00270 /* predefined locations */ 00271 #define AR 1 /* activation record pointer */ 00272 #define SP 2 /* stack pointer */ 00273 #define GF 3 /* pointer to global act. rec. */ 00274 /* explicitly saved and restored by */ 00275 /* intermediate code if it is updated. */ 00276 /* Thus it can easily be assigned to a */ 00277 /* fixed register. */ 00278 #define UN 4 /* location containing "undefined" value */ 00279 #define SK 5 /* value sink, nothing comes out ... */ 00280 /* An instruction using SK as */ 00281 /* destination or an STI SK,... is a */ 00282 /* noop */ 00283 #define RL 6 /* location for function result */ 00284 /* capable of holding max size object */ 00285 #define RS 0x30000000 00286 /* result of operation. In-line code only */ 00287 /* Can't be legitimate operand to anything */ 00288 /* but LDN */ 00289 #define TL 8 /* Location tested in conditional branches */ 00290 /* Dead after first reference. */ 00291 #define C0 10 /* always 0 */ 00292 #define C1 11 /* always 1 */ 00293 #define C2 12 /* always 2 */ 00294 #define C3 13 /* always 3 */ 00295 #define C4 14 /* always 4 */ 00296 /* T1 and T2 are short term temporaries. They should be */ 00297 /* used only in fixed code sequences, not involving */ 00298 /* arbitrary embedded code. T1 is mapped to the same */ 00299 /* location as RL, and may thus conflict with RS in */ 00300 /* inline code sequences. T2 will never be specified as */ 00301 /* the result location for an inline code sequence. */ 00302 /* T1 is assumed to be predeclared. T2 is not treated */ 00303 /* specially by the final code generator. */ 00304 /* Since T1 and RL are the same, and will presumably be */ 00305 /* mapped to the location used for function results, we */ 00306 /* assume that T1 may be clobbered by ALA and ALH. */ 00307 #define T1 RL 00308 #define T2 16 00309 00310 /* Note: All general locations are expected to be saved and */ 00311 /* restored on procedure call. */ 00312 00313 #define FIRST_AVAIL_LOC 20 00314 00315 /* Activation record layout (all parts optional): 00316 * 00317 * 0: static link 00318 * 1: 1st arg 00319 * ... 00320 * locals 00321 */ 00322 #define AR_SL 0 00323 00324 /* 00325 * Function object layout: 00326 * 00327 * 0: size 00328 * 1: ep 00329 * 2: ip 00330 */ 00331 #define FO_SIZE 0 00332 #define FO_EP 1 00333 #define FO_IP 2