github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/evm/asm/opcodes.go (about)

     1  // Copyright Monax Industries Limited
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package asm
     5  
     6  import (
     7  	"fmt"
     8  )
     9  
    10  type OpCode byte
    11  
    12  const (
    13  	// Op codes
    14  	// 0x0 range - arithmetic ops
    15  	STOP OpCode = iota
    16  	ADD
    17  	MUL
    18  	SUB
    19  	DIV
    20  	SDIV
    21  	MOD
    22  	SMOD
    23  	ADDMOD
    24  	MULMOD
    25  	EXP
    26  	SIGNEXTEND
    27  )
    28  
    29  const (
    30  	LT OpCode = iota + 0x10
    31  	GT
    32  	SLT
    33  	SGT
    34  	EQ
    35  	ISZERO
    36  	AND
    37  	OR
    38  	XOR
    39  	NOT
    40  	BYTE
    41  	SHL
    42  	SHR
    43  	SAR
    44  
    45  	SHA3 = 0x20
    46  )
    47  
    48  const (
    49  	// 0x30 range - closure state
    50  	ADDRESS OpCode = 0x30 + iota
    51  	BALANCE
    52  	ORIGIN
    53  	CALLER
    54  	CALLVALUE
    55  	CALLDATALOAD
    56  	CALLDATASIZE
    57  	CALLDATACOPY
    58  	CODESIZE
    59  	CODECOPY
    60  	GASPRICE_DEPRECATED
    61  	EXTCODESIZE
    62  	EXTCODECOPY
    63  	RETURNDATASIZE
    64  	RETURNDATACOPY
    65  	EXTCODEHASH // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1052.md
    66  )
    67  
    68  const (
    69  	// 0x40 range - block operations
    70  	BLOCKHASH OpCode = 0x40 + iota
    71  	COINBASE
    72  	TIMESTAMP
    73  	BLOCKHEIGHT
    74  	DIFFICULTY
    75  	GASLIMIT
    76  	CHAINID
    77  )
    78  
    79  const (
    80  	// 0x50 range - 'storage' and execution
    81  	POP OpCode = 0x50 + iota
    82  	MLOAD
    83  	MSTORE
    84  	MSTORE8
    85  	SLOAD
    86  	SSTORE
    87  	JUMP
    88  	JUMPI
    89  	PC
    90  	MSIZE
    91  	GAS
    92  	JUMPDEST
    93  )
    94  
    95  const (
    96  	// 0x60 range
    97  	PUSH1 OpCode = 0x60 + iota
    98  	PUSH2
    99  	PUSH3
   100  	PUSH4
   101  	PUSH5
   102  	PUSH6
   103  	PUSH7
   104  	PUSH8
   105  	PUSH9
   106  	PUSH10
   107  	PUSH11
   108  	PUSH12
   109  	PUSH13
   110  	PUSH14
   111  	PUSH15
   112  	PUSH16
   113  	PUSH17
   114  	PUSH18
   115  	PUSH19
   116  	PUSH20
   117  	PUSH21
   118  	PUSH22
   119  	PUSH23
   120  	PUSH24
   121  	PUSH25
   122  	PUSH26
   123  	PUSH27
   124  	PUSH28
   125  	PUSH29
   126  	PUSH30
   127  	PUSH31
   128  	PUSH32
   129  	DUP1
   130  	DUP2
   131  	DUP3
   132  	DUP4
   133  	DUP5
   134  	DUP6
   135  	DUP7
   136  	DUP8
   137  	DUP9
   138  	DUP10
   139  	DUP11
   140  	DUP12
   141  	DUP13
   142  	DUP14
   143  	DUP15
   144  	DUP16
   145  	SWAP1
   146  	SWAP2
   147  	SWAP3
   148  	SWAP4
   149  	SWAP5
   150  	SWAP6
   151  	SWAP7
   152  	SWAP8
   153  	SWAP9
   154  	SWAP10
   155  	SWAP11
   156  	SWAP12
   157  	SWAP13
   158  	SWAP14
   159  	SWAP15
   160  	SWAP16
   161  )
   162  
   163  const (
   164  	LOG0 OpCode = 0xa0 + iota
   165  	LOG1
   166  	LOG2
   167  	LOG3
   168  	LOG4
   169  )
   170  
   171  const (
   172  	// 0xf0 range - closures
   173  	CREATE OpCode = 0xf0 + iota
   174  	CALL
   175  	CALLCODE
   176  	RETURN
   177  	DELEGATECALL
   178  	CREATE2
   179  
   180  	// 0x70 range - other
   181  	STATICCALL   = 0xfa
   182  	REVERT       = 0xfd
   183  	INVALID      = 0xfe
   184  	SELFDESTRUCT = 0xff
   185  )
   186  
   187  var opCodeNames = map[OpCode]string{
   188  	// 0x0 range - arithmetic ops
   189  	STOP:       "STOP",
   190  	ADD:        "ADD",
   191  	MUL:        "MUL",
   192  	SUB:        "SUB",
   193  	DIV:        "DIV",
   194  	SDIV:       "SDIV",
   195  	MOD:        "MOD",
   196  	SMOD:       "SMOD",
   197  	EXP:        "EXP",
   198  	NOT:        "NOT",
   199  	LT:         "LT",
   200  	GT:         "GT",
   201  	SLT:        "SLT",
   202  	SGT:        "SGT",
   203  	EQ:         "EQ",
   204  	ISZERO:     "ISZERO",
   205  	SIGNEXTEND: "SIGNEXTEND",
   206  
   207  	// 0x10 range - bit ops
   208  	AND:    "AND",
   209  	OR:     "OR",
   210  	XOR:    "XOR",
   211  	BYTE:   "BYTE",
   212  	SHL:    "SHL",
   213  	SHR:    "SHR",
   214  	SAR:    "SAR",
   215  	ADDMOD: "ADDMOD",
   216  	MULMOD: "MULMOD",
   217  
   218  	// 0x20 range - crypto
   219  	SHA3: "SHA3",
   220  
   221  	// 0x30 range - closure state
   222  	ADDRESS:             "ADDRESS",
   223  	BALANCE:             "BALANCE",
   224  	ORIGIN:              "ORIGIN",
   225  	CALLER:              "CALLER",
   226  	CALLVALUE:           "CALLVALUE",
   227  	CALLDATALOAD:        "CALLDATALOAD",
   228  	CALLDATASIZE:        "CALLDATASIZE",
   229  	CALLDATACOPY:        "CALLDATACOPY",
   230  	CODESIZE:            "CODESIZE",
   231  	CODECOPY:            "CODECOPY",
   232  	GASPRICE_DEPRECATED: "TXGASPRICE_DEPRECATED",
   233  	EXTCODESIZE:         "EXTCODESIZE",
   234  	EXTCODECOPY:         "EXTCODECOPY",
   235  	RETURNDATASIZE:      "RETURNDATASIZE",
   236  	RETURNDATACOPY:      "RETURNDATACOPY",
   237  	EXTCODEHASH:         "EXTCODEHASH",
   238  
   239  	// 0x40 range - block operations
   240  	BLOCKHASH:   "BLOCKHASH",
   241  	COINBASE:    "COINBASE",
   242  	TIMESTAMP:   "TIMESTAMP",
   243  	BLOCKHEIGHT: "BLOCKHEIGHT",
   244  	DIFFICULTY:  "DIFFICULTY",
   245  	GASLIMIT:    "GASLIMIT",
   246  	CHAINID:     "CHAINID",
   247  
   248  	// 0x50 range - 'storage' and execution
   249  	POP:      "POP",
   250  	MLOAD:    "MLOAD",
   251  	MSTORE:   "MSTORE",
   252  	MSTORE8:  "MSTORE8",
   253  	SLOAD:    "SLOAD",
   254  	SSTORE:   "SSTORE",
   255  	JUMP:     "JUMP",
   256  	JUMPI:    "JUMPI",
   257  	PC:       "PC",
   258  	MSIZE:    "MSIZE",
   259  	GAS:      "GAS",
   260  	JUMPDEST: "JUMPDEST",
   261  
   262  	// 0x60 range - push
   263  	PUSH1:  "PUSH1",
   264  	PUSH2:  "PUSH2",
   265  	PUSH3:  "PUSH3",
   266  	PUSH4:  "PUSH4",
   267  	PUSH5:  "PUSH5",
   268  	PUSH6:  "PUSH6",
   269  	PUSH7:  "PUSH7",
   270  	PUSH8:  "PUSH8",
   271  	PUSH9:  "PUSH9",
   272  	PUSH10: "PUSH10",
   273  	PUSH11: "PUSH11",
   274  	PUSH12: "PUSH12",
   275  	PUSH13: "PUSH13",
   276  	PUSH14: "PUSH14",
   277  	PUSH15: "PUSH15",
   278  	PUSH16: "PUSH16",
   279  	PUSH17: "PUSH17",
   280  	PUSH18: "PUSH18",
   281  	PUSH19: "PUSH19",
   282  	PUSH20: "PUSH20",
   283  	PUSH21: "PUSH21",
   284  	PUSH22: "PUSH22",
   285  	PUSH23: "PUSH23",
   286  	PUSH24: "PUSH24",
   287  	PUSH25: "PUSH25",
   288  	PUSH26: "PUSH26",
   289  	PUSH27: "PUSH27",
   290  	PUSH28: "PUSH28",
   291  	PUSH29: "PUSH29",
   292  	PUSH30: "PUSH30",
   293  	PUSH31: "PUSH31",
   294  	PUSH32: "PUSH32",
   295  
   296  	DUP1:  "DUP1",
   297  	DUP2:  "DUP2",
   298  	DUP3:  "DUP3",
   299  	DUP4:  "DUP4",
   300  	DUP5:  "DUP5",
   301  	DUP6:  "DUP6",
   302  	DUP7:  "DUP7",
   303  	DUP8:  "DUP8",
   304  	DUP9:  "DUP9",
   305  	DUP10: "DUP10",
   306  	DUP11: "DUP11",
   307  	DUP12: "DUP12",
   308  	DUP13: "DUP13",
   309  	DUP14: "DUP14",
   310  	DUP15: "DUP15",
   311  	DUP16: "DUP16",
   312  
   313  	SWAP1:  "SWAP1",
   314  	SWAP2:  "SWAP2",
   315  	SWAP3:  "SWAP3",
   316  	SWAP4:  "SWAP4",
   317  	SWAP5:  "SWAP5",
   318  	SWAP6:  "SWAP6",
   319  	SWAP7:  "SWAP7",
   320  	SWAP8:  "SWAP8",
   321  	SWAP9:  "SWAP9",
   322  	SWAP10: "SWAP10",
   323  	SWAP11: "SWAP11",
   324  	SWAP12: "SWAP12",
   325  	SWAP13: "SWAP13",
   326  	SWAP14: "SWAP14",
   327  	SWAP15: "SWAP15",
   328  	SWAP16: "SWAP16",
   329  	LOG0:   "LOG0",
   330  	LOG1:   "LOG1",
   331  	LOG2:   "LOG2",
   332  	LOG3:   "LOG3",
   333  	LOG4:   "LOG4",
   334  
   335  	// 0xf0 range
   336  	CREATE:       "CREATE",
   337  	CALL:         "CALL",
   338  	RETURN:       "RETURN",
   339  	CALLCODE:     "CALLCODE",
   340  	DELEGATECALL: "DELEGATECALL",
   341  	CREATE2:      "CREATE2",
   342  	STATICCALL:   "STATICCALL",
   343  	// 0x70 range - other
   344  	REVERT:       "REVERT",
   345  	INVALID:      "INVALID",
   346  	SELFDESTRUCT: "SELFDESTRUCT",
   347  }
   348  
   349  func GetOpCode(b byte) (OpCode, bool) {
   350  	op := OpCode(b)
   351  	_, isOpcode := opCodeNames[op]
   352  	return op, isOpcode
   353  
   354  }
   355  
   356  func (o OpCode) String() string {
   357  	return o.Name()
   358  }
   359  
   360  func (o OpCode) Name() string {
   361  	str := opCodeNames[o]
   362  	if len(str) == 0 {
   363  		return fmt.Sprintf("Non-opcode 0x%x", int(o))
   364  	}
   365  
   366  	return str
   367  }
   368  
   369  // If OpCode is a Push<N> returns the number of bytes pushed (between 1 and 32 inclusive)
   370  func (o OpCode) Pushes() int {
   371  	if o >= PUSH1 && o <= PUSH32 {
   372  		return int(o - PUSH1 + 1)
   373  	}
   374  	return 0
   375  }