#ifndef EVM_EVM_H
#define EVM_EVM_H

#include <r_util.h>

typedef enum {
	EVM_OP_STOP = 0x00,
	EVM_OP_ADD,
	EVM_OP_MUL,
	EVM_OP_SUB,
	EVM_OP_DIV,
	EVM_OP_SDIV,
	EVM_OP_MOD,
	EVM_OP_SMOD,
	EVM_OP_ADDMOD,
	EVM_OP_MULMOD,
	EVM_OP_EXP,
	EVM_OP_SIGNEXTEND,

	EVM_OP_LT = 0x10,
	EVM_OP_GT,
	EVM_OP_SLT,
	EVM_OP_SGT,
	EVM_OP_EQ,
	EVM_OP_ISZERO,
	EVM_OP_AND,
	EVM_OP_OR,
	EVM_OP_XOR,
	EVM_OP_NOT,
	EVM_OP_BYTE,
	EVM_OP_SHL,
	EVM_OP_SHR,
	EVM_OP_SAR,
	EVM_OP_SHA3 = 0x20,

	EVM_OP_ADDRESS = 0x30,
	EVM_OP_BALANCE,
	EVM_OP_ORIGIN,
	EVM_OP_CALLER,
	EVM_OP_CALLVALUE,
	EVM_OP_CALLDATALOAD,
	EVM_OP_CALLDATASIZE,
	EVM_OP_CALLDATACOPY,
	EVM_OP_CODESIZE,
	EVM_OP_CODECOPY,
	EVM_OP_GASPRICE,
	EVM_OP_EXTCODESIZE,
	EVM_OP_EXTCODECOPY,
	EVM_OP_RETURNDATASIZE,
	EVM_OP_RETURNDATACOPY,
	EVM_OP_EXTCODEHASH,
	EVM_OP_BLOCKHASH,
	EVM_OP_COINBASE,
	EVM_OP_TIMESTAMP,
	EVM_OP_NUMBER,
	EVM_OP_DIFFICULTY,
	EVM_OP_GASLIMIT,
	EVM_OP_CHAINID,
	EVM_OP_SELFBALANCE,
	EVM_OP_BASEFEE,
	EVM_OP_BLOBHASH,
	EVM_OP_BLOBBASEFEE,

	EVM_OP_POP = 0x50,
	EVM_OP_MLOAD,
	EVM_OP_MSTORE,
	EVM_OP_MSTORE8,
	EVM_OP_SLOAD,
	EVM_OP_SSTORE,
	EVM_OP_JUMP,
	EVM_OP_JUMPI,
	EVM_OP_PC,
	EVM_OP_MSIZE,
	EVM_OP_GAS,
	EVM_OP_JUMPDEST,
	EVM_OP_TLOAD,
	EVM_OP_TSTORE,
	EVM_OP_MCOPY,

	EVM_OP_PUSH0 = 0x5f,
	EVM_OP_PUSH1 = 0x60,
	EVM_OP_PUSH2,
	EVM_OP_PUSH3,
	EVM_OP_PUSH4,
	EVM_OP_PUSH5,
	EVM_OP_PUSH6,
	EVM_OP_PUSH7,
	EVM_OP_PUSH8,
	EVM_OP_PUSH9,
	EVM_OP_PUSH10,
	EVM_OP_PUSH11,
	EVM_OP_PUSH12,
	EVM_OP_PUSH13,
	EVM_OP_PUSH14,
	EVM_OP_PUSH15,
	EVM_OP_PUSH16,
	EVM_OP_PUSH17,
	EVM_OP_PUSH18,
	EVM_OP_PUSH19,
	EVM_OP_PUSH20,
	EVM_OP_PUSH21,
	EVM_OP_PUSH22,
	EVM_OP_PUSH23,
	EVM_OP_PUSH24,
	EVM_OP_PUSH25,
	EVM_OP_PUSH26,
	EVM_OP_PUSH27,
	EVM_OP_PUSH28,
	EVM_OP_PUSH29,
	EVM_OP_PUSH30,
	EVM_OP_PUSH31,
	EVM_OP_PUSH32,
	EVM_OP_DUP1,
	EVM_OP_DUP2,
	EVM_OP_DUP3,
	EVM_OP_DUP4,
	EVM_OP_DUP5,
	EVM_OP_DUP6,
	EVM_OP_DUP7,
	EVM_OP_DUP8,
	EVM_OP_DUP9,
	EVM_OP_DUP10,
	EVM_OP_DUP11,
	EVM_OP_DUP12,
	EVM_OP_DUP13,
	EVM_OP_DUP14,
	EVM_OP_DUP15,
	EVM_OP_DUP16,
	EVM_OP_SWAP1,
	EVM_OP_SWAP2,
	EVM_OP_SWAP3,
	EVM_OP_SWAP4,
	EVM_OP_SWAP5,
	EVM_OP_SWAP6,
	EVM_OP_SWAP7,
	EVM_OP_SWAP8,
	EVM_OP_SWAP9,
	EVM_OP_SWAP10,
	EVM_OP_SWAP11,
	EVM_OP_SWAP12,
	EVM_OP_SWAP13,
	EVM_OP_SWAP14,
	EVM_OP_SWAP15,
	EVM_OP_SWAP16,

	EVM_OP_LOG0 = 0xa0,
	EVM_OP_LOG1,
	EVM_OP_LOG2,
	EVM_OP_LOG3,
	EVM_OP_LOG4,

	EVM_OP_CREATE = 0xf0,
	EVM_OP_CALL,
	EVM_OP_CALLCODE,
	EVM_OP_RETURN,
	EVM_OP_DELEGATECALL,
	EVM_OP_CREATE2,
	EVM_OP_STATICCALL = 0xfa,
	EVM_OP_REVERT = 0xfd,
	EVM_OP_INVALID,
	EVM_OP_SELFDESTRUCT
} EvmOpcodes;

typedef struct EvmOp {
	EvmOpcodes op;
	int len;
	const char *txt;
	// Largest opcode is "push32 0x" followed by hex value of 32 bytes.
	char txt_buf[9+64+1];
} EvmOp;

typedef struct {
	const char *txt;
	int len;
} EvmOpDef;

// extern const EvmOpDef opcodes[256];
// int evm_dis(EvmOp *op, const unsigned char *buf, int buf_len);

#endif	/* EVM_EVM_H */
