diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 82bd382b..0799fec1 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -78,6 +78,7 @@ pub struct Interpreter<'a> { pub(crate) halt_offsets: Vec, pub(crate) debug_offsets: Vec, running: bool, + opcode_count: [usize; 0x100], } pub fn run_with_kernel( @@ -132,6 +133,7 @@ impl<'a> Interpreter<'a> { halt_offsets: vec![DEFAULT_HALT_OFFSET], debug_offsets: vec![], running: false, + opcode_count: [0; 0x100], } } @@ -140,6 +142,12 @@ impl<'a> Interpreter<'a> { while self.running { self.run_opcode()?; } + println!("Opcode count:"); + for i in 0..0x100 { + if self.opcode_count[i] > 0 { + println!("{}: {}", get_mnemonic(i as u8), self.opcode_count[i]) + } + } Ok(()) } @@ -223,6 +231,7 @@ impl<'a> Interpreter<'a> { fn run_opcode(&mut self) -> anyhow::Result<()> { let opcode = self.code().get(self.offset).byte(0); + self.opcode_count[opcode as usize] += 1; self.incr(1); match opcode { 0x00 => self.run_stop(), // "STOP", @@ -690,6 +699,170 @@ fn find_jumpdests(code: &[u8]) -> Vec { res } +fn get_mnemonic(opcode: u8) -> &'static str { + match opcode { + 0x00 => "STOP", + 0x01 => "ADD", + 0x02 => "MUL", + 0x03 => "SUB", + 0x04 => "DIV", + 0x05 => "SDIV", + 0x06 => "MOD", + 0x07 => "SMOD", + 0x08 => "ADDMOD", + 0x09 => "MULMOD", + 0x0a => "EXP", + 0x0b => "SIGNEXTEND", + 0x0c => "ADDFP254", + 0x0d => "MULFP254", + 0x0e => "SUBFP254", + 0x10 => "LT", + 0x11 => "GT", + 0x12 => "SLT", + 0x13 => "SGT", + 0x14 => "EQ", + 0x15 => "ISZERO", + 0x16 => "AND", + 0x17 => "OR", + 0x18 => "XOR", + 0x19 => "NOT", + 0x1a => "BYTE", + 0x1b => "SHL", + 0x1c => "SHR", + 0x1d => "SAR", + 0x20 => "KECCAK256", + 0x21 => "KECCAK_GENERAL", + 0x30 => "ADDRESS", + 0x31 => "BALANCE", + 0x32 => "ORIGIN", + 0x33 => "CALLER", + 0x34 => "CALLVALUE", + 0x35 => "CALLDATALOAD", + 0x36 => "CALLDATASIZE", + 0x37 => "CALLDATACOPY", + 0x38 => "CODESIZE", + 0x39 => "CODECOPY", + 0x3a => "GASPRICE", + 0x3b => "EXTCODESIZE", + 0x3c => "EXTCODECOPY", + 0x3d => "RETURNDATASIZE", + 0x3e => "RETURNDATACOPY", + 0x3f => "EXTCODEHASH", + 0x40 => "BLOCKHASH", + 0x41 => "COINBASE", + 0x42 => "TIMESTAMP", + 0x43 => "NUMBER", + 0x44 => "DIFFICULTY", + 0x45 => "GASLIMIT", + 0x46 => "CHAINID", + 0x48 => "BASEFEE", + 0x49 => "PROVER_INPUT", + 0x50 => "POP", + 0x51 => "MLOAD", + 0x52 => "MSTORE", + 0x53 => "MSTORE8", + 0x54 => "SLOAD", + 0x55 => "SSTORE", + 0x56 => "JUMP", + 0x57 => "JUMPI", + 0x58 => "GETPC", + 0x59 => "MSIZE", + 0x5a => "GAS", + 0x5b => "JUMPDEST", + 0x5c => "GET_STATE_ROOT", + 0x5d => "SET_STATE_ROOT", + 0x5e => "GET_RECEIPT_ROOT", + 0x5f => "SET_RECEIPT_ROOT", + 0x60 => "PUSH1", + 0x61 => "PUSH2", + 0x62 => "PUSH3", + 0x63 => "PUSH4", + 0x64 => "PUSH5", + 0x65 => "PUSH6", + 0x66 => "PUSH7", + 0x67 => "PUSH8", + 0x68 => "PUSH9", + 0x69 => "PUSH10", + 0x6a => "PUSH11", + 0x6b => "PUSH12", + 0x6c => "PUSH13", + 0x6d => "PUSH14", + 0x6e => "PUSH15", + 0x6f => "PUSH16", + 0x70 => "PUSH17", + 0x71 => "PUSH18", + 0x72 => "PUSH19", + 0x73 => "PUSH20", + 0x74 => "PUSH21", + 0x75 => "PUSH22", + 0x76 => "PUSH23", + 0x77 => "PUSH24", + 0x78 => "PUSH25", + 0x79 => "PUSH26", + 0x7a => "PUSH27", + 0x7b => "PUSH28", + 0x7c => "PUSH29", + 0x7d => "PUSH30", + 0x7e => "PUSH31", + 0x7f => "PUSH32", + 0x80 => "DUP1", + 0x81 => "DUP2", + 0x82 => "DUP3", + 0x83 => "DUP4", + 0x84 => "DUP5", + 0x85 => "DUP6", + 0x86 => "DUP7", + 0x87 => "DUP8", + 0x88 => "DUP9", + 0x89 => "DUP10", + 0x8a => "DUP11", + 0x8b => "DUP12", + 0x8c => "DUP13", + 0x8d => "DUP14", + 0x8e => "DUP15", + 0x8f => "DUP16", + 0x90 => "SWAP1", + 0x91 => "SWAP2", + 0x92 => "SWAP3", + 0x93 => "SWAP4", + 0x94 => "SWAP5", + 0x95 => "SWAP6", + 0x96 => "SWAP7", + 0x97 => "SWAP8", + 0x98 => "SWAP9", + 0x99 => "SWAP10", + 0x9a => "SWAP11", + 0x9b => "SWAP12", + 0x9c => "SWAP13", + 0x9d => "SWAP14", + 0x9e => "SWAP15", + 0x9f => "SWAP16", + 0xa0 => "LOG0", + 0xa1 => "LOG1", + 0xa2 => "LOG2", + 0xa3 => "LOG3", + 0xa4 => "LOG4", + 0xa5 => "PANIC", + 0xf0 => "CREATE", + 0xf1 => "CALL", + 0xf2 => "CALLCODE", + 0xf3 => "RETURN", + 0xf4 => "DELEGATECALL", + 0xf5 => "CREATE2", + 0xf6 => "GET_CONTEXT", + 0xf7 => "SET_CONTEXT", + 0xf8 => "CONSUME_GAS", + 0xf9 => "EXIT_KERNEL", + 0xfa => "STATICCALL", + 0xfb => "MLOAD_GENERAL", + 0xfc => "MSTORE_GENERAL", + 0xfd => "REVERT", + 0xfe => "INVALID", + 0xff => "SELFDESTRUCT", + _ => panic!("Unrecognized opcode {opcode}"), + } +} + #[cfg(test)] mod tests { use std::collections::HashMap;