Skip to main content

neo_devpack_solidity/runtime/spec/
opcodes.rs

1use super::*;
2
3macro_rules! op {
4    ($code:expr, $name:expr, $gas:expr) => {
5        OpcodeSpec {
6            code: $code,
7            name: $name,
8            gas: $gas,
9        }
10    };
11}
12
13// Canonical Neo N3 opcode table (from provided OpCode enum).
14pub static OPCODES: Lazy<HashMap<u8, OpcodeSpec>> = Lazy::new(|| {
15    let mut m = HashMap::new();
16
17    let entries = [
18        // Constants
19        op!(0x00, "PUSHINT8", 1),
20        op!(0x01, "PUSHINT16", 1),
21        op!(0x02, "PUSHINT32", 1),
22        op!(0x03, "PUSHINT64", 1),
23        op!(0x04, "PUSHINT128", 1),
24        op!(0x05, "PUSHINT256", 1),
25        op!(0x08, "PUSHT", 1),
26        op!(0x09, "PUSHF", 1),
27        op!(0x0A, "PUSHA", 1),
28        op!(0x0B, "PUSHNULL", 1),
29        op!(0x0C, "PUSHDATA1", 2),
30        op!(0x0D, "PUSHDATA2", 2),
31        op!(0x0E, "PUSHDATA4", 2),
32        op!(0x0F, "PUSHM1", 1),
33        op!(0x10, "PUSH0", 1),
34        op!(0x11, "PUSH1", 1),
35        op!(0x12, "PUSH2", 1),
36        op!(0x13, "PUSH3", 1),
37        op!(0x14, "PUSH4", 1),
38        op!(0x15, "PUSH5", 1),
39        op!(0x16, "PUSH6", 1),
40        op!(0x17, "PUSH7", 1),
41        op!(0x18, "PUSH8", 1),
42        op!(0x19, "PUSH9", 1),
43        op!(0x1A, "PUSH10", 1),
44        op!(0x1B, "PUSH11", 1),
45        op!(0x1C, "PUSH12", 1),
46        op!(0x1D, "PUSH13", 1),
47        op!(0x1E, "PUSH14", 1),
48        op!(0x1F, "PUSH15", 1),
49        op!(0x20, "PUSH16", 1),
50        // Flow control
51        op!(0x21, "NOP", 1),
52        op!(0x22, "JMP", 2),
53        op!(0x23, "JMP_L", 2),
54        op!(0x24, "JMPIF", 2),
55        op!(0x25, "JMPIF_L", 2),
56        op!(0x26, "JMPIFNOT", 2),
57        op!(0x27, "JMPIFNOT_L", 2),
58        op!(0x28, "JMPEQ", 2),
59        op!(0x29, "JMPEQ_L", 2),
60        op!(0x2A, "JMPNE", 2),
61        op!(0x2B, "JMPNE_L", 2),
62        op!(0x2C, "JMPGT", 2),
63        op!(0x2D, "JMPGT_L", 2),
64        op!(0x2E, "JMPGE", 2),
65        op!(0x2F, "JMPGE_L", 2),
66        op!(0x30, "JMPLT", 2),
67        op!(0x31, "JMPLT_L", 2),
68        op!(0x32, "JMPLE", 2),
69        op!(0x33, "JMPLE_L", 2),
70        op!(0x34, "CALL", 512),
71        op!(0x35, "CALL_L", 512),
72        op!(0x36, "CALLA", 512),
73        op!(0x37, "CALLT", 512),
74        op!(0x38, "ABORT", 1),
75        op!(0x39, "ASSERT", 1),
76        op!(0x3A, "THROW", 1),
77        op!(0x3B, "TRY", 1),
78        op!(0x3C, "TRY_L", 1),
79        op!(0x3D, "ENDTRY", 1),
80        op!(0x3E, "ENDTRY_L", 1),
81        op!(0x3F, "ENDFINALLY", 1),
82        op!(0x40, "RET", 0),
83        op!(0x41, "SYSCALL", 10),
84        // Stack ops
85        op!(0x43, "DEPTH", 2),
86        op!(0x45, "DROP", 2),
87        op!(0x46, "NIP", 2),
88        op!(0x48, "XDROP", 2),
89        op!(0x49, "CLEAR", 2),
90        op!(0x4A, "DUP", 2),
91        op!(0x4B, "OVER", 2),
92        op!(0x4D, "PICK", 2),
93        op!(0x4E, "TUCK", 2),
94        op!(0x50, "SWAP", 2),
95        op!(0x51, "ROT", 2),
96        op!(0x52, "ROLL", 2),
97        op!(0x53, "REVERSE3", 2),
98        op!(0x54, "REVERSE4", 2),
99        op!(0x55, "REVERSEN", 2),
100        // Slot ops
101        op!(0x56, "INITSSLOT", 2),
102        op!(0x57, "INITSLOT", 3),
103        op!(0x58, "LDSFLD0", 2),
104        op!(0x59, "LDSFLD1", 2),
105        op!(0x5A, "LDSFLD2", 2),
106        op!(0x5B, "LDSFLD3", 2),
107        op!(0x5C, "LDSFLD4", 2),
108        op!(0x5D, "LDSFLD5", 2),
109        op!(0x5E, "LDSFLD6", 2),
110        op!(0x5F, "LDSFLD", 2),
111        op!(0x60, "STSFLD0", 2),
112        op!(0x61, "STSFLD1", 2),
113        op!(0x62, "STSFLD2", 2),
114        op!(0x63, "STSFLD3", 2),
115        op!(0x64, "STSFLD4", 2),
116        op!(0x65, "STSFLD5", 2),
117        op!(0x66, "STSFLD6", 2),
118        op!(0x67, "STSFLD", 2),
119        op!(0x68, "LDLOC0", 2),
120        op!(0x69, "LDLOC1", 2),
121        op!(0x6A, "LDLOC2", 2),
122        op!(0x6B, "LDLOC3", 2),
123        op!(0x6C, "LDLOC4", 2),
124        op!(0x6D, "LDLOC5", 2),
125        op!(0x6E, "LDLOC6", 2),
126        op!(0x6F, "LDLOC", 2),
127        op!(0x70, "STLOC0", 2),
128        op!(0x71, "STLOC1", 2),
129        op!(0x72, "STLOC2", 2),
130        op!(0x73, "STLOC3", 2),
131        op!(0x74, "STLOC4", 2),
132        op!(0x75, "STLOC5", 2),
133        op!(0x76, "STLOC6", 2),
134        op!(0x77, "STLOC", 2),
135        op!(0x78, "LDARG0", 2),
136        op!(0x79, "LDARG1", 2),
137        op!(0x7A, "LDARG2", 2),
138        op!(0x7B, "LDARG3", 2),
139        op!(0x7C, "LDARG4", 2),
140        op!(0x7D, "LDARG5", 2),
141        op!(0x7E, "LDARG6", 2),
142        op!(0x7F, "LDARG", 2),
143        op!(0x80, "STARG0", 2),
144        op!(0x81, "STARG1", 2),
145        op!(0x82, "STARG2", 2),
146        op!(0x83, "STARG3", 2),
147        op!(0x84, "STARG4", 2),
148        op!(0x85, "STARG5", 2),
149        op!(0x86, "STARG6", 2),
150        op!(0x87, "STARG", 2),
151        // Splice / buffer
152        op!(0x88, "NEWBUFFER", 4),
153        op!(0x89, "MEMCPY", 4),
154        op!(0x8B, "CAT", 4),
155        op!(0x8C, "SUBSTR", 4),
156        op!(0x8D, "LEFT", 4),
157        op!(0x8E, "RIGHT", 4),
158        // Bitwise / logic
159        op!(0x90, "INVERT", 3),
160        op!(0x91, "AND", 3),
161        op!(0x92, "OR", 3),
162        op!(0x93, "XOR", 3),
163        op!(0x97, "EQUAL", 3),
164        op!(0x98, "NOTEQUAL", 3),
165        // Numeric
166        op!(0x99, "SIGN", 3),
167        op!(0x9A, "ABS", 3),
168        op!(0x9B, "NEGATE", 3),
169        op!(0x9C, "INC", 3),
170        op!(0x9D, "DEC", 3),
171        op!(0x9E, "ADD", 3),
172        op!(0x9F, "SUB", 3),
173        op!(0xA0, "MUL", 5),
174        op!(0xA1, "DIV", 5),
175        op!(0xA2, "MOD", 5),
176        op!(0xA3, "POW", 8),
177        op!(0xA4, "SQRT", 6),
178        op!(0xA5, "MODMUL", 8),
179        op!(0xA6, "MODPOW", 8),
180        op!(0xA8, "SHL", 3),
181        op!(0xA9, "SHR", 3),
182        op!(0xAA, "NOT", 2),
183        op!(0xAB, "BOOLAND", 2),
184        op!(0xAC, "BOOLOR", 2),
185        op!(0xB1, "NZ", 2),
186        op!(0xB3, "NUMEQUAL", 3),
187        op!(0xB4, "NUMNOTEQUAL", 3),
188        op!(0xB5, "LT", 3),
189        op!(0xB6, "LE", 3),
190        op!(0xB7, "GT", 3),
191        op!(0xB8, "GE", 3),
192        op!(0xB9, "MIN", 3),
193        op!(0xBA, "MAX", 3),
194        op!(0xBB, "WITHIN", 3),
195        // Compound / collections
196        op!(0xBE, "PACKMAP", 4),
197        op!(0xBF, "PACKSTRUCT", 4),
198        op!(0xC0, "PACK", 4),
199        op!(0xC1, "UNPACK", 4),
200        op!(0xC2, "NEWARRAY0", 4),
201        op!(0xC3, "NEWARRAY", 4),
202        op!(0xC4, "NEWARRAY_T", 4),
203        op!(0xC5, "NEWSTRUCT0", 4),
204        op!(0xC6, "NEWSTRUCT", 4),
205        op!(0xC8, "NEWMAP", 4),
206        op!(0xCA, "SIZE", 4),
207        op!(0xCB, "HASKEY", 4),
208        op!(0xCC, "KEYS", 4),
209        op!(0xCD, "VALUES", 4),
210        op!(0xCE, "PICKITEM", 4),
211        op!(0xCF, "APPEND", 4),
212        op!(0xD0, "SETITEM", 4),
213        op!(0xD1, "REVERSEITEMS", 4),
214        op!(0xD2, "REMOVE", 4),
215        op!(0xD3, "CLEARITEMS", 4),
216        op!(0xD4, "POPITEM", 4),
217        // Types
218        op!(0xD8, "ISNULL", 2),
219        op!(0xD9, "ISTYPE", 2),
220        op!(0xDB, "CONVERT", 2),
221        // Extensions
222        op!(0xE0, "ABORTMSG", 1),
223        op!(0xE1, "ASSERTMSG", 1),
224    ];
225
226    for entry in entries {
227        m.insert(entry.code, entry);
228    }
229    m
230});
231
232pub fn opcode_name(code: u8) -> Option<&'static str> {
233    OPCODES.get(&code).map(|op| op.name)
234}
235
236pub fn opcode_gas(code: u8) -> Option<u64> {
237    OPCODES.get(&code).map(|op| op.gas)
238}