import java.io.*; class Const { // from ststructs.mh public static final int LISTHEADER = 0; public static final int DECLARATION = 1; public static final int PARAMETER = 2; public static final int RECORDELEMENT = 3; public static final int VARSIGNATURE = 4; public static final int VALSIGNATURE = 5; public static final int FUNCSIGNATURE = 6; public static final int TYPESIGNATURE = 7; public static final int TSCOMPONENT = 8; public static final int DEFCHARSIGS = 9; public static final int SIGNATURESIG = 10; public static final int BLOCKDENOTATION = 11; public static final int USELIST = 12; public static final int APPLICATION = 13; public static final int ENUMERATION = 14 ; public static final int EXTENSION = 15; public static final int PRODCONSTRUCTION = 16; public static final int RECORDCONSTRUCTION = 17; public static final int UNIONCONSTRUCTION = 18; public static final int WITHLIST = 19; public static final int MODPRIMARY = 20; public static final int EXPORTLIST = 21; public static final int HIDELIST = 22; public static final int EXPORTELEMENT = 23; public static final int ALLCONSTANTS = 24; public static final int WORDELSE = 25; public static final int WORDCAND = 26; public static final int WORDCOR = 27; public static final int GUARDEDLIST = 28; public static final int LOOPDENOTATION = 29; public static final int GUARDEDELEMENT = 30; public static final int OPRID = 31; public static final int LETTERID = 32; public static final int QSTR = 33; public static final int UQSTR = 34; public static final int FUNCCONSTR = 35; public static final int FREEVARNODE = 36; public static final int EXTERNDEF = 37; public static final int REXTERNDEF = 38; public static final int DCSEXCEPTION = 39; //------------------------------------------ // from RIC.c public static final int RIC_TABSIZE = 200; // from op_codes.h /* RIC (Russell Intermediate Code) Op codes */ /* The first group has a single string argument */ public static final int BR = 1; /* branch unconditionally */ public static final int BRT = 2; /* branch if value in TL is true. */ public static final int BRF = 3; /* branch if value in TL is false. */ public static final int CLL = 4; /* call routine with given label */ /* Needs to do any cleanup (e.g. stack pops) */ /* necessitated by the preceding ARG instr that */ /* passed the activation record pointer. */ public static final int LBL = 5; /* attach the given label to the next instruction */ public static final int EXT = 6; /* declare the label to be external */ /* All labels that need to be known to the */ /* outside are marked in this way. All labels */ /* not beginning with an 'L' are intended to be */ /* unique, and thus may be made globally visible. */ public static final int LBA = 7; /* supply a label argument to immediately */ /* following instruction */ public static final int BFN = 9; /* begin named function */ /* function temporaries may be reserved on the */ /* stack at this point */ /* FP should be set to point to one below return */ /* address. AR should be set to first (and only) */ /* argument. Other locations are set explicitly. */ /* Locations (incl. AR) are implicitly saved */ /* during a procedure call. */ public static final int TFB = 10; /* trace function entry */ public static final int TFE = 11; /* trace function exit */ public static final int PRO = 12; /* record function entry for profiling */ public static final int ADT = 13; /* character string data. A label for the */ /* location of the data may be supplied by a */ /* preceding LBA instruction OBSOLETE */ public static final int ERR = 14; /* branch to error routine with indicated label */ /* Arguments may have been pushed. */ public static final int BSF = 15; /* begin short function. Identical to BFN, */ /* except that AR should neither be set, nor does */ /* the old value need to be saved. */ /* Arguments to BSF functions are passed */ /* individually using ARG, rather than passing a */ /* a single argument containing the activation */ /* record. If the name of the function does not */ /* start with Ffn, the generated function must be */ /* C callable. (Typically it will be, in any */ /* case.) */ public static final int LBR = 16; /* Attach a symbolic name to the virtual register */ /* declared by the immediately following DCL */ public static final int DDT = 17; /* Generate double precision floating point data. */ /* May be labelled with an LBA instruction. */ /* The argument is actually a string representing */ /* representing a floating point constant. */ /* Such data is read-only. */ public static final int FDT = 18; /* Analogous to FDT, but for single precision */ /* constants. */ public static final int MAX_LABEL_OP = 19; /* The remainder has up to 3 integer arguments. Unless otherwise */ /* specified, they refer to temporary locations (virtual */ /* registers). An offset is a signed integer value. */ /* An object is considered accessible only if there is an */ /* accessible pointer to its beginning. */ /* Pointers in any active temporary or on the stack are accessible */ /* args */ public static final int DCL = 20; /* loc type -- declare temporary location */ /* (i.e. virtual register) */ /* The following types are allowed: */ public static final int DCL_ADDR = 1; public static final int DCL_INT = 2; /* 32 bit integer */ public static final int DCL_FLOAT = 3; public static final int DCL_DBL_FLOAT = 4; /* DCL_ADDR and DCL_INT, are assumed to be the */ /* same size. The distinction is only a hint */ /* to the machine code generator. */ /* DCL_FLOAT is unlikely to be used in the */ /* near future. */ /* In the following, size is a location: */ public static final int UDC = 21; /* loc -- free temporary location */ /* If applied to a predefined location, this */ /* constitutes a declaration that the value it */ /* contains is dead at this point. */ /* Duplicate UDC's for the same location may */ /* occasionally appear. All but the first can be */ /* safely ignored. */ public static final int ALH = 22; /* size loc -- loc := ptr to new heap object */ public static final int GAR = 23; /* i loc -- Get the ith argument (passed with */ /* ARG) into loc */ public static final int ALS = 24; /* size -- allocate new stack object containing */ /* pointer data */ /* Both ALS and ALH are assumed to clear the */ /* allocated space. This is necessary only for */ /* garbage collection, and may frequently be */ /* eliminated by an optimizer */ public static final int LDI = 25; /* index offset loc -- loc := index[offset] */ public static final int STI = 26; /* index offset loc -- index[offset] := loc */ public static final int CLI = 27; /* index offset -- jsr index[offset] */ /* Needs cleanup similar to CLL */ public static final int LDN = 28; /* signed_value loc -- loc := signed_value */ public static final int RTN = 29; /* -- return from function w/ value at loc RL */ public static final int LDL = 30; /* loc -- load value of label provided */ /* by immediately preceding LBA instruction */ /* The label must have been previously defined. */ public static final int MOV = 31; /* loc1 loc2 -- loc2 := loc1 */ public static final int TAR = 32; /* arg put_fn -- save passed argument for trace */ public static final int PSH = 33; /* loc -- push contents of loc onto stack */ /* equivalent to ALS 1; STI SP, 0, loc */ /* public static final int MVI 34 loc1 loc2 -- *loc2++ := *loc1++ */ public static final int ADP = 35; /* loc1 offset loc2 -- loc2 := &loc1[offset] */ /* Add a (word) offset to a pointer value */ /* Unlike LDI and STI, offset here is a location */ public static final int CLC = 36; /* nargs -- Call to a non-Russell routine or a BSF */ /* style Russell routine. Nargs */ /* is an integer. The routine name is given by */ /* a preceding LBA instruction. The arguments */ /* are supplied in reverse order by prior */ /* ARG instructions. */ public static final int ALA = 37; /* size loc -- loc := ptr to new atomic heap */ /* object. Object should never contain pointer */ /* data. */ public static final int HINT = 38; /* kind arg1 arg2 -- Code generator hint. */ public static final int OPT = 1; /* n -- The next n instructions perform */ /* runtime checks, and may be discarded at */ /* suitably high levels of optimization. */ public static final int NP = 2; /* The following ARG instruction refers to a */ /* pointer to an object that may be on the */ /* heap. The called procedure does not */ /* preserve references to this object. Thus */ /* the ARG instruction may be disregarded for */ /* purposes of static ref. counting */ public static final int AL = 3; /* size atom -- (size is a constant). The */ /* following procedure call (CLC, CLL, CLI) */ /* returns a new object of the indicated */ /* size. If size is != 0 the object may */ /* be deallocated by attaching it directly */ /* to the free list of the indicated size. */ /* If size is = 0, the size of the object */ /* is unknown, and the object could be */ /* statically allocated; rfree should be */ /* called to release it. */ /* Atom is either 0 or 1, and */ /* specifies whether the allocated object is */ /* atomic, and thus should be returned to the */ /* atomic object free list. */ public static final int DEA = 4; /* loc size -- Indicates that */ /* the object pointed to by loc may be freed. */ /* This type of hint is inserted by the */ /* static reference counter for the benefit */ /* of the code generator. */ /* A negative size indicates the object is */ /* atomic; a positive size means composite, */ /* and a 0 size means unknown. */ /* Size is a constant, not a location. */ public static final int NSC = 5; /* The following CLL or CLI instruction */ /* does not result in a saved continuation. */ /* Thus the reference counts of objects */ /* pointed to only by virtual registers */ /* is unchanged across the call. */ /* (This is always the case for CLC calls.) */ public static final int STSZ = 6; /* loc -- The following STI instruction */ /* should store the size of loc if it's known */ /* that loc has exactly one reference, and 0 */ /* otherwise. Loc contains a pointer to a */ /* composite object. */ public static final int PT = 7; /* Analogous to NP, but a single reference is */ /* preserved (passed through) as the function */ /* result. */ public static final int DEAD = 8; /* loc -- The value in loc will not be used */ /* again. (The location itself may be reused.*/ /* Thus UDC would be inappropriate.) */ public static final int GFU = 9; /* GF is about to be updated, or AR is about */ /* to be updated inside a BSF function. */ /* Such a hint always precedes the first such */ /* update in a routine. */ public static final int LIVE = 10; /* loc -- The value in loc should be viewed */ /* as live up to this point. Such a hint is */ /* included whenever a location (other than */ /* GF and AR) could appear to be dead, but a */ /* derived pointer is not. A value in such a */ /* location needs to be retained, so as not */ /* to confuse the garbage collector. */ /* We do not generate such HINTs if it is */ /* known that the value in question is also */ /* stored in an accessible memory location. */ /* Similarly, we do not generate such a HINT */ /* if the derived pointer is only implicit */ /* in an LDI or STI instruction. */ public static final int ET = 11; /* Defines the type of the following item */ /* declared by an EXT. All EXTs that do not */ /* refer to functions are preceded by such a */ /* hint. The second argument is a type */ /* specifier, as for the DCL instruction. */ public static final int ONS = 12; /* The following allocation instruction may */ /* be implemented as a stack allocation. */ /* This is used only if the comipler is not */ /* allowed to generate ALS instructions (-f */ /* or -F flag). Each allocation instruction */ /* preceded by a HINT ONS is eventually */ /* followed by a corresponding HINT ONS; */ /* HINT DEA sequence. All such pairs are */ /* properly nested. There are no branches */ /* into or our of such a pair. */ public static final int ARG = 39; /* n loc -- Pass loc as the nth argument to CLC */ /* ARG instructions always occur in reverse order, */ /* with highest numbered argument first. The */ /* lowest numbered argument is numbered 1. */ /* Also used to pass the activation record pointer */ /* through CLL and CLI calls. */ /* MAY reserve space on the stack. */ /* Integer operations */ public static final int ADI = 40; /* op1 op2 result -- result := (int)op1 + (int)op2 */ public static final int SBI = 41; /* op1 op2 result -- result := (int)op1 - (int)op2 */ public static final int MLI = 42; /* op1 op2 result -- result := (int)op1 * (int)op2 */ public static final int DVI = 43; /* op1 op2 result -- result := (int)op1 / (int)op2 */ public static final int NGI = 44; /* op result -- result := -op */ public static final int IDT = 45; /* data -- generate integer data. May be labeled */ /* with an LBA */ /* Consecutive IDTs w/o intervening LBAs generate */ /* consecutive data. */ /* Data is read-only. */ public static final int EQI = 46; /* op1 op2 result -- result := (int)op1 = (int)op2 */ public static final int LTI = 47; /* op1 op2 result -- result := (int)op1 < (int)op2 */ public static final int GTI = 48; /* op1 op2 result -- result := (int)op1 > (int)op2 */ public static final int NEI = 49; /* op1 op2 result -- result := (int)op1 != (int)op2 */ public static final int LEI = 50; /* op1 op2 result -- result := (int)op1 <= (int)op2 */ public static final int GEI = 51; /* op1 op2 result -- result := (int)op1 >= (int)op2 */ public static final int SHI = 52; /* op1 op2 result -- result := arith_shift(op1, op2) */ public static final int ABI = 53; /* op1 result -- result := abs(op1) */ /* Boolean operations */ public static final int TRU = 60; /* loc -- load the constant true into the */ /* indicated location. */ public static final int FLS = 61; /* loc -- load the constant false into the */ /* indicated location. */ /* The following instructions are assumed to work on */ /* both Booleans and bit vectors: */ public static final int AND = 62; /* op1 op2 result -- result := op1 & op2 */ public static final int OR = 63; /* op1 op2 result -- result := op1 | op2 */ /* The following applies only to Booleans: */ public static final int NOT = 64; /* op result -- result := ~ op */ /* String operations */ public static final int LDS = 70; /* loc -- put a pointer to the string given by the */ /* preceding LBA instruction into loc */ public static final int LDC = 71; /* index offset loc -- loc := index[offset] */ /* Differs from LDI in that offset is a virtual */ /* register (location) and it is a BYTE rather than */ /* word displacement from index. Used to access */ /* individual characters in a string. */ /* Operations on single precision floating point numbers */ public static final int ADF = 80; /* op1 op2 result -- result := (float)op1 + (float)op2 */ public static final int SBF = 81; /* op1 op2 result -- result := (float)op1 - (float)op2 */ public static final int MLF = 82; /* op1 op2 result -- result := (float)op1 * (float)op2 */ public static final int DVF = 83; /* op1 op2 result -- result := (float)op1 / (float)op2 */ public static final int NGF = 84; /* op result -- result := - (float) op */ public static final int EXF = 85; /* op1 result -- result := (int) x s.t. */ /* 2 **(x-1) <= op1 < 2**x */ public static final int EQF = 86; /* op1 op2 result -- result := (float)op1 = (float)op2 */ public static final int LTF = 87; /* op1 op2 result -- result := (float)op1 < (float)op2 */ public static final int GTF = 88; /* op1 op2 result -- result := (float)op1 > (float)op2 */ public static final int NEF = 89; /* op1 op2 result -- result := (float)op1 != (float)op2 */ public static final int LEF = 90; /* op1 op2 result -- result := (float)op1 <= (float)op2 */ public static final int GEF = 91; /* op1 op2 result -- result := (float)op1 >= (float)op2 */ public static final int SHF = 92; /* op1 op2 result -- result := (float)op1 * 2** (int)op2 */ public static final int N_OP_CODES = 100; /* predefined locations */ public static final int AR = 1; /* activation record pointer */ public static final int SP = 2; /* stack pointer */ public static final int GF = 3; /* pointer to global act. rec. */ /* explicitly saved and restored by */ /* intermediate code if it is updated. */ /* Thus it can easily be assigned to a */ /* fixed register. */ public static final int UN = 4; /* location containing "undefined" value */ public static final int SK = 5; /* value sink, nothing comes out ... */ /* An instruction using SK as */ /* destination or an STI SK,... is a */ /* noop */ public static final int RL = 6; /* location for function result */ /* capable of holding max size object */ public static final int RS = 0x30000000; /* result of operation. In-line code only */ /* Can't be legitimate operand to anything */ /* but LDN */ public static final int TL = 8; /* Location tested in conditional branches */ /* Dead after first reference. */ public static final int C0 = 10; /* always 0 */ public static final int C1 = 11; /* always 1 */ public static final int C2 = 12; /* always 2 */ public static final int C3 = 13; /* always 3 */ public static final int C4 = 14; /* always 4 */ /* T1 and T2 are short term temporaries. They should be */ /* used only in fixed code sequences, not involving */ /* arbitrary embedded code. T1 is mapped to the same */ /* location as RL, and may thus conflict with RS in */ /* inline code sequences. T2 will never be specified as */ /* the result location for an inline code sequence. */ /* T1 is assumed to be predeclared. T2 is not treated */ /* specially by the final code generator. */ /* Since T1 and RL are the same, and will presumably be */ /* mapped to the location used for function results, we */ /* assume that T1 may be clobbered by ALA and ALH. */ public static final int T1 = RL; public static final int T2 = 16; /* Note: All general locations are expected to be saved and */ /* restored on procedure call. */ public static final int FIRST_AVAIL_LOC = 20; /* Activation record layout (all parts optional): * * 0: static link * 1: 1st arg * ... * locals */ public static final int AR_SL = 0; /* * Function object layout: * * 0: size * 1: ep * 2: ip */ public static final int FO_SIZE = 0; public static final int FO_EP = 1; public static final int FO_IP = 2; public static final int MISSING = -2; }