opcodes.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Author: simon
  2. // Author: ynwdlxm@163.com
  3. // Date: 2024/4/13 22:53
  4. // Desc: 操作码 每条指令占4 个字节(32 比特),其中 6 比特用于操作码(Opcode),26 比特用于操作数(Operand)
  5. // * iABC 模式指令可以携带 A、B、C 三个操作数,分别占用 8、9、9 个比特
  6. // * iABx 模式指令可以携带 A 和 Bx 两个操作数,分别占用 8 和 18 个比特
  7. // * iAsBx 模式的指令可以携带 A 和 sBx 两个操作数,分别占用 8 和 18 个比特
  8. // * iAx 模式的指令中携带一个操作数,占用全部 26 比特
  9. // * 在 四种模式中,只用 iAsBx 模式下的 sBx 操作数会被解释成有符号整数,其他情况下操作数均被解释成无符号整数
  10. package vm
  11. // op MODE
  12. const (
  13. IABC = iota
  14. IABx
  15. IAsBx
  16. IAx
  17. )
  18. // Lua 5.3 共定义了 47 条指令,按照作用,
  19. // 可大致分为 常量加载指令、运算符相关指令、循环和跳转指令、函数调用相关指令、表操作指令以及 Upvalue 操作指令
  20. const (
  21. MOVE = iota
  22. LOADK
  23. LOADKX
  24. LOADBOOL
  25. LOADNIL
  26. GETUPVAL
  27. GETTABUP
  28. GETTABLE
  29. SETTABUP
  30. SETUPVAL
  31. SETTABLE
  32. NEWTABLE
  33. SELF
  34. ADD
  35. SUB
  36. MUL
  37. MOD
  38. POW
  39. DIV
  40. IDIV
  41. BAND
  42. BOR
  43. BXOR
  44. SHL
  45. SHR
  46. UNM
  47. BNOT
  48. NOT
  49. LEN
  50. CONCAT
  51. JMP
  52. EQ
  53. LT
  54. LE
  55. TEST
  56. TESTSET
  57. CALL
  58. TALLCALL
  59. RETURN
  60. FORLOOP
  61. FORPREP
  62. TFORCALL
  63. TFORLOOP
  64. SETLIST
  65. CLOSURE
  66. VARARG
  67. EXTRAARG
  68. )
  69. // 操作数
  70. const (
  71. OpArgN = iota // argument is not used
  72. OpArgU // argument is used
  73. OpArgR // argument is a register or a jump offset
  74. OpArgK // argument is a constant or register/constant
  75. )
  76. type opcode struct {
  77. testFlag byte // operator is a test (next instruction must be a jump)
  78. setAFlag byte // instruction set register A
  79. argBMode byte // B arg mode
  80. argCMode byte // C arg mode
  81. opMode byte // op mode
  82. name string
  83. }
  84. var opcodes = []opcode{
  85. /*testFlag setAFlag argBMode argCMode opMode name */
  86. {0, 1, OpArgR, OpArgN, IABC, "MOVE "},
  87. {0, 1, OpArgK, OpArgN, IABx, "LOADK "},
  88. {0, 1, OpArgN, OpArgN, IABx, "LOADKX "},
  89. {0, 1, OpArgU, OpArgU, IABC, "LOADBOOL "},
  90. {0, 1, OpArgU, OpArgN, IABC, "LOADNIl "},
  91. {0, 1, OpArgU, OpArgN, IABC, "GETUPVAL "},
  92. {0, 1, OpArgU, OpArgK, IABC, "GETTABUP "},
  93. {0, 1, OpArgR, OpArgK, IABC, "GETTABLE "},
  94. {0, 0, OpArgK, OpArgK, IABC, "GETTABUP "},
  95. {0, 0, OpArgU, OpArgN, IABC, "SETUPVAL "},
  96. {0, 0, OpArgK, OpArgK, IABC, "SETTABLE "},
  97. {0, 1, OpArgU, OpArgU, IABC, "NEWTABLE "},
  98. {0, 1, OpArgR, OpArgK, IABC, "SELF "},
  99. {0, 1, OpArgK, OpArgK, IABC, "ADD "},
  100. {0, 1, OpArgK, OpArgK, IABC, "SUB "},
  101. {0, 1, OpArgK, OpArgK, IABC, "MUL "},
  102. {0, 1, OpArgK, OpArgK, IABC, "MOD "},
  103. {0, 1, OpArgK, OpArgK, IABC, "POW "},
  104. {0, 1, OpArgK, OpArgK, IABC, "DIV "},
  105. {0, 1, OpArgK, OpArgK, IABC, "IDIV "},
  106. {0, 1, OpArgK, OpArgK, IABC, "BAND "},
  107. {0, 1, OpArgK, OpArgK, IABC, "BOR "},
  108. {0, 1, OpArgK, OpArgK, IABC, "BXOR "},
  109. {0, 1, OpArgK, OpArgK, IABC, "SHL "},
  110. {0, 1, OpArgK, OpArgK, IABC, "SHR "},
  111. {0, 1, OpArgR, OpArgN, IABC, "UNM "},
  112. {0, 1, OpArgR, OpArgN, IABC, "BNOT "},
  113. {0, 1, OpArgR, OpArgN, IABC, "NOT "},
  114. {0, 1, OpArgR, OpArgN, IABC, "LEN "},
  115. {0, 1, OpArgR, OpArgR, IABC, "CONCAT "},
  116. {0, 0, OpArgR, OpArgN, IAsBx, "JMP "},
  117. {1, 0, OpArgK, OpArgK, IABC, "EQ "},
  118. {1, 0, OpArgK, OpArgK, IABC, "LT "},
  119. {1, 0, OpArgK, OpArgK, IABC, "LE "},
  120. {1, 0, OpArgN, OpArgU, IABC, "TEST "},
  121. {1, 1, OpArgR, OpArgU, IABC, "TESTSET "},
  122. {0, 1, OpArgU, OpArgU, IABC, "CALL "},
  123. {0, 1, OpArgU, OpArgU, IABC, "TALLCALL "},
  124. {0, 0, OpArgU, OpArgN, IABC, "RETURN "},
  125. {0, 1, OpArgR, OpArgN, IAsBx, "FORLOOP "},
  126. {0, 1, OpArgR, OpArgN, IAsBx, "FORREEP "},
  127. {0, 0, OpArgU, OpArgU, IABC, "SETLIST "},
  128. {0, 1, OpArgU, OpArgN, IABx, "CLOSURE "},
  129. {0, 1, OpArgU, OpArgN, IABC, "VARARG "},
  130. {0, 0, OpArgU, OpArgU, IAx, "EXTRAARG "},
  131. }