/source/Opcodes.ooc

http://github.com/fperrad/ooc-lua · Unknown · 374 lines · 304 code · 70 blank · 0 comment · 0 complexity · bc1fb972ad7b99df8a1004458af0dd1f MD5 · raw file

  1. include stdint
  2. /*===========================================================================
  3. We assume that instructions are unsigned numbers.
  4. All instructions have an opcode in the first 6 bits.
  5. Instructions can have the following fields:
  6. `A' : 8 bits
  7. `B' : 9 bits
  8. `C' : 9 bits
  9. 'Ax' : 26 bits ('A', 'B', and 'C' together)
  10. `Bx' : 18 bits (`B' and `C' together)
  11. `sBx' : signed Bx
  12. A signed argument is represented in excess K; that is, the number
  13. value is the unsigned value minus K. K is exactly the maximum value
  14. for that argument (so that -max is represented by 0, and +max is
  15. represented by 2*max), which is half the maximum for the corresponding
  16. unsigned argument.
  17. ===========================================================================*/
  18. OpMode: enum { /* basic instruction format */
  19. iABC,
  20. iABx,
  21. iAsBx,
  22. iAx
  23. }
  24. /*
  25. ** size and position of opcode arguments.
  26. */
  27. SIZE_C := const 9
  28. SIZE_B := const 9
  29. SIZE_Bx := const SIZE_C + SIZE_B
  30. SIZE_A := const 8
  31. SIZE_Ax := const SIZE_C + SIZE_B + SIZE_A
  32. SIZE_OP := const 6
  33. POS_OP := const 0
  34. POS_A := const POS_OP + SIZE_OP
  35. POS_C := const POS_A + SIZE_A
  36. POS_B := const POS_C + SIZE_C
  37. POS_Bx := const POS_C
  38. POS_Ax := const POS_A
  39. /*
  40. ** limits for opcode arguments.
  41. ** we use (signed) int to manipulate most arguments,
  42. ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
  43. */
  44. MAXARG_Bx := const (1 << SIZE_Bx) - 1
  45. MAXARG_sBx := const MAXARG_Bx >> 1 /* `sBx' is signed */
  46. MAXARG_Ax := const (1 << SIZE_Ax) - 1
  47. MAXARG_A := const (1 << SIZE_A) - 1
  48. MAXARG_B := const (1 << SIZE_B) - 1
  49. MAXARG_C := const (1 << SIZE_C) - 1
  50. Instruction: cover from uint32_t {
  51. createABC: static inline func(o: OpCode, a, b, c: UInt) -> This {
  52. return (o as UInt << POS_OP | a << POS_A | b << POS_B | c << POS_C) as Instruction
  53. }
  54. createABx: static inline func(o: OpCode, a, bc: UInt) -> This {
  55. return (o as UInt << POS_OP | a << POS_A | bc << POS_Bx) as Instruction
  56. }
  57. createAx: static inline func(o: OpCode, a: UInt) -> This {
  58. return (o as UInt << POS_OP | a << POS_Ax) as Instruction
  59. }
  60. getOpcode: inline func -> OpCode {
  61. return ((this >> POS_OP) & ~(~0 << SIZE_OP)) as OpCode
  62. }
  63. setOpcode: inline func(o: OpCode) -> Instruction {
  64. return (this & ~(~(~0 << SIZE_OP) << POS_OP)) | ((o << POS_OP) & (~(~0 << SIZE_OP)) << POS_OP)
  65. }
  66. getarg_A: inline func -> Int {
  67. return ((this >> POS_A) & ~(~0 << SIZE_A)) as Int
  68. }
  69. setarg_A: inline func(a: UInt) -> Instruction {
  70. return (this & ~(~(~0 << SIZE_A) << POS_A)) | ((a << POS_A) & (~(~0 << SIZE_A)) << POS_A)
  71. }
  72. getarg_B: inline func -> Int {
  73. return ((this >> POS_B) & ~(~0 << SIZE_B)) as Int
  74. }
  75. setarg_B: inline func(b: UInt) -> Instruction {
  76. return (this & ~(~(~0 << SIZE_B) << POS_B)) | ((b << POS_B) & (~(~0 << SIZE_B)) << POS_B)
  77. }
  78. getarg_C: inline func -> Int {
  79. return ((this >> POS_C) & ~(~0 << SIZE_C)) as Int
  80. }
  81. setarg_C: inline func(c: UInt) -> Instruction {
  82. return (this & ~(~(~0 << SIZE_C) << POS_C)) | ((c << POS_C) & (~(~0 << SIZE_C)) << POS_C)
  83. }
  84. getarg_Bx: inline func -> Int {
  85. return ((this >> POS_Bx) & ~(~0 << SIZE_Bx)) as Int
  86. }
  87. setarg_Bx: inline func(b: UInt) -> Instruction {
  88. return (this & ~(~(~0 << SIZE_Bx) << POS_Bx)) | ((b << POS_Bx) & (~(~0 << SIZE_Bx)) << POS_Bx)
  89. }
  90. getarg_Ax: inline func -> Int {
  91. return ((this >> POS_Ax) & ~(~0 << SIZE_Ax)) as Int
  92. }
  93. setarg_Ax: inline func(a: UInt) -> Instruction {
  94. return (this & ~(~(~0 << SIZE_Ax) << POS_Ax)) | ((a << POS_Ax) & (~(~0 << SIZE_Ax)) << POS_Ax)
  95. }
  96. getarg_sBx: inline func -> Int {
  97. return (((this >> POS_Bx) & ~(~0 << SIZE_Bx)) - MAXARG_sBx) as Int
  98. }
  99. setarg_sBx: inline func(b: Int) -> Instruction {
  100. return (this & ~(~(~0 << SIZE_Bx) << POS_Bx)) | (((b + MAXARG_sBx) << POS_Bx) & (~(~0 << SIZE_Bx)) << POS_Bx)
  101. }
  102. }
  103. /* this bit 1 means constant (0 means register) */
  104. BITRK := const 1 << (SIZE_B - 1)
  105. MAXINDEXRK := const BITRK - 1
  106. /*
  107. ** invalid register that fits in 8 bits
  108. */
  109. NO_REG := const MAXARG_A
  110. /*
  111. ** R(x) - register
  112. ** Kst(x) - constant (in constant table)
  113. ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
  114. */
  115. /*
  116. ** grep "ORDER OP" if you change these enums
  117. */
  118. OpCode: enum {
  119. /*----------------------------------------------------------------------
  120. name args description
  121. ------------------------------------------------------------------------*/
  122. OP_MOVE,/* A B R(A) := R(B) */
  123. OP_LOADK,/* A Bx R(A) := Kst(Bx - 1) */
  124. OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
  125. OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
  126. OP_GETUPVAL,/* A B R(A) := UpValue[B] */
  127. OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
  128. OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
  129. OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
  130. OP_SETUPVAL,/* A B UpValue[B] := R(A) */
  131. OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
  132. OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
  133. OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
  134. OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
  135. OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
  136. OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
  137. OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
  138. OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
  139. OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
  140. OP_UNM,/* A B R(A) := -R(B) */
  141. OP_NOT,/* A B R(A) := not R(B) */
  142. OP_LEN,/* A B R(A) := length of R(B) */
  143. OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
  144. OP_JMP,/* sBx pc+=sBx */
  145. OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
  146. OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
  147. OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
  148. OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
  149. OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
  150. OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
  151. OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
  152. OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
  153. OP_FORLOOP,/* A sBx R(A)+=R(A+2);
  154. if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
  155. OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
  156. OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
  157. OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
  158. OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
  159. OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
  160. OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
  161. OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
  162. OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
  163. getOpMode: inline func -> OpMode {
  164. return (OP_MODES[this] & 3) as OpMode
  165. }
  166. getBMode: inline func -> OpArgMask {
  167. return ((OP_MODES[this] >> 4) & 3) as OpArgMask
  168. }
  169. getCMode: inline func -> OpArgMask {
  170. return ((OP_MODES[this] >> 2) & 3) as OpArgMask
  171. }
  172. testAMode: inline func -> Bool {
  173. return (OP_MODES[this] & (1 << 6)) != 0
  174. }
  175. testTMode: inline func -> Bool {
  176. return (OP_MODES[this] & (1 << 7)) != 0
  177. }
  178. }
  179. OP_NAMES := const [
  180. "MOVE",
  181. "LOADK",
  182. "LOADBOOL",
  183. "LOADNIL",
  184. "GETUPVAL",
  185. "GETTABUP",
  186. "GETTABLE",
  187. "SETTABUP",
  188. "SETUPVAL",
  189. "SETTABLE",
  190. "NEWTABLE",
  191. "SELF",
  192. "ADD",
  193. "SUB",
  194. "MUL",
  195. "DIV",
  196. "MOD",
  197. "POW",
  198. "UNM",
  199. "NOT",
  200. "LEN",
  201. "CONCAT",
  202. "JMP",
  203. "EQ",
  204. "LT",
  205. "LE",
  206. "TEST",
  207. "TESTSET",
  208. "CALL",
  209. "TAILCALL",
  210. "RETURN",
  211. "FORLOOP",
  212. "FORPREP",
  213. "TFORCALL",
  214. "TFORLOOP",
  215. "SETLIST",
  216. "CLOSE",
  217. "CLOSURE",
  218. "VARARG",
  219. "EXTRAARG"
  220. ]
  221. /*
  222. ** masks for instruction properties. The format is:
  223. ** bits 0-1: op mode
  224. ** bits 2-3: C arg mode
  225. ** bits 4-5: B arg mode
  226. ** bit 6: instruction set register A
  227. ** bit 7: operator is a test (next instruction must be a jump)
  228. */
  229. OpArgMask: enum {
  230. OpArgN, /* argument is not used */
  231. OpArgU, /* argument is used */
  232. OpArgR, /* argument is a register or a jump offset */
  233. OpArgK /* argument is a constant or register/constant */
  234. }
  235. OP_MODES := const [
  236. /* T A B C mode opcode */
  237. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_MOVE */
  238. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgN<<2) | OpMode iABx, /* OP_LOADK */
  239. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_LOADBOOL */
  240. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_LOADNIL */
  241. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_GETUPVAL */
  242. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_GETTABUP */
  243. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_GETTABLE */
  244. (0<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SETTABUP */
  245. (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_SETUPVAL */
  246. (0<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SETTABLE */
  247. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_NEWTABLE */
  248. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SELF */
  249. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_ADD */
  250. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_SUB */
  251. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_MUL */
  252. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_DIV */
  253. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_MOD */
  254. (0<<7) | (1<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_POW */
  255. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_UNM */
  256. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_NOT */
  257. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_LEN */
  258. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgR<<2) | OpMode iABC, /* OP_CONCAT */
  259. (0<<7) | (0<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_JMP */
  260. (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_EQ */
  261. (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_LT */
  262. (1<<7) | (0<<6) | (OpArgMask OpArgK<<4) | (OpArgMask OpArgK<<2) | OpMode iABC, /* OP_LE */
  263. (1<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TEST */
  264. (1<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TESTSET */
  265. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_CALL */
  266. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TAILCALL */
  267. (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_RETURN */
  268. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_FORLOOP */
  269. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_FORPREP */
  270. (0<<7) | (0<<6) | (OpArgMask OpArgN<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_TFORCALL */
  271. (0<<7) | (1<<6) | (OpArgMask OpArgR<<4) | (OpArgMask OpArgN<<2) | OpMode iAsBx, /* OP_TFORLOOP */
  272. (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iABC, /* OP_SETLIST */
  273. (0<<7) | (0<<6) | (OpArgMask OpArgN<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_CLOSE */
  274. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABx, /* OP_CLOSURE */
  275. (0<<7) | (1<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgN<<2) | OpMode iABC, /* OP_VARARG */
  276. (0<<7) | (0<<6) | (OpArgMask OpArgU<<4) | (OpArgMask OpArgU<<2) | OpMode iAx, /* OP_EXTRAARG */
  277. ]
  278. /* number of list items to accumulate before a SETLIST instruction */
  279. LFIELDS_PER_FLUSH := const 50
  280. /* option for multiple returns in 'lua_pcall' and 'lua_call' */
  281. LUA_MULTRET := const -1
  282. /*
  283. ** converts an integer to a "floating point byte", represented as
  284. ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
  285. ** eeeee != 0 and (xxx) otherwise.
  286. */
  287. int2fb: func(x: UInt32) -> Int {
  288. e := 0 /* exponent */
  289. if (x < 8)
  290. return x
  291. while (x >= 0x10) {
  292. x = (x+1) >> 1
  293. e += 1
  294. }
  295. return ((e+1) << 3) | (x as Int - 8)
  296. }
  297. /* converts back */
  298. fb2int: func(x: Int) -> Int {
  299. e := (x >> 3) & 0x1f
  300. if (e == 0)
  301. return x
  302. else
  303. return ((x & 7) + 8) << (e - 1)
  304. }