rusty_dex/dex/
opcodes.rs

1//! Opcodes module
2//!
3//! This modules defines the list of all possible opcodes in Dalvik, and a
4//! method to convert an `u8` value into an `OpCode` object.
5
6use log::warn;
7
8/// All existing Dalvik opcodes
9#[allow(non_camel_case_types)]
10#[derive(Copy, Clone, Debug, PartialEq)]
11pub enum OpCode {
12    NOP,
13    MOVE,
14    MOVE_FROM16,
15    MOVE_16,
16    MOVE_WIDE,
17    MOVE_WIDE_FROM16,
18    MOVE_WIDE_16,
19    MOVE_OBJECT,
20    MOVE_OBJECT_FROM16,
21    MOVE_OBJECT_16,
22    MOVE_RESULT,
23    MOVE_RESULT_WIDE,
24    MOVE_RESULT_OBJECT,
25    MOVE_EXCEPTION,
26    RETURN_VOID,
27    RETURN,
28    RETURN_WIDE,
29    RETURN_OBJECT,
30    CONST_4,
31    CONST_16,
32    CONST,
33    CONST_HIGH16,
34    CONST_WIDE_16,
35    CONST_WIDE_32,
36    CONST_WIDE,
37    CONST_WIDE_HIGH16,
38    CONST_STRING,
39    CONST_STRING_JUMBO,
40    CONST_CLASS,
41    MONITOR_ENTER,
42    MONITOR_EXIT,
43    CHECK_CAST,
44    INSTANCE_OF,
45    ARRAY_LENGTH,
46    NEW_INSTANCE,
47    NEW_ARRAY,
48    FILLED_NEW_ARRAY,
49    FILLED_NEW_ARRAY_RANGE,
50    FILL_ARRAY_DATA,
51    THROW,
52    GOTO,
53    GOTO_16,
54    GOTO_32,
55    PACKED_SWITCH,
56    SPARSE_SWITCH,
57    CMPL_FLOAT,
58    CMPG_FLOAT,
59    CMPL_DOUBLE,
60    CMPG_DOUBLE,
61    CMP_LONG,
62    IF_EQ,
63    IF_NE,
64    IF_LT,
65    IF_GE,
66    IF_GT,
67    IF_LE,
68    IF_EQZ,
69    IF_NEZ,
70    IF_LTZ,
71    IF_GEZ,
72    IF_GTZ,
73    IF_LEZ,
74    AGET,
75    AGET_WIDE,
76    AGET_OBJECT,
77    AGET_BOOLEAN,
78    AGET_BYTE,
79    AGET_CHAR,
80    AGET_SHORT,
81    APUT,
82    APUT_WIDE,
83    APUT_OBJECT,
84    APUT_BOOLEAN,
85    APUT_BYTE,
86    APUT_CHAR,
87    APUT_SHORT,
88    IGET,
89    IGET_WIDE,
90    IGET_OBJECT,
91    IGET_BOOLEAN,
92    IGET_BYTE,
93    IGET_CHAR,
94    IGET_SHORT,
95    IPUT,
96    IPUT_WIDE,
97    IPUT_OBJECT,
98    IPUT_BOOLEAN,
99    IPUT_BYTE,
100    IPUT_CHAR,
101    IPUT_SHORT,
102    SGET,
103    SGET_WIDE,
104    SGET_OBJECT,
105    SGET_BOOLEAN,
106    SGET_BYTE,
107    SGET_CHAR,
108    SGET_SHORT,
109    SPUT,
110    SPUT_WIDE,
111    SPUT_OBJECT,
112    SPUT_BOOLEAN,
113    SPUT_BYTE,
114    SPUT_CHAR,
115    SPUT_SHORT,
116    INVOKE_VIRTUAL,
117    INVOKE_SUPER,
118    INVOKE_DIRECT,
119    INVOKE_STATIC,
120    INVOKE_INTERFACE,
121    INVOKE_VIRTUAL_RANGE,
122    INVOKE_SUPER_RANGE,
123    INVOKE_DIRECT_RANGE,
124    INVOKE_STATIC_RANGE,
125    INVOKE_INTERFACE_RANGE,
126    NEG_INT,
127    NOT_INT,
128    NEG_LONG,
129    NOT_LONG,
130    NEG_FLOAT,
131    NEG_DOUBLE,
132    INT_TO_LONG,
133    INT_TO_FLOAT,
134    INT_TO_DOUBLE,
135    LONG_TO_INT,
136    LONG_TO_FLOAT,
137    LONG_TO_DOUBLE,
138    FLOAT_TO_INT,
139    FLOAT_TO_LONG,
140    FLOAT_TO_DOUBLE,
141    DOUBLE_TO_INT,
142    DOUBLE_TO_LONG,
143    DOUBLE_TO_FLOAT,
144    INT_TO_BYTE,
145    INT_TO_CHAR,
146    INT_TO_SHORT,
147    ADD_INT,
148    SUB_INT,
149    MUL_INT,
150    DIV_INT,
151    REM_INT,
152    AND_INT,
153    OR_INT,
154    XOR_INT,
155    SHL_INT,
156    SHR_INT,
157    USHR_INT,
158    ADD_LONG,
159    SUB_LONG,
160    MUL_LONG,
161    DIV_LONG,
162    REM_LONG,
163    AND_LONG,
164    OR_LONG,
165    XOR_LONG,
166    SHL_LONG,
167    SHR_LONG,
168    USHR_LONG,
169    ADD_FLOAT,
170    SUB_FLOAT,
171    MUL_FLOAT,
172    DIV_FLOAT,
173    REM_FLOAT,
174    ADD_DOUBLE,
175    SUB_DOUBLE,
176    MUL_DOUBLE,
177    DIV_DOUBLE,
178    REM_DOUBLE,
179    ADD_INT_2ADDR,
180    SUB_INT_2ADDR,
181    MUL_INT_2ADDR,
182    DIV_INT_2ADDR,
183    REM_INT_2ADDR,
184    AND_INT_2ADDR,
185    OR_INT_2ADDR,
186    XOR_INT_2ADDR,
187    SHL_INT_2ADDR,
188    SHR_INT_2ADDR,
189    USHR_INT_2ADDR,
190    ADD_LONG_2ADDR,
191    SUB_LONG_2ADDR,
192    MUL_LONG_2ADDR,
193    DIV_LONG_2ADDR,
194    REM_LONG_2ADDR,
195    AND_LONG_2ADDR,
196    OR_LONG_2ADDR,
197    XOR_LONG_2ADDR,
198    SHL_LONG_2ADDR,
199    SHR_LONG_2ADDR,
200    USHR_LONG_2ADDR,
201    ADD_FLOAT_2ADDR,
202    SUB_FLOAT_2ADDR,
203    MUL_FLOAT_2ADDR,
204    DIV_FLOAT_2ADDR,
205    REM_FLOAT_2ADDR,
206    ADD_DOUBLE_2ADDR,
207    SUB_DOUBLE_2ADDR,
208    MUL_DOUBLE_2ADDR,
209    DIV_DOUBLE_2ADDR,
210    REM_DOUBLE_2ADDR,
211    ADD_INT_LIT16,
212    RSUB_INT,
213    MUL_INT_LIT16,
214    DIV_INT_LIT16,
215    REM_INT_LIT16,
216    AND_INT_LIT16,
217    OR_INT_LIT16,
218    XOR_INT_LIT16,
219    ADD_INT_LIT8,
220    RSUB_INT_LIT8,
221    MUL_INT_LIT8,
222    DIV_INT_LIT8,
223    REM_INT_LIT8,
224    AND_INT_LIT8,
225    OR_INT_LIT8,
226    XOR_INT_LIT8,
227    SHL_INT_LIT8,
228    SHR_INT_LIT8,
229    USHR_INT_LIT8,
230    INVOKE_POLYMORPHIC,
231    INVOKE_POLYMORPHIC_RANGE,
232    INVOKE_CUSTOM,
233    INVOKE_CUSTOM_RANGE,
234    CONST_METHOD_HANDLE,
235    CONST_METHOD_TYPE,
236    PACKED_SWITCH_PAYLOAD,
237    SPARSE_SWITCH_PAYLOAD,
238    FILL_ARRAY_DATA_PAYLOAD,
239}
240
241
242impl OpCode {
243    /// Converts an `u8` into an `OpCode`
244    pub fn parse(value: u8) -> Option<Self> {
245        match value {
246            0x00 => Some(OpCode::NOP),                        // Instruction 10x
247            0x01 => Some(OpCode::MOVE),                       // Instruction 12x
248            0x02 => Some(OpCode::MOVE_FROM16),                // Instruction 22x
249            0x03 => Some(OpCode::MOVE_16),                    // Instruction 32x
250            0x04 => Some(OpCode::MOVE_WIDE),                  // Instruction 12x
251            0x05 => Some(OpCode::MOVE_WIDE_FROM16),           // Instruction 22x
252            0x06 => Some(OpCode::MOVE_WIDE_16),               // Instruction 32x
253            0x07 => Some(OpCode::MOVE_OBJECT),                // Instruction 12x
254            0x08 => Some(OpCode::MOVE_OBJECT_FROM16),         // Instruction 22x
255            0x09 => Some(OpCode::MOVE_OBJECT_16),             // Instruction 32x
256            0x0a => Some(OpCode::MOVE_RESULT),                // Instruction 11x
257            0x0b => Some(OpCode::MOVE_RESULT_WIDE),           // Instruction 11x
258            0x0c => Some(OpCode::MOVE_RESULT_OBJECT),         // Instruction 11x
259            0x0d => Some(OpCode::MOVE_EXCEPTION),             // Instruction 11x
260            0x0e => Some(OpCode::RETURN_VOID),                // Instruction 10x
261            0x0f => Some(OpCode::RETURN),                     // Instruction 11x
262            0x10 => Some(OpCode::RETURN_WIDE),                // Instruction 11x
263            0x11 => Some(OpCode::RETURN_OBJECT),              // Instruction 11x
264            0x12 => Some(OpCode::CONST_4),                    // Instruction 11n
265            0x13 => Some(OpCode::CONST_16),                   // Instruction 21s
266            0x14 => Some(OpCode::CONST),                      // Instruction 31i
267            0x15 => Some(OpCode::CONST_HIGH16),               // Instruction 21h
268            0x16 => Some(OpCode::CONST_WIDE_16),              // Instruction 21s
269            0x17 => Some(OpCode::CONST_WIDE_32),              // Instruction 31i
270            0x18 => Some(OpCode::CONST_WIDE),                 // Instruction 51l
271            0x19 => Some(OpCode::CONST_WIDE_HIGH16),          // Instruction 21h
272            0x1a => Some(OpCode::CONST_STRING),               // Instruction 21c
273            0x1b => Some(OpCode::CONST_STRING_JUMBO),         // Instruction 31c
274            0x1c => Some(OpCode::CONST_CLASS),                // Instruction 21c
275            0x1d => Some(OpCode::MONITOR_ENTER),              // Instruction 11x
276            0x1e => Some(OpCode::MONITOR_EXIT),               // Instruction 11x
277            0x1f => Some(OpCode::CHECK_CAST),                 // Instruction 21c
278            0x20 => Some(OpCode::INSTANCE_OF),                // Instruction 22c
279            0x21 => Some(OpCode::ARRAY_LENGTH),               // Instruction 12x
280            0x22 => Some(OpCode::NEW_INSTANCE),               // Instruction 21c
281            0x23 => Some(OpCode::NEW_ARRAY),                  // Instruction 22c
282            0x24 => Some(OpCode::FILLED_NEW_ARRAY),           // Instruction 35c
283            0x25 => Some(OpCode::FILLED_NEW_ARRAY_RANGE),     // Instruction 3rc
284            0x26 => Some(OpCode::FILL_ARRAY_DATA),            // Instruction 31t
285            0x27 => Some(OpCode::THROW),                      // Instruction 11x
286            0x28 => Some(OpCode::GOTO),                       // Instruction 10t
287            0x29 => Some(OpCode::GOTO_16),                    // Instruction 20t
288            0x2a => Some(OpCode::GOTO_32),                    // Instruction 30t
289            0x2b => Some(OpCode::PACKED_SWITCH),              // Instruction 31t
290            0x2c => Some(OpCode::SPARSE_SWITCH),              // Instruction 31t
291            0x2d => Some(OpCode::CMPL_FLOAT),                 // Instruction 23x
292            0x2e => Some(OpCode::CMPG_FLOAT),                 // Instruction 23x
293            0x2f => Some(OpCode::CMPL_DOUBLE),                // Instruction 23x
294            0x30 => Some(OpCode::CMPG_DOUBLE),                // Instruction 23x
295            0x31 => Some(OpCode::CMP_LONG),                   // Instruction 23x
296            0x32 => Some(OpCode::IF_EQ),                      // Instruction 22t
297            0x33 => Some(OpCode::IF_NE),                      // Instruction 22t
298            0x34 => Some(OpCode::IF_LT),                      // Instruction 22t
299            0x35 => Some(OpCode::IF_GE),                      // Instruction 22t
300            0x36 => Some(OpCode::IF_GT),                      // Instruction 22t
301            0x37 => Some(OpCode::IF_LE),                      // Instruction 22t
302            0x38 => Some(OpCode::IF_EQZ),                     // Instruction 21t
303            0x39 => Some(OpCode::IF_NEZ),                     // Instruction 21t
304            0x3a => Some(OpCode::IF_LTZ),                     // Instruction 21t
305            0x3b => Some(OpCode::IF_GEZ),                     // Instruction 21t
306            0x3c => Some(OpCode::IF_GTZ),                     // Instruction 21t
307            0x3d => Some(OpCode::IF_LEZ),                     // Instruction 21t
308
309            /* Unused */
310            0x3e..=0x43 => {
311                warn!("use of unused opcode {}", value);
312                None
313            },
314
315            0x44 => Some(OpCode::AGET),                       // Instruction 23x
316            0x45 => Some(OpCode::AGET_WIDE),                  // Instruction 23x
317            0x46 => Some(OpCode::AGET_OBJECT),                // Instruction 23x
318            0x47 => Some(OpCode::AGET_BOOLEAN),               // Instruction 23x
319            0x48 => Some(OpCode::AGET_BYTE),                  // Instruction 23x
320            0x49 => Some(OpCode::AGET_CHAR),                  // Instruction 23x
321            0x4a => Some(OpCode::AGET_SHORT),                 // Instruction 23x
322            0x4b => Some(OpCode::APUT),                       // Instruction 23x
323            0x4c => Some(OpCode::APUT_WIDE),                  // Instruction 23x
324            0x4d => Some(OpCode::APUT_OBJECT),                // Instruction 23x
325            0x4e => Some(OpCode::APUT_BOOLEAN),               // Instruction 23x
326            0x4f => Some(OpCode::APUT_BYTE),                  // Instruction 23x
327            0x50 => Some(OpCode::APUT_CHAR),                  // Instruction 23x
328            0x51 => Some(OpCode::APUT_SHORT),                 // Instruction 23x
329            0x52 => Some(OpCode::IGET),                       // Instruction 22c
330            0x53 => Some(OpCode::IGET_WIDE),                  // Instruction 22c
331            0x54 => Some(OpCode::IGET_OBJECT),                // Instruction 22c
332            0x55 => Some(OpCode::IGET_BOOLEAN),               // Instruction 22c
333            0x56 => Some(OpCode::IGET_BYTE),                  // Instruction 22c
334            0x57 => Some(OpCode::IGET_CHAR),                  // Instruction 22c
335            0x58 => Some(OpCode::IGET_SHORT),                 // Instruction 22c
336            0x59 => Some(OpCode::IPUT),                       // Instruction 22c
337            0x5a => Some(OpCode::IPUT_WIDE),                  // Instruction 22c
338            0x5b => Some(OpCode::IPUT_OBJECT),                // Instruction 22c
339            0x5c => Some(OpCode::IPUT_BOOLEAN),               // Instruction 22c
340            0x5d => Some(OpCode::IPUT_BYTE),                  // Instruction 22c
341            0x5e => Some(OpCode::IPUT_CHAR),                  // Instruction 22c
342            0x5f => Some(OpCode::IPUT_SHORT),                 // Instruction 22c
343            0x60 => Some(OpCode::SGET),                       // Instruction 21c
344            0x61 => Some(OpCode::SGET_WIDE),                  // Instruction 21c
345            0x62 => Some(OpCode::SGET_OBJECT),                // Instruction 21c
346            0x63 => Some(OpCode::SGET_BOOLEAN),               // Instruction 21c
347            0x64 => Some(OpCode::SGET_BYTE),                  // Instruction 21c
348            0x65 => Some(OpCode::SGET_CHAR),                  // Instruction 21c
349            0x66 => Some(OpCode::SGET_SHORT),                 // Instruction 21c
350            0x67 => Some(OpCode::SPUT),                       // Instruction 21c
351            0x68 => Some(OpCode::SPUT_WIDE),                  // Instruction 21c
352            0x69 => Some(OpCode::SPUT_OBJECT),                // Instruction 21c
353            0x6a => Some(OpCode::SPUT_BOOLEAN),               // Instruction 21c
354            0x6b => Some(OpCode::SPUT_BYTE),                  // Instruction 21c
355            0x6c => Some(OpCode::SPUT_CHAR),                  // Instruction 21c
356            0x6d => Some(OpCode::SPUT_SHORT),                 // Instruction 21c
357            0x6e => Some(OpCode::INVOKE_VIRTUAL),             // Instruction 35c
358            0x6f => Some(OpCode::INVOKE_SUPER),               // Instruction 35c
359            0x70 => Some(OpCode::INVOKE_DIRECT),              // Instruction 35c
360            0x71 => Some(OpCode::INVOKE_STATIC),              // Instruction 35c
361            0x72 => Some(OpCode::INVOKE_INTERFACE),           // Instruction 35c
362
363            /* Unused */
364            0x73 => {
365                warn!("use of unused opcode {}", value);
366                None
367            },
368
369            0x74 => Some(OpCode::INVOKE_VIRTUAL_RANGE),       // Instruction 3rc
370            0x75 => Some(OpCode::INVOKE_SUPER_RANGE),         // Instruction 3rc
371            0x76 => Some(OpCode::INVOKE_DIRECT_RANGE),        // Instruction 3rc
372            0x77 => Some(OpCode::INVOKE_STATIC_RANGE),        // Instruction 3rc
373            0x78 => Some(OpCode::INVOKE_INTERFACE_RANGE),     // Instruction 3rc
374
375            /* Unused */
376            0x79 | 0x7a => {
377                warn!("use of unused opcode {}", value);
378                None
379            },
380
381            0x7b => Some(OpCode::NEG_INT),                    // Instruction 12x
382            0x7c => Some(OpCode::NOT_INT),                    // Instruction 12x
383            0x7d => Some(OpCode::NEG_LONG),                   // Instruction 12x
384            0x7e => Some(OpCode::NOT_LONG),                   // Instruction 12x
385            0x7f => Some(OpCode::NEG_FLOAT),                  // Instruction 12x
386            0x80 => Some(OpCode::NEG_DOUBLE),                 // Instruction 12x
387            0x81 => Some(OpCode::INT_TO_LONG),                // Instruction 12x
388            0x82 => Some(OpCode::INT_TO_FLOAT),               // Instruction 12x
389            0x83 => Some(OpCode::INT_TO_DOUBLE),              // Instruction 12x
390            0x84 => Some(OpCode::LONG_TO_INT),                // Instruction 12x
391            0x85 => Some(OpCode::LONG_TO_FLOAT),              // Instruction 12x
392            0x86 => Some(OpCode::LONG_TO_DOUBLE),             // Instruction 12x
393            0x87 => Some(OpCode::FLOAT_TO_INT),               // Instruction 12x
394            0x88 => Some(OpCode::FLOAT_TO_LONG),              // Instruction 12x
395            0x89 => Some(OpCode::FLOAT_TO_DOUBLE),            // Instruction 12x
396            0x8a => Some(OpCode::DOUBLE_TO_INT),              // Instruction 12x
397            0x8b => Some(OpCode::DOUBLE_TO_LONG),             // Instruction 12x
398            0x8c => Some(OpCode::DOUBLE_TO_FLOAT),            // Instruction 12x
399            0x8d => Some(OpCode::INT_TO_BYTE),                // Instruction 12x
400            0x8e => Some(OpCode::INT_TO_CHAR),                // Instruction 12x
401            0x8f => Some(OpCode::INT_TO_SHORT),               // Instruction 12x
402            0x90 => Some(OpCode::ADD_INT),                    // Instruction 23x
403            0x91 => Some(OpCode::SUB_INT),                    // Instruction 23x
404            0x92 => Some(OpCode::MUL_INT),                    // Instruction 23x
405            0x93 => Some(OpCode::DIV_INT),                    // Instruction 23x
406            0x94 => Some(OpCode::REM_INT),                    // Instruction 23x
407            0x95 => Some(OpCode::AND_INT),                    // Instruction 23x
408            0x96 => Some(OpCode::OR_INT),                     // Instruction 23x
409            0x97 => Some(OpCode::XOR_INT),                    // Instruction 23x
410            0x98 => Some(OpCode::SHL_INT),                    // Instruction 23x
411            0x99 => Some(OpCode::SHR_INT),                    // Instruction 23x
412            0x9a => Some(OpCode::USHR_INT),                   // Instruction 23x
413            0x9b => Some(OpCode::ADD_LONG),                   // Instruction 23x
414            0x9c => Some(OpCode::SUB_LONG),                   // Instruction 23x
415            0x9d => Some(OpCode::MUL_LONG),                   // Instruction 23x
416            0x9e => Some(OpCode::DIV_LONG),                   // Instruction 23x
417            0x9f => Some(OpCode::REM_LONG),                   // Instruction 23x
418            0xa0 => Some(OpCode::AND_LONG),                   // Instruction 23x
419            0xa1 => Some(OpCode::OR_LONG),                    // Instruction 23x
420            0xa2 => Some(OpCode::XOR_LONG),                   // Instruction 23x
421            0xa3 => Some(OpCode::SHL_LONG),                   // Instruction 23x
422            0xa4 => Some(OpCode::SHR_LONG),                   // Instruction 23x
423            0xa5 => Some(OpCode::USHR_LONG),                  // Instruction 23x
424            0xa6 => Some(OpCode::ADD_FLOAT),                  // Instruction 23x
425            0xa7 => Some(OpCode::SUB_FLOAT),                  // Instruction 23x
426            0xa8 => Some(OpCode::MUL_FLOAT),                  // Instruction 23x
427            0xa9 => Some(OpCode::DIV_FLOAT),                  // Instruction 23x
428            0xaa => Some(OpCode::REM_FLOAT),                  // Instruction 23x
429            0xab => Some(OpCode::ADD_DOUBLE),                 // Instruction 23x
430            0xac => Some(OpCode::SUB_DOUBLE),                 // Instruction 23x
431            0xad => Some(OpCode::MUL_DOUBLE),                 // Instruction 23x
432            0xae => Some(OpCode::DIV_DOUBLE),                 // Instruction 23x
433            0xaf => Some(OpCode::REM_DOUBLE),                 // Instruction 23x
434            0xb0 => Some(OpCode::ADD_INT_2ADDR),              // Instruction 12x
435            0xb1 => Some(OpCode::SUB_INT_2ADDR),              // Instruction 12x
436            0xb2 => Some(OpCode::MUL_INT_2ADDR),              // Instruction 12x
437            0xb3 => Some(OpCode::DIV_INT_2ADDR),              // Instruction 12x
438            0xb4 => Some(OpCode::REM_INT_2ADDR),              // Instruction 12x
439            0xb5 => Some(OpCode::AND_INT_2ADDR),              // Instruction 12x
440            0xb6 => Some(OpCode::OR_INT_2ADDR),               // Instruction 12x
441            0xb7 => Some(OpCode::XOR_INT_2ADDR),              // Instruction 12x
442            0xb8 => Some(OpCode::SHL_INT_2ADDR),              // Instruction 12x
443            0xb9 => Some(OpCode::SHR_INT_2ADDR),              // Instruction 12x
444            0xba => Some(OpCode::USHR_INT_2ADDR),             // Instruction 12x
445            0xbb => Some(OpCode::ADD_LONG_2ADDR),             // Instruction 12x
446            0xbc => Some(OpCode::SUB_LONG_2ADDR),             // Instruction 12x
447            0xbd => Some(OpCode::MUL_LONG_2ADDR),             // Instruction 12x
448            0xbe => Some(OpCode::DIV_LONG_2ADDR),             // Instruction 12x
449            0xbf => Some(OpCode::REM_LONG_2ADDR),             // Instruction 12x
450            0xc0 => Some(OpCode::AND_LONG_2ADDR),             // Instruction 12x
451            0xc1 => Some(OpCode::OR_LONG_2ADDR),              // Instruction 12x
452            0xc2 => Some(OpCode::XOR_LONG_2ADDR),             // Instruction 12x
453            0xc3 => Some(OpCode::SHL_LONG_2ADDR),             // Instruction 12x
454            0xc4 => Some(OpCode::SHR_LONG_2ADDR),             // Instruction 12x
455            0xc5 => Some(OpCode::USHR_LONG_2ADDR),            // Instruction 12x
456            0xc6 => Some(OpCode::ADD_FLOAT_2ADDR),            // Instruction 12x
457            0xc7 => Some(OpCode::SUB_FLOAT_2ADDR),            // Instruction 12x
458            0xc8 => Some(OpCode::MUL_FLOAT_2ADDR),            // Instruction 12x
459            0xc9 => Some(OpCode::DIV_FLOAT_2ADDR),            // Instruction 12x
460            0xca => Some(OpCode::REM_FLOAT_2ADDR),            // Instruction 12x
461            0xcb => Some(OpCode::ADD_DOUBLE_2ADDR),           // Instruction 12x
462            0xcc => Some(OpCode::SUB_DOUBLE_2ADDR),           // Instruction 12x
463            0xcd => Some(OpCode::MUL_DOUBLE_2ADDR),           // Instruction 12x
464            0xce => Some(OpCode::DIV_DOUBLE_2ADDR),           // Instruction 12x
465            0xcf => Some(OpCode::REM_DOUBLE_2ADDR),           // Instruction 12x
466            0xd0 => Some(OpCode::ADD_INT_LIT16),              // Instruction 22s
467            0xd1 => Some(OpCode::RSUB_INT),                   // Instruction 22s
468            0xd2 => Some(OpCode::MUL_INT_LIT16),              // Instruction 22s
469            0xd3 => Some(OpCode::DIV_INT_LIT16),              // Instruction 22s
470            0xd4 => Some(OpCode::REM_INT_LIT16),              // Instruction 22s
471            0xd5 => Some(OpCode::AND_INT_LIT16),              // Instruction 22s
472            0xd6 => Some(OpCode::OR_INT_LIT16),               // Instruction 22s
473            0xd7 => Some(OpCode::XOR_INT_LIT16),              // Instruction 22s
474            0xd8 => Some(OpCode::ADD_INT_LIT8),               // Instruction 22b
475            0xd9 => Some(OpCode::RSUB_INT_LIT8),              // Instruction 22b
476            0xda => Some(OpCode::MUL_INT_LIT8),               // Instruction 22b
477            0xdb => Some(OpCode::DIV_INT_LIT8),               // Instruction 22b
478            0xdc => Some(OpCode::REM_INT_LIT8),               // Instruction 22b
479            0xdd => Some(OpCode::AND_INT_LIT8),               // Instruction 22b
480            0xde => Some(OpCode::OR_INT_LIT8),                // Instruction 22b
481            0xdf => Some(OpCode::XOR_INT_LIT8),               // Instruction 22b
482            0xe0 => Some(OpCode::SHL_INT_LIT8),               // Instruction 22b
483            0xe1 => Some(OpCode::SHR_INT_LIT8),               // Instruction 22b
484            0xe2 => Some(OpCode::USHR_INT_LIT8),              // Instruction 22b
485
486            /* Unused */
487            0xe3..=0xf9 => {
488                warn!("use of unused opcode {}", value);
489                None
490            },
491
492            0xfa => Some(OpCode::INVOKE_POLYMORPHIC),         // Instruction 45cc,
493            0xfb => Some(OpCode::INVOKE_POLYMORPHIC_RANGE),   // Instruction 4rcc,
494            0xfc => Some(OpCode::INVOKE_CUSTOM),              // Instruction 35c,
495            0xfd => Some(OpCode::INVOKE_CUSTOM_RANGE),        // Instruction 3rc,
496            0xfe => Some(OpCode::CONST_METHOD_HANDLE),        // Instruction 21c,
497            0xff => Some(OpCode::CONST_METHOD_TYPE),          // Instruction 21c,
498        }
499    }
500}