1 /*
2  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.tools.classfile;
27 
28 import static com.sun.tools.classfile.Instruction.Kind.*;
29 import static com.sun.tools.classfile.Opcode.Set.*;
30 
31 /**
32  * See JVMS, chapter 6.
33  *
34  * <p>In addition to providing all the standard opcodes defined in JVMS,
35  * this class also provides legacy support for the PicoJava extensions.
36  *
37  *  <p><b>This is NOT part of any supported API.
38  *  If you write code that depends on this, you do so at your own risk.
39  *  This code and its internal interfaces are subject to change or
40  *  deletion without notice.</b>
41  */
42 public enum Opcode {
43     NOP(0x0),
44     ACONST_NULL(0x1),
45     ICONST_M1(0x2),
46     ICONST_0(0x3),
47     ICONST_1(0x4),
48     ICONST_2(0x5),
49     ICONST_3(0x6),
50     ICONST_4(0x7),
51     ICONST_5(0x8),
52     LCONST_0(0x9),
53     LCONST_1(0xa),
54     FCONST_0(0xb),
55     FCONST_1(0xc),
56     FCONST_2(0xd),
57     DCONST_0(0xe),
58     DCONST_1(0xf),
59     BIPUSH(0x10, BYTE),
60     SIPUSH(0x11, SHORT),
61     LDC(0x12, CPREF),
62     LDC_W(0x13, CPREF_W),
63     LDC2_W(0x14, CPREF_W),
64     ILOAD(0x15, LOCAL),
65     LLOAD(0x16, LOCAL),
66     FLOAD(0x17, LOCAL),
67     DLOAD(0x18, LOCAL),
68     ALOAD(0x19, LOCAL),
69     ILOAD_0(0x1a),
70     ILOAD_1(0x1b),
71     ILOAD_2(0x1c),
72     ILOAD_3(0x1d),
73     LLOAD_0(0x1e),
74     LLOAD_1(0x1f),
75     LLOAD_2(0x20),
76     LLOAD_3(0x21),
77     FLOAD_0(0x22),
78     FLOAD_1(0x23),
79     FLOAD_2(0x24),
80     FLOAD_3(0x25),
81     DLOAD_0(0x26),
82     DLOAD_1(0x27),
83     DLOAD_2(0x28),
84     DLOAD_3(0x29),
85     ALOAD_0(0x2a),
86     ALOAD_1(0x2b),
87     ALOAD_2(0x2c),
88     ALOAD_3(0x2d),
89     IALOAD(0x2e),
90     LALOAD(0x2f),
91     FALOAD(0x30),
92     DALOAD(0x31),
93     AALOAD(0x32),
94     BALOAD(0x33),
95     CALOAD(0x34),
96     SALOAD(0x35),
97     ISTORE(0x36, LOCAL),
98     LSTORE(0x37, LOCAL),
99     FSTORE(0x38, LOCAL),
100     DSTORE(0x39, LOCAL),
101     ASTORE(0x3a, LOCAL),
102     ISTORE_0(0x3b),
103     ISTORE_1(0x3c),
104     ISTORE_2(0x3d),
105     ISTORE_3(0x3e),
106     LSTORE_0(0x3f),
107     LSTORE_1(0x40),
108     LSTORE_2(0x41),
109     LSTORE_3(0x42),
110     FSTORE_0(0x43),
111     FSTORE_1(0x44),
112     FSTORE_2(0x45),
113     FSTORE_3(0x46),
114     DSTORE_0(0x47),
115     DSTORE_1(0x48),
116     DSTORE_2(0x49),
117     DSTORE_3(0x4a),
118     ASTORE_0(0x4b),
119     ASTORE_1(0x4c),
120     ASTORE_2(0x4d),
121     ASTORE_3(0x4e),
122     IASTORE(0x4f),
123     LASTORE(0x50),
124     FASTORE(0x51),
125     DASTORE(0x52),
126     AASTORE(0x53),
127     BASTORE(0x54),
128     CASTORE(0x55),
129     SASTORE(0x56),
130     POP(0x57),
131     POP2(0x58),
132     DUP(0x59),
133     DUP_X1(0x5a),
134     DUP_X2(0x5b),
135     DUP2(0x5c),
136     DUP2_X1(0x5d),
137     DUP2_X2(0x5e),
138     SWAP(0x5f),
139     IADD(0x60),
140     LADD(0x61),
141     FADD(0x62),
142     DADD(0x63),
143     ISUB(0x64),
144     LSUB(0x65),
145     FSUB(0x66),
146     DSUB(0x67),
147     IMUL(0x68),
148     LMUL(0x69),
149     FMUL(0x6a),
150     DMUL(0x6b),
151     IDIV(0x6c),
152     LDIV(0x6d),
153     FDIV(0x6e),
154     DDIV(0x6f),
155     IREM(0x70),
156     LREM(0x71),
157     FREM(0x72),
158     DREM(0x73),
159     INEG(0x74),
160     LNEG(0x75),
161     FNEG(0x76),
162     DNEG(0x77),
163     ISHL(0x78),
164     LSHL(0x79),
165     ISHR(0x7a),
166     LSHR(0x7b),
167     IUSHR(0x7c),
168     LUSHR(0x7d),
169     IAND(0x7e),
170     LAND(0x7f),
171     IOR(0x80),
172     LOR(0x81),
173     IXOR(0x82),
174     LXOR(0x83),
175     IINC(0x84, LOCAL_BYTE),
176     I2L(0x85),
177     I2F(0x86),
178     I2D(0x87),
179     L2I(0x88),
180     L2F(0x89),
181     L2D(0x8a),
182     F2I(0x8b),
183     F2L(0x8c),
184     F2D(0x8d),
185     D2I(0x8e),
186     D2L(0x8f),
187     D2F(0x90),
188     I2B(0x91),
189     I2C(0x92),
190     I2S(0x93),
191     LCMP(0x94),
192     FCMPL(0x95),
193     FCMPG(0x96),
194     DCMPL(0x97),
195     DCMPG(0x98),
196     IFEQ(0x99, BRANCH),
197     IFNE(0x9a, BRANCH),
198     IFLT(0x9b, BRANCH),
199     IFGE(0x9c, BRANCH),
200     IFGT(0x9d, BRANCH),
201     IFLE(0x9e, BRANCH),
202     IF_ICMPEQ(0x9f, BRANCH),
203     IF_ICMPNE(0xa0, BRANCH),
204     IF_ICMPLT(0xa1, BRANCH),
205     IF_ICMPGE(0xa2, BRANCH),
206     IF_ICMPGT(0xa3, BRANCH),
207     IF_ICMPLE(0xa4, BRANCH),
208     IF_ACMPEQ(0xa5, BRANCH),
209     IF_ACMPNE(0xa6, BRANCH),
210     GOTO(0xa7, BRANCH),
211     JSR(0xa8, BRANCH),
212     RET(0xa9, LOCAL),
213     TABLESWITCH(0xaa, DYNAMIC),
214     LOOKUPSWITCH(0xab, DYNAMIC),
215     IRETURN(0xac),
216     LRETURN(0xad),
217     FRETURN(0xae),
218     DRETURN(0xaf),
219     ARETURN(0xb0),
220     RETURN(0xb1),
221     GETSTATIC(0xb2, CPREF_W),
222     PUTSTATIC(0xb3, CPREF_W),
223     GETFIELD(0xb4, CPREF_W),
224     PUTFIELD(0xb5, CPREF_W),
225     INVOKEVIRTUAL(0xb6, CPREF_W),
226     INVOKESPECIAL(0xb7, CPREF_W),
227     INVOKESTATIC(0xb8, CPREF_W),
228     INVOKEINTERFACE(0xb9, CPREF_W_UBYTE_ZERO),
229     INVOKEDYNAMIC(0xba, CPREF_W_UBYTE_ZERO),
230     NEW(0xbb, CPREF_W),
231     NEWARRAY(0xbc, ATYPE),
232     ANEWARRAY(0xbd, CPREF_W),
233     ARRAYLENGTH(0xbe),
234     ATHROW(0xbf),
235     CHECKCAST(0xc0, CPREF_W),
236     INSTANCEOF(0xc1, CPREF_W),
237     MONITORENTER(0xc2),
238     MONITOREXIT(0xc3),
239     // wide 0xc4
240     MULTIANEWARRAY(0xc5, CPREF_W_UBYTE),
241     IFNULL(0xc6, BRANCH),
242     IFNONNULL(0xc7, BRANCH),
243     GOTO_W(0xc8, BRANCH_W),
244     JSR_W(0xc9, BRANCH_W),
245     // impdep 0xfe: PicoJava nonpriv
246     // impdep 0xff: Picojava priv
247 
248     // wide opcodes
249     ILOAD_W(0xc415, WIDE_LOCAL),
250     LLOAD_W(0xc416, WIDE_LOCAL),
251     FLOAD_W(0xc417, WIDE_LOCAL),
252     DLOAD_W(0xc418, WIDE_LOCAL),
253     ALOAD_W(0xc419, WIDE_LOCAL),
254     ISTORE_W(0xc436, WIDE_LOCAL),
255     LSTORE_W(0xc437, WIDE_LOCAL),
256     FSTORE_W(0xc438, WIDE_LOCAL),
257     DSTORE_W(0xc439, WIDE_LOCAL),
258     ASTORE_W(0xc43a, WIDE_LOCAL),
259     IINC_W(0xc484, WIDE_LOCAL_SHORT),
260     RET_W(0xc4a9, WIDE_LOCAL),
261 
262     // PicoJava nonpriv instructions
263     LOAD_UBYTE(PICOJAVA, 0xfe00),
264     LOAD_BYTE(PICOJAVA, 0xfe01),
265     LOAD_CHAR(PICOJAVA, 0xfe02),
266     LOAD_SHORT(PICOJAVA, 0xfe03),
267     LOAD_WORD(PICOJAVA, 0xfe04),
268     RET_FROM_SUB(PICOJAVA, 0xfe05),
269     LOAD_CHAR_OE(PICOJAVA, 0xfe0a),
270     LOAD_SHORT_OE(PICOJAVA, 0xfe0b),
271     LOAD_WORD_OE(PICOJAVA, 0xfe0c),
272     NCLOAD_UBYTE(PICOJAVA, 0xfe10),
273     NCLOAD_BYTE(PICOJAVA, 0xfe11),
274     NCLOAD_CHAR(PICOJAVA, 0xfe12),
275     NCLOAD_SHORT(PICOJAVA, 0xfe13),
276     NCLOAD_WORD(PICOJAVA, 0xfe14),
277     NCLOAD_CHAR_OE(PICOJAVA, 0xfe1a),
278     NCLOAD_SHORT_OE(PICOJAVA, 0xfe1b),
279     NCLOAD_WORD_OE(PICOJAVA, 0xfe1c),
280     CACHE_FLUSH(PICOJAVA, 0xfe1e),
281     STORE_BYTE(PICOJAVA, 0xfe20),
282     STORE_SHORT(PICOJAVA, 0xfe22),
283     STORE_WORD(PICOJAVA, 0xfe24),
284     STORE_SHORT_OE(PICOJAVA, 0xfe2a),
285     STORE_WORD_OE(PICOJAVA, 0xfe2c),
286     NCSTORE_BYTE(PICOJAVA, 0xfe30),
287     NCSTORE_SHORT(PICOJAVA, 0xfe32),
288     NCSTORE_WORD(PICOJAVA, 0xfe34),
289     NCSTORE_SHORT_OE(PICOJAVA, 0xfe3a),
290     NCSTORE_WORD_OE(PICOJAVA, 0xfe3c),
291     ZERO_LINE(PICOJAVA, 0xfe3e),
292     ENTER_SYNC_METHOD(PICOJAVA, 0xfe3f),
293 
294     // PicoJava priv instructions
295     PRIV_LOAD_UBYTE(PICOJAVA, 0xff00),
296     PRIV_LOAD_BYTE(PICOJAVA, 0xff01),
297     PRIV_LOAD_CHAR(PICOJAVA, 0xff02),
298     PRIV_LOAD_SHORT(PICOJAVA, 0xff03),
299     PRIV_LOAD_WORD(PICOJAVA, 0xff04),
300     PRIV_RET_FROM_TRAP(PICOJAVA, 0xff05),
301     PRIV_READ_DCACHE_TAG(PICOJAVA, 0xff06),
302     PRIV_READ_DCACHE_DATA(PICOJAVA, 0xff07),
303     PRIV_LOAD_CHAR_OE(PICOJAVA, 0xff0a),
304     PRIV_LOAD_SHORT_OE(PICOJAVA, 0xff0b),
305     PRIV_LOAD_WORD_OE(PICOJAVA, 0xff0c),
306     PRIV_READ_ICACHE_TAG(PICOJAVA, 0xff0e),
307     PRIV_READ_ICACHE_DATA(PICOJAVA, 0xff0f),
308     PRIV_NCLOAD_UBYTE(PICOJAVA, 0xff10),
309     PRIV_NCLOAD_BYTE(PICOJAVA, 0xff11),
310     PRIV_NCLOAD_CHAR(PICOJAVA, 0xff12),
311     PRIV_NCLOAD_SHORT(PICOJAVA, 0xff13),
312     PRIV_NCLOAD_WORD(PICOJAVA, 0xff14),
313     PRIV_POWERDOWN(PICOJAVA, 0xff16),
314     PRIV_READ_SCACHE_DATA(PICOJAVA, 0xff17),
315     PRIV_NCLOAD_CHAR_OE(PICOJAVA, 0xff1a),
316     PRIV_NCLOAD_SHORT_OE(PICOJAVA, 0xff1b),
317     PRIV_NCLOAD_WORD_OE(PICOJAVA, 0xff1c),
318     PRIV_CACHE_FLUSH(PICOJAVA, 0xff1e),
319     PRIV_CACHE_INDEX_FLUSH(PICOJAVA, 0xff1f),
320     PRIV_STORE_BYTE(PICOJAVA, 0xff20),
321     PRIV_STORE_SHORT(PICOJAVA, 0xff22),
322     PRIV_STORE_WORD(PICOJAVA, 0xff24),
323     PRIV_WRITE_DCACHE_TAG(PICOJAVA, 0xff26),
324     PRIV_WRITE_DCACHE_DATA(PICOJAVA, 0xff27),
325     PRIV_STORE_SHORT_OE(PICOJAVA, 0xff2a),
326     PRIV_STORE_WORD_OE(PICOJAVA, 0xff2c),
327     PRIV_WRITE_ICACHE_TAG(PICOJAVA, 0xff2e),
328     PRIV_WRITE_ICACHE_DATA(PICOJAVA, 0xff2f),
329     PRIV_NCSTORE_BYTE(PICOJAVA, 0xff30),
330     PRIV_NCSTORE_SHORT(PICOJAVA, 0xff32),
331     PRIV_NCSTORE_WORD(PICOJAVA, 0xff34),
332     PRIV_RESET(PICOJAVA, 0xff36),
333     PRIV_WRITE_SCACHE_DATA(PICOJAVA, 0xff37),
334     PRIV_NCSTORE_SHORT_OE(PICOJAVA, 0xff3a),
335     PRIV_NCSTORE_WORD_OE(PICOJAVA, 0xff3c),
336     PRIV_ZERO_LINE(PICOJAVA, 0xff3e),
337     PRIV_READ_REG_0(PICOJAVA, 0xff40),
338     PRIV_READ_REG_1(PICOJAVA, 0xff41),
339     PRIV_READ_REG_2(PICOJAVA, 0xff42),
340     PRIV_READ_REG_3(PICOJAVA, 0xff43),
341     PRIV_READ_REG_4(PICOJAVA, 0xff44),
342     PRIV_READ_REG_5(PICOJAVA, 0xff45),
343     PRIV_READ_REG_6(PICOJAVA, 0xff46),
344     PRIV_READ_REG_7(PICOJAVA, 0xff47),
345     PRIV_READ_REG_8(PICOJAVA, 0xff48),
346     PRIV_READ_REG_9(PICOJAVA, 0xff49),
347     PRIV_READ_REG_10(PICOJAVA, 0xff4a),
348     PRIV_READ_REG_11(PICOJAVA, 0xff4b),
349     PRIV_READ_REG_12(PICOJAVA, 0xff4c),
350     PRIV_READ_REG_13(PICOJAVA, 0xff4d),
351     PRIV_READ_REG_14(PICOJAVA, 0xff4e),
352     PRIV_READ_REG_15(PICOJAVA, 0xff4f),
353     PRIV_READ_REG_16(PICOJAVA, 0xff50),
354     PRIV_READ_REG_17(PICOJAVA, 0xff51),
355     PRIV_READ_REG_18(PICOJAVA, 0xff52),
356     PRIV_READ_REG_19(PICOJAVA, 0xff53),
357     PRIV_READ_REG_20(PICOJAVA, 0xff54),
358     PRIV_READ_REG_21(PICOJAVA, 0xff55),
359     PRIV_READ_REG_22(PICOJAVA, 0xff56),
360     PRIV_READ_REG_23(PICOJAVA, 0xff57),
361     PRIV_READ_REG_24(PICOJAVA, 0xff58),
362     PRIV_READ_REG_25(PICOJAVA, 0xff59),
363     PRIV_READ_REG_26(PICOJAVA, 0xff5a),
364     PRIV_READ_REG_27(PICOJAVA, 0xff5b),
365     PRIV_READ_REG_28(PICOJAVA, 0xff5c),
366     PRIV_READ_REG_29(PICOJAVA, 0xff5d),
367     PRIV_READ_REG_30(PICOJAVA, 0xff5e),
368     PRIV_READ_REG_31(PICOJAVA, 0xff5f),
369     PRIV_WRITE_REG_0(PICOJAVA, 0xff60),
370     PRIV_WRITE_REG_1(PICOJAVA, 0xff61),
371     PRIV_WRITE_REG_2(PICOJAVA, 0xff62),
372     PRIV_WRITE_REG_3(PICOJAVA, 0xff63),
373     PRIV_WRITE_REG_4(PICOJAVA, 0xff64),
374     PRIV_WRITE_REG_5(PICOJAVA, 0xff65),
375     PRIV_WRITE_REG_6(PICOJAVA, 0xff66),
376     PRIV_WRITE_REG_7(PICOJAVA, 0xff67),
377     PRIV_WRITE_REG_8(PICOJAVA, 0xff68),
378     PRIV_WRITE_REG_9(PICOJAVA, 0xff69),
379     PRIV_WRITE_REG_10(PICOJAVA, 0xff6a),
380     PRIV_WRITE_REG_11(PICOJAVA, 0xff6b),
381     PRIV_WRITE_REG_12(PICOJAVA, 0xff6c),
382     PRIV_WRITE_REG_13(PICOJAVA, 0xff6d),
383     PRIV_WRITE_REG_14(PICOJAVA, 0xff6e),
384     PRIV_WRITE_REG_15(PICOJAVA, 0xff6f),
385     PRIV_WRITE_REG_16(PICOJAVA, 0xff70),
386     PRIV_WRITE_REG_17(PICOJAVA, 0xff71),
387     PRIV_WRITE_REG_18(PICOJAVA, 0xff72),
388     PRIV_WRITE_REG_19(PICOJAVA, 0xff73),
389     PRIV_WRITE_REG_20(PICOJAVA, 0xff74),
390     PRIV_WRITE_REG_21(PICOJAVA, 0xff75),
391     PRIV_WRITE_REG_22(PICOJAVA, 0xff76),
392     PRIV_WRITE_REG_23(PICOJAVA, 0xff77),
393     PRIV_WRITE_REG_24(PICOJAVA, 0xff78),
394     PRIV_WRITE_REG_25(PICOJAVA, 0xff79),
395     PRIV_WRITE_REG_26(PICOJAVA, 0xff7a),
396     PRIV_WRITE_REG_27(PICOJAVA, 0xff7b),
397     PRIV_WRITE_REG_28(PICOJAVA, 0xff7c),
398     PRIV_WRITE_REG_29(PICOJAVA, 0xff7d),
399     PRIV_WRITE_REG_30(PICOJAVA, 0xff7e),
400     PRIV_WRITE_REG_31(PICOJAVA, 0xff7f);
401 
Opcode(int opcode)402     Opcode(int opcode) {
403         this(STANDARD, opcode, NO_OPERANDS);
404     }
405 
Opcode(int opcode, Instruction.Kind kind)406     Opcode(int opcode, Instruction.Kind kind) {
407         this(STANDARD, opcode, kind);
408     }
409 
Opcode(Set set, int opcode)410     Opcode(Set set, int opcode) {
411         this(set, opcode, (set == STANDARD ? NO_OPERANDS : WIDE_NO_OPERANDS));
412     }
413 
Opcode(Set set, int opcode, Instruction.Kind kind)414     Opcode(Set set, int opcode, Instruction.Kind kind) {
415         this.set = set;
416         this.opcode = opcode;
417         this.kind = kind;
418     }
419 
420     public final Set set;
421     public final int opcode;
422     public final Instruction.Kind kind;
423 
424     /** Get the Opcode for a simple standard 1-byte opcode. */
get(int opcode)425     public static Opcode get(int opcode) {
426         return stdOpcodes[opcode];
427     }
428 
429     /** Get the Opcode for 1- or 2-byte opcode. */
get(int opcodePrefix, int opcode)430     public static Opcode get(int opcodePrefix, int opcode) {
431         Opcode[] block = getOpcodeBlock(opcodePrefix);
432         return (block == null ? null : block[opcode]);
433     }
434 
getOpcodeBlock(int opcodePrefix)435     private static Opcode[] getOpcodeBlock(int opcodePrefix) {
436         switch (opcodePrefix) {
437             case 0:
438                 return stdOpcodes;
439             case WIDE:
440                 return wideOpcodes;
441             case NONPRIV:
442                 return nonPrivOpcodes;
443             case PRIV:
444                 return privOpcodes;
445             default:
446                 return null;
447         }
448 
449     }
450 
451     private static final Opcode[] stdOpcodes = new Opcode[256];
452     private static final Opcode[] wideOpcodes = new Opcode[256];
453     private static final Opcode[] nonPrivOpcodes = new Opcode[256];
454     private static final Opcode[] privOpcodes = new Opcode[256];
455     static {
456         for (Opcode o: values())
457             getOpcodeBlock(o.opcode >> 8)[o.opcode & 0xff] = o;
458     }
459 
460     /** The byte prefix for the wide instructions. */
461     public static final int WIDE = 0xc4;
462     /** The byte prefix for the PicoJava nonpriv instructions. */
463     public static final int NONPRIV = 0xfe;
464     /** The byte prefix for the PicoJava priv instructions. */
465     public static final int PRIV = 0xff;
466 
467     public enum Set {
468         /** Standard opcodes. */
469         STANDARD,
470         /** Legacy support for PicoJava opcodes. */
471         PICOJAVA  }
472 }
473