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