PageRenderTime 19ms CodeModel.GetById 2ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

/vm/tinyrb/opcode.h

http://github.com/feyeleanor/RubyGoLightly
C++ Header | 208 lines | 169 code | 21 blank | 18 comment | 0 complexity | 5cc699bd17f0cee8c87dc4456d4f8582 MD5 | raw file
  1#ifndef _OPCODE_H_
  2#define _OPCODE_H_
  3
  4/* Taken from Lua */
  5#define cast(T,X) ((T)X)
  6
  7#define SIZE_C    9
  8#define SIZE_B    9
  9#define SIZE_Bx   (SIZE_C + SIZE_B)
 10#define SIZE_A    8
 11
 12#define SIZE_OP   6
 13
 14#define POS_OP    0
 15#define POS_A     (POS_OP + SIZE_OP)
 16#define POS_C     (POS_A + SIZE_A)
 17#define POS_B     (POS_C + SIZE_C)
 18#define POS_Bx    POS_C
 19
 20#if SIZE_Bx < TR_BITSINT-1
 21#define MAXARG_Bx   ((1<<SIZE_Bx)-1)
 22#define MAXARG_sBx  (MAXARG_Bx>>1)         /* `sBx' is signed */
 23#else
 24#define MAXARG_Bx   MAX_INT
 25#define MAXARG_sBx  MAX_INT
 26#endif
 27
 28/* creates a mask with `n' 1 bits at position `p' */
 29#define MASK1(n,p)  ((~((~(TrInst)0)<<n))<<p)
 30
 31/* creates a mask with `n' 0 bits at position `p' */
 32#define MASK0(n,p)  (~MASK1(n,p))
 33
 34/* the following macros help to manipulate instructions (TrInst) */
 35
 36#define GET_OPCODE(i) (cast(int, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
 37#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
 38    ((cast(TrInst, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
 39
 40#define GETARG_A(i) (cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
 41#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
 42    ((cast(TrInst, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
 43
 44#define GETARG_B(i) (cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
 45#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
 46    ((cast(TrInst, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
 47
 48#define GETARG_C(i) (cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
 49#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
 50    ((cast(TrInst, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
 51
 52#define GETARG_Bx(i)  (cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
 53#define SETARG_Bx(i,b)  ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
 54    ((cast(TrInst, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
 55
 56#define GETARG_sBx(i) cast(int, GETARG_Bx(i)-MAXARG_sBx)
 57#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
 58
 59#define CREATE_ABC(o,a,b,c) ((cast(TrInst, o)<<POS_OP) \
 60      | (cast(TrInst, a)<<POS_A) \
 61      | (cast(TrInst, b)<<POS_B) \
 62      | (cast(TrInst, c)<<POS_C))
 63
 64#define CREATE_ABx(o,a,bc)  ((cast(TrInst, o)<<POS_OP) \
 65      | (cast(TrInst, a)<<POS_A) \
 66      | (cast(TrInst, bc)<<POS_Bx))
 67
 68/*
 69== TinyRb opcodes.
 70Format of one instruction: OPCODE A B C
 71Bx    -- unsigned value of BC
 72sBx   -- signed value of BC
 73R[A]  -- Value of register which index is stored in A of the current instruction.
 74R[nA] -- Value of the register A in the next instruction (instruction will be ignored).
 75K[A]  -- Value which index is stored in A of the current instruction.
 76RK[A] -- Register A or a constant index
 77*/
 78enum TrInstCode {
 79  /* opname            operands description */
 80  TR_OP_BOING,      /*          do nothing with elegance and frivolity */
 81  TR_OP_MOVE,       /* A B      R[A] = R[B]  */
 82  TR_OP_LOADK,      /* A Bx     R[A] = K[Bx] */
 83  TR_OP_STRING,     /* A Bx     R[A] = strings[Bx] */
 84  TR_OP_BOOL,       /* A B      R[A] = B + 1 */
 85  TR_OP_NIL,        /* A        R[A] = nil */
 86  TR_OP_SELF,       /* A        put self in R[A] */
 87  TR_OP_LOOKUP,     /* A Bx     R[A+1] = lookup method K[Bx] on R[A] and store */
 88  TR_OP_CACHE,      /* A B C    if sites[C] matches R[A].type, jmp +B and next call will be on sites[C] */
 89  TR_OP_CALL,       /* A B C    call last looked up method on R[A] with B>>1 args starting at R[A+2],
 90                                if B & 1, splat last arg,
 91                                if C > 0 pass block[C-1] */
 92  TR_OP_JMP,        /*   sBx    jump sBx instructions */
 93  TR_OP_JMPIF,      /* A sBx    jump sBx instructions if R[A] */
 94  TR_OP_JMPUNLESS,  /* A sBx    jump sBx instructions unless R[A] */
 95  TR_OP_RETURN,     /* A        return R[A] (can be non local) */
 96  TR_OP_THROW,      /* A B      throw type=A value=R[B] */
 97  TR_OP_SETUPVAL,   /* A B      upvals[B] = R[A] */
 98  TR_OP_GETUPVAL,   /* A B      R[A] = upvals[B] */
 99  TR_OP_DEF,        /* A Bx     define method k[Bx] on self w/ blocks[A] */
100  TR_OP_METADEF,    /* A Bx     define method k[Bx] on R[nA] w/ blocks[A] */
101  TR_OP_GETCONST,   /* A Bx     R[A] = Consts[k[Bx]] */
102  TR_OP_SETCONST,   /* A Bx     Consts[k[Bx]] = R[A] */
103  TR_OP_CLASS,      /* A Bx     define class k[Bx] on self w/ blocks[A] and superclass R[nA] */
104  TR_OP_MODULE,     /* A Bx     define module k[Bx] on self w/ blocks[A] */
105  TR_OP_NEWARRAY,   /* A B      R[A] = Array.new(R[A+1]..R[A+1+B]) */
106  TR_OP_NEWHASH,    /* A B      R[A] = Hash.new(R[A+1] => R[A+2] .. R[A+1+B*2] => R[A+2+B*2]) */
107  TR_OP_YIELD,      /* A B      R[A] = passed_block.call(R[A+1]..R[A+1+B]) */
108  TR_OP_GETIVAR,    /* A Bx     R[A] = self.ivars[k[Bx]] */
109  TR_OP_SETIVAR,    /* A Bx     self.ivars[k[Bx]] = R[A] */
110  TR_OP_GETCVAR,    /* A Bx     R[A] = class.ivars[k[Bx]] */
111  TR_OP_SETCVAR,    /* A Bx     class.ivars[k[Bx]] = R[A] */
112  TR_OP_GETGLOBAL,  /* A Bx     R[A] = globals[k[Bx]] */
113  TR_OP_SETGLOBAL,  /* A Bx     globals[k[Bx]] = R[A] */
114  TR_OP_NEWRANGE,   /* A B C    R[A] = Range.new(start:R[A], end:R[B], exclusive:C) */
115  TR_OP_ADD,        /* A B C    R[A] = RK[B] + RK[C] */
116  TR_OP_SUB,        /* A B C    R[A] = RK[B] - RK[C] */
117  TR_OP_LT,         /* A B C    R[A] = RK[B] < RK[C] */
118  TR_OP_NEG,        /* A B      R[A] = -RK[B] */
119  TR_OP_NOT,        /* A B      R[A] = !RK[B] */
120  TR_OP_SUPER,      /* TODO */
121};
122
123#define TR_OP_NAMES \
124  "boing", \
125  "move", \
126  "loadk", \
127  "string", \
128  "bool", \
129  "nil", \
130  "self", \
131  "lookup", \
132  "cache", \
133  "call", \
134  "jmp", \
135  "jmpif", \
136  "jmpunless", \
137  "return", \
138  "throw", \
139  "setupval", \
140  "getupval", \
141  "def", \
142  "metadef", \
143  "getconst", \
144  "setconst", \
145  "class", \
146  "module", \
147  "newarray", \
148  "newhash", \
149  "yield", \
150  "getivar", \
151  "setivar", \
152  "getcvar", \
153  "setcvar", \
154  "getglobal", \
155  "setglobal", \
156  "newrange", \
157  "add", \
158  "sub", \
159  "lt", \
160  "neg", \
161  "not", \
162  "super"
163
164#if TR_THREADED_DISPATCH
165/* has to be in some order as in enum TrInstCode */
166#define TR_OP_LABELS \
167  &&op_BOING, \
168  &&op_MOVE, \
169  &&op_LOADK, \
170  &&op_STRING, \
171  &&op_BOOL, \
172  &&op_NIL, \
173  &&op_SELF, \
174  &&op_LOOKUP, \
175  &&op_CACHE, \
176  &&op_CALL, \
177  &&op_JMP, \
178  &&op_JMPIF, \
179  &&op_JMPUNLESS, \
180  &&op_RETURN, \
181  &&op_THROW, \
182  &&op_SETUPVAL, \
183  &&op_GETUPVAL, \
184  &&op_DEF, \
185  &&op_METADEF, \
186  &&op_GETCONST, \
187  &&op_SETCONST, \
188  &&op_CLASS, \
189  &&op_MODULE, \
190  &&op_NEWARRAY, \
191  &&op_NEWHASH, \
192  &&op_YIELD, \
193  &&op_GETIVAR, \
194  &&op_SETIVAR, \
195  &&op_GETCVAR, \
196  &&op_SETCVAR, \
197  &&op_GETGLOBAL, \
198  &&op_SETGLOBAL, \
199  &&op_NEWRANGE, \
200  &&op_ADD, \
201  &&op_SUB, \
202  &&op_LT, \
203  &&op_NEG, \
204  &&op_NOT
205  
206#endif
207
208#endif /* _OPCODE_H_ */