• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dx.rop.code;
18 
19 import com.android.dx.rop.cst.Constant;
20 import com.android.dx.rop.cst.CstBaseMethodRef;
21 import com.android.dx.rop.cst.CstCallSiteRef;
22 import com.android.dx.rop.cst.CstMethodRef;
23 import com.android.dx.rop.cst.CstType;
24 import com.android.dx.rop.type.Prototype;
25 import com.android.dx.rop.type.StdTypeList;
26 import com.android.dx.rop.type.Type;
27 import com.android.dx.rop.type.TypeBearer;
28 import com.android.dx.rop.type.TypeList;
29 
30 /**
31  * Standard instances of {@link Rop}.
32  */
33 public final class Rops {
34     /** {@code nop()} */
35     public static final Rop NOP =
36         new Rop(RegOps.NOP, Type.VOID, StdTypeList.EMPTY, "nop");
37 
38     /** {@code r,x: int :: r = x;} */
39     public static final Rop MOVE_INT =
40         new Rop(RegOps.MOVE, Type.INT, StdTypeList.INT, "move-int");
41 
42     /** {@code r,x: long :: r = x;} */
43     public static final Rop MOVE_LONG =
44         new Rop(RegOps.MOVE, Type.LONG, StdTypeList.LONG, "move-long");
45 
46     /** {@code r,x: float :: r = x;} */
47     public static final Rop MOVE_FLOAT =
48         new Rop(RegOps.MOVE, Type.FLOAT, StdTypeList.FLOAT, "move-float");
49 
50     /** {@code r,x: double :: r = x;} */
51     public static final Rop MOVE_DOUBLE =
52         new Rop(RegOps.MOVE, Type.DOUBLE, StdTypeList.DOUBLE, "move-double");
53 
54     /** {@code r,x: Object :: r = x;} */
55     public static final Rop MOVE_OBJECT =
56         new Rop(RegOps.MOVE, Type.OBJECT, StdTypeList.OBJECT, "move-object");
57 
58     /**
59      * {@code r,x: ReturnAddress :: r = x;}
60      *
61      * Note that this rop-form instruction has no dex-form equivilent and
62      * must be removed before the dex conversion.
63      */
64     public static final Rop MOVE_RETURN_ADDRESS =
65         new Rop(RegOps.MOVE, Type.RETURN_ADDRESS,
66                 StdTypeList.RETURN_ADDRESS, "move-return-address");
67 
68     /** {@code r,param(x): int :: r = param(x);} */
69     public static final Rop MOVE_PARAM_INT =
70         new Rop(RegOps.MOVE_PARAM, Type.INT, StdTypeList.EMPTY,
71                 "move-param-int");
72 
73     /** {@code r,param(x): long :: r = param(x);} */
74     public static final Rop MOVE_PARAM_LONG =
75         new Rop(RegOps.MOVE_PARAM, Type.LONG, StdTypeList.EMPTY,
76                 "move-param-long");
77 
78     /** {@code r,param(x): float :: r = param(x);} */
79     public static final Rop MOVE_PARAM_FLOAT =
80         new Rop(RegOps.MOVE_PARAM, Type.FLOAT, StdTypeList.EMPTY,
81                 "move-param-float");
82 
83     /** {@code r,param(x): double :: r = param(x);} */
84     public static final Rop MOVE_PARAM_DOUBLE =
85         new Rop(RegOps.MOVE_PARAM, Type.DOUBLE, StdTypeList.EMPTY,
86                 "move-param-double");
87 
88     /** {@code r,param(x): Object :: r = param(x);} */
89     public static final Rop MOVE_PARAM_OBJECT =
90         new Rop(RegOps.MOVE_PARAM, Type.OBJECT, StdTypeList.EMPTY,
91                 "move-param-object");
92 
93     /** {@code r, literal: int :: r = literal;} */
94     public static final Rop CONST_INT =
95         new Rop(RegOps.CONST, Type.INT, StdTypeList.EMPTY, "const-int");
96 
97     /** {@code r, literal: long :: r = literal;} */
98     public static final Rop CONST_LONG =
99         new Rop(RegOps.CONST, Type.LONG, StdTypeList.EMPTY, "const-long");
100 
101     /** {@code r, literal: float :: r = literal;} */
102     public static final Rop CONST_FLOAT =
103         new Rop(RegOps.CONST, Type.FLOAT, StdTypeList.EMPTY, "const-float");
104 
105     /** {@code r, literal: double :: r = literal;} */
106     public static final Rop CONST_DOUBLE =
107         new Rop(RegOps.CONST, Type.DOUBLE, StdTypeList.EMPTY, "const-double");
108 
109     /** {@code r, literal: Object :: r = literal;} */
110     public static final Rop CONST_OBJECT =
111         new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,
112                 Exceptions.LIST_Error, "const-object");
113 
114     /** {@code r, literal: Object :: r = literal;} */
115     public static final Rop CONST_OBJECT_NOTHROW =
116         new Rop(RegOps.CONST, Type.OBJECT, StdTypeList.EMPTY,
117                 "const-object-nothrow");
118 
119     /** {@code goto label} */
120     public static final Rop GOTO =
121         new Rop(RegOps.GOTO, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_GOTO,
122                 "goto");
123 
124     /** {@code x: int :: if (x == 0) goto label} */
125     public static final Rop IF_EQZ_INT =
126         new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
127                 "if-eqz-int");
128 
129     /** {@code x: int :: if (x != 0) goto label} */
130     public static final Rop IF_NEZ_INT =
131         new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
132                 "if-nez-int");
133 
134     /** {@code x: int :: if (x < 0) goto label} */
135     public static final Rop IF_LTZ_INT =
136         new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
137                 "if-ltz-int");
138 
139     /** {@code x: int :: if (x >= 0) goto label} */
140     public static final Rop IF_GEZ_INT =
141         new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
142                 "if-gez-int");
143 
144     /** {@code x: int :: if (x <= 0) goto label} */
145     public static final Rop IF_LEZ_INT =
146         new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
147                 "if-lez-int");
148 
149     /** {@code x: int :: if (x > 0) goto label} */
150     public static final Rop IF_GTZ_INT =
151         new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT, Rop.BRANCH_IF,
152                 "if-gtz-int");
153 
154     /** {@code x: Object :: if (x == null) goto label} */
155     public static final Rop IF_EQZ_OBJECT =
156         new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,
157                 "if-eqz-object");
158 
159     /** {@code x: Object :: if (x != null) goto label} */
160     public static final Rop IF_NEZ_OBJECT =
161         new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT, Rop.BRANCH_IF,
162                 "if-nez-object");
163 
164     /** {@code x,y: int :: if (x == y) goto label} */
165     public static final Rop IF_EQ_INT =
166         new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
167                 "if-eq-int");
168 
169     /** {@code x,y: int :: if (x != y) goto label} */
170     public static final Rop IF_NE_INT =
171         new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
172                 "if-ne-int");
173 
174     /** {@code x,y: int :: if (x < y) goto label} */
175     public static final Rop IF_LT_INT =
176         new Rop(RegOps.IF_LT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
177                 "if-lt-int");
178 
179     /** {@code x,y: int :: if (x >= y) goto label} */
180     public static final Rop IF_GE_INT =
181         new Rop(RegOps.IF_GE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
182                 "if-ge-int");
183 
184     /** {@code x,y: int :: if (x <= y) goto label} */
185     public static final Rop IF_LE_INT =
186         new Rop(RegOps.IF_LE, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
187                 "if-le-int");
188 
189     /** {@code x,y: int :: if (x > y) goto label} */
190     public static final Rop IF_GT_INT =
191         new Rop(RegOps.IF_GT, Type.VOID, StdTypeList.INT_INT, Rop.BRANCH_IF,
192                 "if-gt-int");
193 
194     /** {@code x,y: Object :: if (x == y) goto label} */
195     public static final Rop IF_EQ_OBJECT =
196         new Rop(RegOps.IF_EQ, Type.VOID, StdTypeList.OBJECT_OBJECT,
197                 Rop.BRANCH_IF, "if-eq-object");
198 
199     /** {@code x,y: Object :: if (x != y) goto label} */
200     public static final Rop IF_NE_OBJECT =
201         new Rop(RegOps.IF_NE, Type.VOID, StdTypeList.OBJECT_OBJECT,
202                 Rop.BRANCH_IF, "if-ne-object");
203 
204     /** {@code x: int :: goto switchtable[x]} */
205     public static final Rop SWITCH =
206         new Rop(RegOps.SWITCH, Type.VOID, StdTypeList.INT, Rop.BRANCH_SWITCH,
207                 "switch");
208 
209     /** {@code r,x,y: int :: r = x + y;} */
210     public static final Rop ADD_INT =
211         new Rop(RegOps.ADD, Type.INT, StdTypeList.INT_INT, "add-int");
212 
213     /** {@code r,x,y: long :: r = x + y;} */
214     public static final Rop ADD_LONG =
215         new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG_LONG, "add-long");
216 
217     /** {@code r,x,y: float :: r = x + y;} */
218     public static final Rop ADD_FLOAT =
219         new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "add-float");
220 
221     /** {@code r,x,y: double :: r = x + y;} */
222     public static final Rop ADD_DOUBLE =
223         new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
224                 Rop.BRANCH_NONE, "add-double");
225 
226     /** {@code r,x,y: int :: r = x - y;} */
227     public static final Rop SUB_INT =
228         new Rop(RegOps.SUB, Type.INT, StdTypeList.INT_INT, "sub-int");
229 
230     /** {@code r,x,y: long :: r = x - y;} */
231     public static final Rop SUB_LONG =
232         new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG_LONG, "sub-long");
233 
234     /** {@code r,x,y: float :: r = x - y;} */
235     public static final Rop SUB_FLOAT =
236         new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "sub-float");
237 
238     /** {@code r,x,y: double :: r = x - y;} */
239     public static final Rop SUB_DOUBLE =
240         new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
241                 Rop.BRANCH_NONE, "sub-double");
242 
243     /** {@code r,x,y: int :: r = x * y;} */
244     public static final Rop MUL_INT =
245         new Rop(RegOps.MUL, Type.INT, StdTypeList.INT_INT, "mul-int");
246 
247     /** {@code r,x,y: long :: r = x * y;} */
248     public static final Rop MUL_LONG =
249         new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG_LONG, "mul-long");
250 
251     /** {@code r,x,y: float :: r = x * y;} */
252     public static final Rop MUL_FLOAT =
253         new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "mul-float");
254 
255     /** {@code r,x,y: double :: r = x * y;} */
256     public static final Rop MUL_DOUBLE =
257         new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
258                 Rop.BRANCH_NONE, "mul-double");
259 
260     /** {@code r,x,y: int :: r = x / y;} */
261     public static final Rop DIV_INT =
262         new Rop(RegOps.DIV, Type.INT, StdTypeList.INT_INT,
263                 Exceptions.LIST_Error_ArithmeticException, "div-int");
264 
265     /** {@code r,x,y: long :: r = x / y;} */
266     public static final Rop DIV_LONG =
267         new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG_LONG,
268                 Exceptions.LIST_Error_ArithmeticException, "div-long");
269 
270     /** {@code r,x,y: float :: r = x / y;} */
271     public static final Rop DIV_FLOAT =
272         new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "div-float");
273 
274     /** {@code r,x,y: double :: r = x / y;} */
275     public static final Rop DIV_DOUBLE =
276         new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
277                 "div-double");
278 
279     /** {@code r,x,y: int :: r = x % y;} */
280     public static final Rop REM_INT =
281         new Rop(RegOps.REM, Type.INT, StdTypeList.INT_INT,
282                 Exceptions.LIST_Error_ArithmeticException, "rem-int");
283 
284     /** {@code r,x,y: long :: r = x % y;} */
285     public static final Rop REM_LONG =
286         new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG_LONG,
287                 Exceptions.LIST_Error_ArithmeticException, "rem-long");
288 
289     /** {@code r,x,y: float :: r = x % y;} */
290     public static final Rop REM_FLOAT =
291         new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT_FLOAT, "rem-float");
292 
293     /** {@code r,x,y: double :: r = x % y;} */
294     public static final Rop REM_DOUBLE =
295         new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE_DOUBLE,
296                 "rem-double");
297 
298     /** {@code r,x: int :: r = -x;} */
299     public static final Rop NEG_INT =
300         new Rop(RegOps.NEG, Type.INT, StdTypeList.INT, "neg-int");
301 
302     /** {@code r,x: long :: r = -x;} */
303     public static final Rop NEG_LONG =
304         new Rop(RegOps.NEG, Type.LONG, StdTypeList.LONG, "neg-long");
305 
306     /** {@code r,x: float :: r = -x;} */
307     public static final Rop NEG_FLOAT =
308         new Rop(RegOps.NEG, Type.FLOAT, StdTypeList.FLOAT, "neg-float");
309 
310     /** {@code r,x: double :: r = -x;} */
311     public static final Rop NEG_DOUBLE =
312         new Rop(RegOps.NEG, Type.DOUBLE, StdTypeList.DOUBLE, "neg-double");
313 
314     /** {@code r,x,y: int :: r = x & y;} */
315     public static final Rop AND_INT =
316         new Rop(RegOps.AND, Type.INT, StdTypeList.INT_INT, "and-int");
317 
318     /** {@code r,x,y: long :: r = x & y;} */
319     public static final Rop AND_LONG =
320         new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG_LONG, "and-long");
321 
322     /** {@code r,x,y: int :: r = x | y;} */
323     public static final Rop OR_INT =
324         new Rop(RegOps.OR, Type.INT, StdTypeList.INT_INT, "or-int");
325 
326     /** {@code r,x,y: long :: r = x | y;} */
327     public static final Rop OR_LONG =
328         new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG_LONG, "or-long");
329 
330     /** {@code r,x,y: int :: r = x ^ y;} */
331     public static final Rop XOR_INT =
332         new Rop(RegOps.XOR, Type.INT, StdTypeList.INT_INT, "xor-int");
333 
334     /** {@code r,x,y: long :: r = x ^ y;} */
335     public static final Rop XOR_LONG =
336         new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG_LONG, "xor-long");
337 
338     /** {@code r,x,y: int :: r = x << y;} */
339     public static final Rop SHL_INT =
340         new Rop(RegOps.SHL, Type.INT, StdTypeList.INT_INT, "shl-int");
341 
342     /** {@code r,x: long; y: int :: r = x << y;} */
343     public static final Rop SHL_LONG =
344         new Rop(RegOps.SHL, Type.LONG, StdTypeList.LONG_INT, "shl-long");
345 
346     /** {@code r,x,y: int :: r = x >> y;} */
347     public static final Rop SHR_INT =
348         new Rop(RegOps.SHR, Type.INT, StdTypeList.INT_INT, "shr-int");
349 
350     /** {@code r,x: long; y: int :: r = x >> y;} */
351     public static final Rop SHR_LONG =
352         new Rop(RegOps.SHR, Type.LONG, StdTypeList.LONG_INT, "shr-long");
353 
354     /** {@code r,x,y: int :: r = x >>> y;} */
355     public static final Rop USHR_INT =
356         new Rop(RegOps.USHR, Type.INT, StdTypeList.INT_INT, "ushr-int");
357 
358     /** {@code r,x: long; y: int :: r = x >>> y;} */
359     public static final Rop USHR_LONG =
360         new Rop(RegOps.USHR, Type.LONG, StdTypeList.LONG_INT, "ushr-long");
361 
362     /** {@code r,x: int :: r = ~x;} */
363     public static final Rop NOT_INT =
364         new Rop(RegOps.NOT, Type.INT, StdTypeList.INT, "not-int");
365 
366     /** {@code r,x: long :: r = ~x;} */
367     public static final Rop NOT_LONG =
368         new Rop(RegOps.NOT, Type.LONG, StdTypeList.LONG, "not-long");
369 
370     /** {@code r,x,c: int :: r = x + c;} */
371     public static final Rop ADD_CONST_INT =
372         new Rop(RegOps.ADD, Type.INT, StdTypeList.INT, "add-const-int");
373 
374     /** {@code r,x,c: long :: r = x + c;} */
375     public static final Rop ADD_CONST_LONG =
376         new Rop(RegOps.ADD, Type.LONG, StdTypeList.LONG, "add-const-long");
377 
378     /** {@code r,x,c: float :: r = x + c;} */
379     public static final Rop ADD_CONST_FLOAT =
380         new Rop(RegOps.ADD, Type.FLOAT, StdTypeList.FLOAT, "add-const-float");
381 
382     /** {@code r,x,c: double :: r = x + c;} */
383     public static final Rop ADD_CONST_DOUBLE =
384         new Rop(RegOps.ADD, Type.DOUBLE, StdTypeList.DOUBLE,
385                 "add-const-double");
386 
387     /** {@code r,x,c: int :: r = x - c;} */
388     public static final Rop SUB_CONST_INT =
389         new Rop(RegOps.SUB, Type.INT, StdTypeList.INT, "sub-const-int");
390 
391     /** {@code r,x,c: long :: r = x - c;} */
392     public static final Rop SUB_CONST_LONG =
393         new Rop(RegOps.SUB, Type.LONG, StdTypeList.LONG, "sub-const-long");
394 
395     /** {@code r,x,c: float :: r = x - c;} */
396     public static final Rop SUB_CONST_FLOAT =
397         new Rop(RegOps.SUB, Type.FLOAT, StdTypeList.FLOAT, "sub-const-float");
398 
399     /** {@code r,x,c: double :: r = x - c;} */
400     public static final Rop SUB_CONST_DOUBLE =
401         new Rop(RegOps.SUB, Type.DOUBLE, StdTypeList.DOUBLE,
402                 "sub-const-double");
403 
404     /** {@code r,x,c: int :: r = x * c;} */
405     public static final Rop MUL_CONST_INT =
406         new Rop(RegOps.MUL, Type.INT, StdTypeList.INT, "mul-const-int");
407 
408     /** {@code r,x,c: long :: r = x * c;} */
409     public static final Rop MUL_CONST_LONG =
410         new Rop(RegOps.MUL, Type.LONG, StdTypeList.LONG, "mul-const-long");
411 
412     /** {@code r,x,c: float :: r = x * c;} */
413     public static final Rop MUL_CONST_FLOAT =
414         new Rop(RegOps.MUL, Type.FLOAT, StdTypeList.FLOAT, "mul-const-float");
415 
416     /** {@code r,x,c: double :: r = x * c;} */
417     public static final Rop MUL_CONST_DOUBLE =
418         new Rop(RegOps.MUL, Type.DOUBLE, StdTypeList.DOUBLE,
419                 "mul-const-double");
420 
421     /** {@code r,x,c: int :: r = x / c;} */
422     public static final Rop DIV_CONST_INT =
423         new Rop(RegOps.DIV, Type.INT, StdTypeList.INT,
424                 Exceptions.LIST_Error_ArithmeticException, "div-const-int");
425 
426     /** {@code r,x,c: long :: r = x / c;} */
427     public static final Rop DIV_CONST_LONG =
428         new Rop(RegOps.DIV, Type.LONG, StdTypeList.LONG,
429                 Exceptions.LIST_Error_ArithmeticException, "div-const-long");
430 
431     /** {@code r,x,c: float :: r = x / c;} */
432     public static final Rop DIV_CONST_FLOAT =
433         new Rop(RegOps.DIV, Type.FLOAT, StdTypeList.FLOAT, "div-const-float");
434 
435     /** {@code r,x,c: double :: r = x / c;} */
436     public static final Rop DIV_CONST_DOUBLE =
437         new Rop(RegOps.DIV, Type.DOUBLE, StdTypeList.DOUBLE,
438                 "div-const-double");
439 
440     /** {@code r,x,c: int :: r = x % c;} */
441     public static final Rop REM_CONST_INT =
442         new Rop(RegOps.REM, Type.INT, StdTypeList.INT,
443                 Exceptions.LIST_Error_ArithmeticException, "rem-const-int");
444 
445     /** {@code r,x,c: long :: r = x % c;} */
446     public static final Rop REM_CONST_LONG =
447         new Rop(RegOps.REM, Type.LONG, StdTypeList.LONG,
448                 Exceptions.LIST_Error_ArithmeticException, "rem-const-long");
449 
450     /** {@code r,x,c: float :: r = x % c;} */
451     public static final Rop REM_CONST_FLOAT =
452         new Rop(RegOps.REM, Type.FLOAT, StdTypeList.FLOAT, "rem-const-float");
453 
454     /** {@code r,x,c: double :: r = x % c;} */
455     public static final Rop REM_CONST_DOUBLE =
456         new Rop(RegOps.REM, Type.DOUBLE, StdTypeList.DOUBLE,
457                 "rem-const-double");
458 
459     /** {@code r,x,c: int :: r = x & c;} */
460     public static final Rop AND_CONST_INT =
461         new Rop(RegOps.AND, Type.INT, StdTypeList.INT, "and-const-int");
462 
463     /** {@code r,x,c: long :: r = x & c;} */
464     public static final Rop AND_CONST_LONG =
465         new Rop(RegOps.AND, Type.LONG, StdTypeList.LONG, "and-const-long");
466 
467     /** {@code r,x,c: int :: r = x | c;} */
468     public static final Rop OR_CONST_INT =
469         new Rop(RegOps.OR, Type.INT, StdTypeList.INT, "or-const-int");
470 
471     /** {@code r,x,c: long :: r = x | c;} */
472     public static final Rop OR_CONST_LONG =
473         new Rop(RegOps.OR, Type.LONG, StdTypeList.LONG, "or-const-long");
474 
475     /** {@code r,x,c: int :: r = x ^ c;} */
476     public static final Rop XOR_CONST_INT =
477         new Rop(RegOps.XOR, Type.INT, StdTypeList.INT, "xor-const-int");
478 
479     /** {@code r,x,c: long :: r = x ^ c;} */
480     public static final Rop XOR_CONST_LONG =
481         new Rop(RegOps.XOR, Type.LONG, StdTypeList.LONG, "xor-const-long");
482 
483     /** {@code r,x,c: int :: r = x << c;} */
484     public static final Rop SHL_CONST_INT =
485         new Rop(RegOps.SHL, Type.INT, StdTypeList.INT, "shl-const-int");
486 
487     /** {@code r,x: long; c: int :: r = x << c;} */
488     public static final Rop SHL_CONST_LONG =
489         new Rop(RegOps.SHL, Type.LONG, StdTypeList.INT, "shl-const-long");
490 
491     /** {@code r,x,c: int :: r = x >> c;} */
492     public static final Rop SHR_CONST_INT =
493         new Rop(RegOps.SHR, Type.INT, StdTypeList.INT, "shr-const-int");
494 
495     /** {@code r,x: long; c: int :: r = x >> c;} */
496     public static final Rop SHR_CONST_LONG =
497         new Rop(RegOps.SHR, Type.LONG, StdTypeList.INT, "shr-const-long");
498 
499     /** {@code r,x,c: int :: r = x >>> c;} */
500     public static final Rop USHR_CONST_INT =
501         new Rop(RegOps.USHR, Type.INT, StdTypeList.INT, "ushr-const-int");
502 
503     /** {@code r,x: long; c: int :: r = x >>> c;} */
504     public static final Rop USHR_CONST_LONG =
505         new Rop(RegOps.USHR, Type.LONG, StdTypeList.INT, "ushr-const-long");
506 
507     /** {@code r: int; x,y: long :: r = cmp(x, y);} */
508     public static final Rop CMPL_LONG =
509         new Rop(RegOps.CMPL, Type.INT, StdTypeList.LONG_LONG, "cmpl-long");
510 
511     /** {@code r: int; x,y: float :: r = cmpl(x, y);} */
512     public static final Rop CMPL_FLOAT =
513         new Rop(RegOps.CMPL, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpl-float");
514 
515     /** {@code r: int; x,y: double :: r = cmpl(x, y);} */
516     public static final Rop CMPL_DOUBLE =
517         new Rop(RegOps.CMPL, Type.INT, StdTypeList.DOUBLE_DOUBLE,
518                 "cmpl-double");
519 
520     /** {@code r: int; x,y: float :: r = cmpg(x, y);} */
521     public static final Rop CMPG_FLOAT =
522         new Rop(RegOps.CMPG, Type.INT, StdTypeList.FLOAT_FLOAT, "cmpg-float");
523 
524     /** {@code r: int; x,y: double :: r = cmpg(x, y);} */
525     public static final Rop CMPG_DOUBLE =
526         new Rop(RegOps.CMPG, Type.INT, StdTypeList.DOUBLE_DOUBLE,
527                 "cmpg-double");
528 
529     /** {@code r: int; x: long :: r = (int) x} */
530     public static final Rop CONV_L2I =
531         new Rop(RegOps.CONV, Type.INT, StdTypeList.LONG, "conv-l2i");
532 
533     /** {@code r: int; x: float :: r = (int) x} */
534     public static final Rop CONV_F2I =
535         new Rop(RegOps.CONV, Type.INT, StdTypeList.FLOAT, "conv-f2i");
536 
537     /** {@code r: int; x: double :: r = (int) x} */
538     public static final Rop CONV_D2I =
539         new Rop(RegOps.CONV, Type.INT, StdTypeList.DOUBLE, "conv-d2i");
540 
541     /** {@code r: long; x: int :: r = (long) x} */
542     public static final Rop CONV_I2L =
543         new Rop(RegOps.CONV, Type.LONG, StdTypeList.INT, "conv-i2l");
544 
545     /** {@code r: long; x: float :: r = (long) x} */
546     public static final Rop CONV_F2L =
547         new Rop(RegOps.CONV, Type.LONG, StdTypeList.FLOAT, "conv-f2l");
548 
549     /** {@code r: long; x: double :: r = (long) x} */
550     public static final Rop CONV_D2L =
551         new Rop(RegOps.CONV, Type.LONG, StdTypeList.DOUBLE, "conv-d2l");
552 
553     /** {@code r: float; x: int :: r = (float) x} */
554     public static final Rop CONV_I2F =
555         new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.INT, "conv-i2f");
556 
557     /** {@code r: float; x: long :: r = (float) x} */
558     public static final Rop CONV_L2F =
559         new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.LONG, "conv-l2f");
560 
561     /** {@code r: float; x: double :: r = (float) x} */
562     public static final Rop CONV_D2F =
563         new Rop(RegOps.CONV, Type.FLOAT, StdTypeList.DOUBLE, "conv-d2f");
564 
565     /** {@code r: double; x: int :: r = (double) x} */
566     public static final Rop CONV_I2D =
567         new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.INT, "conv-i2d");
568 
569     /** {@code r: double; x: long :: r = (double) x} */
570     public static final Rop CONV_L2D =
571         new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.LONG, "conv-l2d");
572 
573     /** {@code r: double; x: float :: r = (double) x} */
574     public static final Rop CONV_F2D =
575         new Rop(RegOps.CONV, Type.DOUBLE, StdTypeList.FLOAT, "conv-f2d");
576 
577     /**
578      * {@code r,x: int :: r = (x << 24) >> 24} (Java-style
579      * convert int to byte)
580      */
581     public static final Rop TO_BYTE =
582         new Rop(RegOps.TO_BYTE, Type.INT, StdTypeList.INT, "to-byte");
583 
584     /**
585      * {@code r,x: int :: r = x & 0xffff} (Java-style
586      * convert int to char)
587      */
588     public static final Rop TO_CHAR =
589         new Rop(RegOps.TO_CHAR, Type.INT, StdTypeList.INT, "to-char");
590 
591     /**
592      * {@code r,x: int :: r = (x << 16) >> 16} (Java-style
593      * convert int to short)
594      */
595     public static final Rop TO_SHORT =
596         new Rop(RegOps.TO_SHORT, Type.INT, StdTypeList.INT, "to-short");
597 
598     /** {@code return void} */
599     public static final Rop RETURN_VOID =
600         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.EMPTY, Rop.BRANCH_RETURN,
601                 "return-void");
602 
603     /** {@code x: int; return x} */
604     public static final Rop RETURN_INT =
605         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.INT, Rop.BRANCH_RETURN,
606                 "return-int");
607 
608     /** {@code x: long; return x} */
609     public static final Rop RETURN_LONG =
610         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.LONG, Rop.BRANCH_RETURN,
611                 "return-long");
612 
613     /** {@code x: float; return x} */
614     public static final Rop RETURN_FLOAT =
615         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.FLOAT, Rop.BRANCH_RETURN,
616                 "return-float");
617 
618     /** {@code x: double; return x} */
619     public static final Rop RETURN_DOUBLE =
620         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.DOUBLE,
621                 Rop.BRANCH_RETURN, "return-double");
622 
623     /** {@code x: Object; return x} */
624     public static final Rop RETURN_OBJECT =
625         new Rop(RegOps.RETURN, Type.VOID, StdTypeList.OBJECT,
626                 Rop.BRANCH_RETURN, "return-object");
627 
628     /** {@code T: any type; r: int; x: T[]; :: r = x.length} */
629     public static final Rop ARRAY_LENGTH =
630         new Rop(RegOps.ARRAY_LENGTH, Type.INT, StdTypeList.OBJECT,
631                 Exceptions.LIST_Error_NullPointerException, "array-length");
632 
633     /** {@code x: Throwable :: throw(x)} */
634     public static final Rop THROW =
635         new Rop(RegOps.THROW, Type.VOID, StdTypeList.THROWABLE,
636                 StdTypeList.THROWABLE, "throw");
637 
638     /** {@code x: Object :: monitorenter(x)} */
639     public static final Rop MONITOR_ENTER =
640         new Rop(RegOps.MONITOR_ENTER, Type.VOID, StdTypeList.OBJECT,
641                 Exceptions.LIST_Error_NullPointerException, "monitor-enter");
642 
643     /** {@code x: Object :: monitorexit(x)} */
644     public static final Rop MONITOR_EXIT =
645         new Rop(RegOps.MONITOR_EXIT, Type.VOID, StdTypeList.OBJECT,
646                 Exceptions.LIST_Error_Null_IllegalMonitorStateException,
647                 "monitor-exit");
648 
649     /** {@code r,y: int; x: int[] :: r = x[y]} */
650     public static final Rop AGET_INT =
651         new Rop(RegOps.AGET, Type.INT, StdTypeList.INTARR_INT,
652                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
653                 "aget-int");
654 
655     /** {@code r: long; x: long[]; y: int :: r = x[y]} */
656     public static final Rop AGET_LONG =
657         new Rop(RegOps.AGET, Type.LONG, StdTypeList.LONGARR_INT,
658                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
659                 "aget-long");
660 
661     /** {@code r: float; x: float[]; y: int :: r = x[y]} */
662     public static final Rop AGET_FLOAT =
663         new Rop(RegOps.AGET, Type.FLOAT, StdTypeList.FLOATARR_INT,
664                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
665                 "aget-float");
666 
667     /** {@code r: double; x: double[]; y: int :: r = x[y]} */
668     public static final Rop AGET_DOUBLE =
669         new Rop(RegOps.AGET, Type.DOUBLE, StdTypeList.DOUBLEARR_INT,
670                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
671                 "aget-double");
672 
673     /** {@code r: Object; x: Object[]; y: int :: r = x[y]} */
674     public static final Rop AGET_OBJECT =
675         new Rop(RegOps.AGET, Type.OBJECT, StdTypeList.OBJECTARR_INT,
676                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
677                 "aget-object");
678 
679     /** {@code r: boolean; x: boolean[]; y: int :: r = x[y]} */
680     public static final Rop AGET_BOOLEAN =
681         new Rop(RegOps.AGET, Type.INT, StdTypeList.BOOLEANARR_INT,
682                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
683                 "aget-boolean");
684 
685     /** {@code r: byte; x: byte[]; y: int :: r = x[y]} */
686     public static final Rop AGET_BYTE =
687         new Rop(RegOps.AGET, Type.INT, StdTypeList.BYTEARR_INT,
688                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-byte");
689 
690     /** {@code r: char; x: char[]; y: int :: r = x[y]} */
691     public static final Rop AGET_CHAR =
692         new Rop(RegOps.AGET, Type.INT, StdTypeList.CHARARR_INT,
693                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aget-char");
694 
695     /** {@code r: short; x: short[]; y: int :: r = x[y]} */
696     public static final Rop AGET_SHORT =
697         new Rop(RegOps.AGET, Type.INT, StdTypeList.SHORTARR_INT,
698                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
699                 "aget-short");
700 
701     /** {@code x,z: int; y: int[] :: y[z] = x} */
702     public static final Rop APUT_INT =
703         new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_INTARR_INT,
704                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-int");
705 
706     /** {@code x: long; y: long[]; z: int :: y[z] = x} */
707     public static final Rop APUT_LONG =
708         new Rop(RegOps.APUT, Type.VOID, StdTypeList.LONG_LONGARR_INT,
709                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds, "aput-long");
710 
711     /** {@code x: float; y: float[]; z: int :: y[z] = x} */
712     public static final Rop APUT_FLOAT =
713         new Rop(RegOps.APUT, Type.VOID, StdTypeList.FLOAT_FLOATARR_INT,
714                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
715                 "aput-float");
716 
717     /** {@code x: double; y: double[]; z: int :: y[z] = x} */
718     public static final Rop APUT_DOUBLE =
719         new Rop(RegOps.APUT, Type.VOID, StdTypeList.DOUBLE_DOUBLEARR_INT,
720                 Exceptions.LIST_Error_Null_ArrayIndexOutOfBounds,
721                 "aput-double");
722 
723     /** {@code x: Object; y: Object[]; z: int :: y[z] = x} */
724     public static final Rop APUT_OBJECT =
725         new Rop(RegOps.APUT, Type.VOID, StdTypeList.OBJECT_OBJECTARR_INT,
726                 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
727                 "aput-object");
728 
729     /** {@code x: boolean; y: boolean[]; z: int :: y[z] = x} */
730     public static final Rop APUT_BOOLEAN =
731         new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BOOLEANARR_INT,
732                 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
733                 "aput-boolean");
734 
735     /** {@code x: byte; y: byte[]; z: int :: y[z] = x} */
736     public static final Rop APUT_BYTE =
737         new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_BYTEARR_INT,
738                 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-byte");
739 
740     /** {@code x: char; y: char[]; z: int :: y[z] = x} */
741     public static final Rop APUT_CHAR =
742         new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_CHARARR_INT,
743                 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore, "aput-char");
744 
745     /** {@code x: short; y: short[]; z: int :: y[z] = x} */
746     public static final Rop APUT_SHORT =
747         new Rop(RegOps.APUT, Type.VOID, StdTypeList.INT_SHORTARR_INT,
748                 Exceptions.LIST_Error_Null_ArrayIndex_ArrayStore,
749                 "aput-short");
750 
751     /**
752      * {@code T: any non-array object type :: r =
753      * alloc(T)} (allocate heap space for an object)
754      */
755     public static final Rop NEW_INSTANCE =
756         new Rop(RegOps.NEW_INSTANCE, Type.OBJECT, StdTypeList.EMPTY,
757                 Exceptions.LIST_Error, "new-instance");
758 
759     /** {@code r: int[]; x: int :: r = new int[x]} */
760     public static final Rop NEW_ARRAY_INT =
761         new Rop(RegOps.NEW_ARRAY, Type.INT_ARRAY, StdTypeList.INT,
762                 Exceptions.LIST_Error_NegativeArraySizeException,
763                 "new-array-int");
764 
765     /** {@code r: long[]; x: int :: r = new long[x]} */
766     public static final Rop NEW_ARRAY_LONG =
767         new Rop(RegOps.NEW_ARRAY, Type.LONG_ARRAY, StdTypeList.INT,
768                 Exceptions.LIST_Error_NegativeArraySizeException,
769                 "new-array-long");
770 
771     /** {@code r: float[]; x: int :: r = new float[x]} */
772     public static final Rop NEW_ARRAY_FLOAT =
773         new Rop(RegOps.NEW_ARRAY, Type.FLOAT_ARRAY, StdTypeList.INT,
774                 Exceptions.LIST_Error_NegativeArraySizeException,
775                 "new-array-float");
776 
777     /** {@code r: double[]; x: int :: r = new double[x]} */
778     public static final Rop NEW_ARRAY_DOUBLE =
779         new Rop(RegOps.NEW_ARRAY, Type.DOUBLE_ARRAY, StdTypeList.INT,
780                 Exceptions.LIST_Error_NegativeArraySizeException,
781                 "new-array-double");
782 
783     /** {@code r: boolean[]; x: int :: r = new boolean[x]} */
784     public static final Rop NEW_ARRAY_BOOLEAN =
785         new Rop(RegOps.NEW_ARRAY, Type.BOOLEAN_ARRAY, StdTypeList.INT,
786                 Exceptions.LIST_Error_NegativeArraySizeException,
787                 "new-array-boolean");
788 
789     /** {@code r: byte[]; x: int :: r = new byte[x]} */
790     public static final Rop NEW_ARRAY_BYTE =
791         new Rop(RegOps.NEW_ARRAY, Type.BYTE_ARRAY, StdTypeList.INT,
792                 Exceptions.LIST_Error_NegativeArraySizeException,
793                 "new-array-byte");
794 
795     /** {@code r: char[]; x: int :: r = new char[x]} */
796     public static final Rop NEW_ARRAY_CHAR =
797         new Rop(RegOps.NEW_ARRAY, Type.CHAR_ARRAY, StdTypeList.INT,
798                 Exceptions.LIST_Error_NegativeArraySizeException,
799                 "new-array-char");
800 
801     /** {@code r: short[]; x: int :: r = new short[x]} */
802     public static final Rop NEW_ARRAY_SHORT =
803         new Rop(RegOps.NEW_ARRAY, Type.SHORT_ARRAY, StdTypeList.INT,
804                 Exceptions.LIST_Error_NegativeArraySizeException,
805                 "new-array-short");
806 
807     /**
808      * {@code T: any non-array object type; x: Object :: (T) x} (can
809      * throw {@code ClassCastException})
810      */
811     public static final Rop CHECK_CAST =
812         new Rop(RegOps.CHECK_CAST, Type.VOID, StdTypeList.OBJECT,
813                 Exceptions.LIST_Error_ClassCastException, "check-cast");
814 
815     /**
816      * {@code T: any non-array object type; x: Object :: x instanceof
817      * T}. Note: This is listed as throwing {@code Error}
818      * explicitly because the op <i>can</i> throw, but there are no
819      * other predefined exceptions for it.
820      */
821     public static final Rop INSTANCE_OF =
822         new Rop(RegOps.INSTANCE_OF, Type.INT, StdTypeList.OBJECT,
823                 Exceptions.LIST_Error, "instance-of");
824 
825     /**
826      * {@code r: int; x: Object; f: instance field spec of
827      * type int :: r = x.f}
828      */
829     public static final Rop GET_FIELD_INT =
830         new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
831                 Exceptions.LIST_Error_NullPointerException, "get-field-int");
832 
833     /**
834      * {@code r: long; x: Object; f: instance field spec of
835      * type long :: r = x.f}
836      */
837     public static final Rop GET_FIELD_LONG =
838         new Rop(RegOps.GET_FIELD, Type.LONG, StdTypeList.OBJECT,
839                 Exceptions.LIST_Error_NullPointerException, "get-field-long");
840 
841     /**
842      * {@code r: float; x: Object; f: instance field spec of
843      * type float :: r = x.f}
844      */
845     public static final Rop GET_FIELD_FLOAT =
846         new Rop(RegOps.GET_FIELD, Type.FLOAT, StdTypeList.OBJECT,
847                 Exceptions.LIST_Error_NullPointerException,
848                 "get-field-float");
849 
850     /**
851      * {@code r: double; x: Object; f: instance field spec of
852      * type double :: r = x.f}
853      */
854     public static final Rop GET_FIELD_DOUBLE =
855         new Rop(RegOps.GET_FIELD, Type.DOUBLE, StdTypeList.OBJECT,
856                 Exceptions.LIST_Error_NullPointerException,
857                 "get-field-double");
858 
859     /**
860      * {@code r: Object; x: Object; f: instance field spec of
861      * type Object :: r = x.f}
862      */
863     public static final Rop GET_FIELD_OBJECT =
864         new Rop(RegOps.GET_FIELD, Type.OBJECT, StdTypeList.OBJECT,
865                 Exceptions.LIST_Error_NullPointerException,
866                 "get-field-object");
867 
868     /**
869      * {@code r: boolean; x: Object; f: instance field spec of
870      * type boolean :: r = x.f}
871      */
872     public static final Rop GET_FIELD_BOOLEAN =
873         new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
874                 Exceptions.LIST_Error_NullPointerException,
875                 "get-field-boolean");
876 
877     /**
878      * {@code r: byte; x: Object; f: instance field spec of
879      * type byte :: r = x.f}
880      */
881     public static final Rop GET_FIELD_BYTE =
882         new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
883                 Exceptions.LIST_Error_NullPointerException,
884                 "get-field-byte");
885 
886     /**
887      * {@code r: char; x: Object; f: instance field spec of
888      * type char :: r = x.f}
889      */
890     public static final Rop GET_FIELD_CHAR =
891         new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
892                 Exceptions.LIST_Error_NullPointerException,
893                 "get-field-char");
894 
895     /**
896      * {@code r: short; x: Object; f: instance field spec of
897      * type short :: r = x.f}
898      */
899     public static final Rop GET_FIELD_SHORT =
900         new Rop(RegOps.GET_FIELD, Type.INT, StdTypeList.OBJECT,
901                 Exceptions.LIST_Error_NullPointerException,
902                 "get-field-short");
903 
904     /** {@code r: int; f: static field spec of type int :: r = f} */
905     public static final Rop GET_STATIC_INT =
906         new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
907                 Exceptions.LIST_Error, "get-static-int");
908 
909     /** {@code r: long; f: static field spec of type long :: r = f} */
910     public static final Rop GET_STATIC_LONG =
911         new Rop(RegOps.GET_STATIC, Type.LONG, StdTypeList.EMPTY,
912                 Exceptions.LIST_Error, "get-static-long");
913 
914     /** {@code r: float; f: static field spec of type float :: r = f} */
915     public static final Rop GET_STATIC_FLOAT =
916         new Rop(RegOps.GET_STATIC, Type.FLOAT, StdTypeList.EMPTY,
917                 Exceptions.LIST_Error, "get-static-float");
918 
919     /** {@code r: double; f: static field spec of type double :: r = f} */
920     public static final Rop GET_STATIC_DOUBLE =
921         new Rop(RegOps.GET_STATIC, Type.DOUBLE, StdTypeList.EMPTY,
922                 Exceptions.LIST_Error, "get-static-double");
923 
924     /** {@code r: Object; f: static field spec of type Object :: r = f} */
925     public static final Rop GET_STATIC_OBJECT =
926         new Rop(RegOps.GET_STATIC, Type.OBJECT, StdTypeList.EMPTY,
927                 Exceptions.LIST_Error, "get-static-object");
928 
929     /** {@code r: boolean; f: static field spec of type boolean :: r = f} */
930     public static final Rop GET_STATIC_BOOLEAN =
931         new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
932                 Exceptions.LIST_Error, "get-field-boolean");
933 
934     /** {@code r: byte; f: static field spec of type byte :: r = f} */
935     public static final Rop GET_STATIC_BYTE =
936         new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
937                 Exceptions.LIST_Error, "get-field-byte");
938 
939     /** {@code r: char; f: static field spec of type char :: r = f} */
940     public static final Rop GET_STATIC_CHAR =
941         new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
942                 Exceptions.LIST_Error, "get-field-char");
943 
944     /** {@code r: short; f: static field spec of type short :: r = f} */
945     public static final Rop GET_STATIC_SHORT =
946         new Rop(RegOps.GET_STATIC, Type.INT, StdTypeList.EMPTY,
947                 Exceptions.LIST_Error, "get-field-short");
948 
949     /**
950      * {@code x: int; y: Object; f: instance field spec of type
951      * int :: y.f = x}
952      */
953     public static final Rop PUT_FIELD_INT =
954         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
955                 Exceptions.LIST_Error_NullPointerException, "put-field-int");
956 
957     /**
958      * {@code x: long; y: Object; f: instance field spec of type
959      * long :: y.f = x}
960      */
961     public static final Rop PUT_FIELD_LONG =
962         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.LONG_OBJECT,
963                 Exceptions.LIST_Error_NullPointerException, "put-field-long");
964 
965     /**
966      * {@code x: float; y: Object; f: instance field spec of type
967      * float :: y.f = x}
968      */
969     public static final Rop PUT_FIELD_FLOAT =
970         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.FLOAT_OBJECT,
971                 Exceptions.LIST_Error_NullPointerException,
972                 "put-field-float");
973 
974     /**
975      * {@code x: double; y: Object; f: instance field spec of type
976      * double :: y.f = x}
977      */
978     public static final Rop PUT_FIELD_DOUBLE =
979         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.DOUBLE_OBJECT,
980                 Exceptions.LIST_Error_NullPointerException,
981                 "put-field-double");
982 
983     /**
984      * {@code x: Object; y: Object; f: instance field spec of type
985      * Object :: y.f = x}
986      */
987     public static final Rop PUT_FIELD_OBJECT =
988         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.OBJECT_OBJECT,
989                 Exceptions.LIST_Error_NullPointerException,
990                 "put-field-object");
991 
992     /**
993      * {@code x: int; y: Object; f: instance field spec of type
994      * boolean :: y.f = x}
995      */
996     public static final Rop PUT_FIELD_BOOLEAN =
997         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
998                 Exceptions.LIST_Error_NullPointerException,
999                 "put-field-boolean");
1000 
1001     /**
1002      * {@code x: int; y: Object; f: instance field spec of type
1003      * byte :: y.f = x}
1004      */
1005     public static final Rop PUT_FIELD_BYTE =
1006         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
1007                 Exceptions.LIST_Error_NullPointerException,
1008                 "put-field-byte");
1009 
1010     /**
1011      * {@code x: int; y: Object; f: instance field spec of type
1012      * char :: y.f = x}
1013      */
1014     public static final Rop PUT_FIELD_CHAR =
1015         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
1016                 Exceptions.LIST_Error_NullPointerException,
1017                 "put-field-char");
1018 
1019     /**
1020      * {@code x: int; y: Object; f: instance field spec of type
1021      * short :: y.f = x}
1022      */
1023     public static final Rop PUT_FIELD_SHORT =
1024         new Rop(RegOps.PUT_FIELD, Type.VOID, StdTypeList.INT_OBJECT,
1025                 Exceptions.LIST_Error_NullPointerException,
1026                 "put-field-short");
1027 
1028     /** {@code f: static field spec of type int; x: int :: f = x} */
1029     public static final Rop PUT_STATIC_INT =
1030         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
1031                 Exceptions.LIST_Error, "put-static-int");
1032 
1033     /** {@code f: static field spec of type long; x: long :: f = x} */
1034     public static final Rop PUT_STATIC_LONG =
1035         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.LONG,
1036                 Exceptions.LIST_Error, "put-static-long");
1037 
1038     /** {@code f: static field spec of type float; x: float :: f = x} */
1039     public static final Rop PUT_STATIC_FLOAT =
1040         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.FLOAT,
1041                 Exceptions.LIST_Error, "put-static-float");
1042 
1043     /** {@code f: static field spec of type double; x: double :: f = x} */
1044     public static final Rop PUT_STATIC_DOUBLE =
1045         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.DOUBLE,
1046                 Exceptions.LIST_Error, "put-static-double");
1047 
1048     /** {@code f: static field spec of type Object; x: Object :: f = x} */
1049     public static final Rop PUT_STATIC_OBJECT =
1050         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.OBJECT,
1051                 Exceptions.LIST_Error, "put-static-object");
1052 
1053     /**
1054      * {@code f: static field spec of type boolean; x: boolean :: f =
1055      * x}
1056      */
1057     public static final Rop PUT_STATIC_BOOLEAN =
1058         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
1059                 Exceptions.LIST_Error, "put-static-boolean");
1060 
1061     /** {@code f: static field spec of type byte; x: byte :: f = x} */
1062     public static final Rop PUT_STATIC_BYTE =
1063         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
1064                 Exceptions.LIST_Error, "put-static-byte");
1065 
1066     /** {@code f: static field spec of type char; x: char :: f = x} */
1067     public static final Rop PUT_STATIC_CHAR =
1068         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
1069                 Exceptions.LIST_Error, "put-static-char");
1070 
1071     /** {@code f: static field spec of type short; x: short :: f = x} */
1072     public static final Rop PUT_STATIC_SHORT =
1073         new Rop(RegOps.PUT_STATIC, Type.VOID, StdTypeList.INT,
1074                 Exceptions.LIST_Error, "put-static-short");
1075 
1076     /** {@code x: Int :: local variable begins in x} */
1077     public static final Rop MARK_LOCAL_INT =
1078             new Rop (RegOps.MARK_LOCAL, Type.VOID,
1079                     StdTypeList.INT, "mark-local-int");
1080 
1081     /** {@code x: Long :: local variable begins in x} */
1082     public static final Rop MARK_LOCAL_LONG =
1083             new Rop (RegOps.MARK_LOCAL, Type.VOID,
1084                     StdTypeList.LONG, "mark-local-long");
1085 
1086     /** {@code x: Float :: local variable begins in x} */
1087     public static final Rop MARK_LOCAL_FLOAT =
1088             new Rop (RegOps.MARK_LOCAL, Type.VOID,
1089                     StdTypeList.FLOAT, "mark-local-float");
1090 
1091     /** {@code x: Double :: local variable begins in x} */
1092     public static final Rop MARK_LOCAL_DOUBLE =
1093             new Rop (RegOps.MARK_LOCAL, Type.VOID,
1094                     StdTypeList.DOUBLE, "mark-local-double");
1095 
1096     /** {@code x: Object :: local variable begins in x} */
1097     public static final Rop MARK_LOCAL_OBJECT =
1098             new Rop (RegOps.MARK_LOCAL, Type.VOID,
1099                     StdTypeList.OBJECT, "mark-local-object");
1100 
1101     /** {@code T: Any primitive type; v0..vx: T :: {v0, ..., vx}} */
1102     public static final Rop FILL_ARRAY_DATA =
1103         new Rop(RegOps.FILL_ARRAY_DATA, Type.VOID, StdTypeList.EMPTY,
1104                 "fill-array-data");
1105 
1106     /**
1107      * Returns the appropriate rop for the given opcode, destination,
1108      * and sources. The result is typically, but not necessarily, a
1109      * shared instance.
1110      *
1111      * <p><b>Note:</b> This method does not do complete error checking on
1112      * its arguments, and so it may return an instance which seemed "right
1113      * enough" even though in actuality the passed arguments don't quite
1114      * match what is returned. TODO: Revisit this issue.</p>
1115      *
1116      * @param opcode the opcode
1117      * @param dest {@code non-null;} destination (result) type, or
1118      * {@link Type#VOID} if none
1119      * @param sources {@code non-null;} list of source types
1120      * @param cst {@code null-ok;} associated constant, if any
1121      * @return {@code non-null;} an appropriate instance
1122      */
ropFor(int opcode, TypeBearer dest, TypeList sources, Constant cst)1123     public static Rop ropFor(int opcode, TypeBearer dest, TypeList sources,
1124             Constant cst) {
1125         switch (opcode) {
1126             case RegOps.NOP: return NOP;
1127             case RegOps.MOVE: return opMove(dest);
1128             case RegOps.MOVE_PARAM: return opMoveParam(dest);
1129             case RegOps.MOVE_EXCEPTION: return opMoveException(dest);
1130             case RegOps.CONST: return opConst(dest);
1131             case RegOps.GOTO: return GOTO;
1132             case RegOps.IF_EQ: return opIfEq(sources);
1133             case RegOps.IF_NE: return opIfNe(sources);
1134             case RegOps.IF_LT: return opIfLt(sources);
1135             case RegOps.IF_GE: return opIfGe(sources);
1136             case RegOps.IF_LE: return opIfLe(sources);
1137             case RegOps.IF_GT: return opIfGt(sources);
1138             case RegOps.SWITCH: return SWITCH;
1139             case RegOps.ADD: return opAdd(sources);
1140             case RegOps.SUB: return opSub(sources);
1141             case RegOps.MUL: return opMul(sources);
1142             case RegOps.DIV: return opDiv(sources);
1143             case RegOps.REM: return opRem(sources);
1144             case RegOps.NEG: return opNeg(dest);
1145             case RegOps.AND: return opAnd(sources);
1146             case RegOps.OR: return opOr(sources);
1147             case RegOps.XOR: return opXor(sources);
1148             case RegOps.SHL: return opShl(sources);
1149             case RegOps.SHR: return opShr(sources);
1150             case RegOps.USHR: return opUshr(sources);
1151             case RegOps.NOT: return opNot(dest);
1152             case RegOps.CMPL: return opCmpl(sources.getType(0));
1153             case RegOps.CMPG: return opCmpg(sources.getType(0));
1154             case RegOps.CONV: return opConv(dest, sources.getType(0));
1155             case RegOps.TO_BYTE: return TO_BYTE;
1156             case RegOps.TO_CHAR: return TO_CHAR;
1157             case RegOps.TO_SHORT: return TO_SHORT;
1158             case RegOps.RETURN: {
1159                 if (sources.size() == 0) {
1160                     return RETURN_VOID;
1161                 }
1162                 return opReturn(sources.getType(0));
1163             }
1164             case RegOps.ARRAY_LENGTH: return ARRAY_LENGTH;
1165             case RegOps.THROW: return THROW;
1166             case RegOps.MONITOR_ENTER: return MONITOR_ENTER;
1167             case RegOps.MONITOR_EXIT: return MONITOR_EXIT;
1168             case RegOps.AGET: {
1169                 Type source = sources.getType(0);
1170                 Type componentType;
1171                 if (source == Type.KNOWN_NULL) {
1172                     /*
1173                      * Treat a known-null as an array of the expected
1174                      * result type.
1175                      */
1176                     componentType = dest.getType();
1177                 } else {
1178                     componentType = source.getComponentType();
1179                 }
1180                 return opAget(componentType);
1181             }
1182             case RegOps.APUT: {
1183                 Type source = sources.getType(1);
1184                 Type componentType;
1185                 if (source == Type.KNOWN_NULL) {
1186                     /*
1187                      * Treat a known-null as an array of the type being
1188                      * stored.
1189                      */
1190                     componentType = sources.getType(0);
1191                 } else {
1192                     componentType = source.getComponentType();
1193                 }
1194                 return opAput(componentType);
1195             }
1196             case RegOps.NEW_INSTANCE: return NEW_INSTANCE;
1197             case RegOps.NEW_ARRAY: return opNewArray(dest.getType());
1198             case RegOps.CHECK_CAST: return CHECK_CAST;
1199             case RegOps.INSTANCE_OF: return INSTANCE_OF;
1200             case RegOps.GET_FIELD: return opGetField(dest);
1201             case RegOps.GET_STATIC: return opGetStatic(dest);
1202             case RegOps.PUT_FIELD: return opPutField(sources.getType(0));
1203             case RegOps.PUT_STATIC: return opPutStatic(sources.getType(0));
1204             case RegOps.INVOKE_STATIC: {
1205                 return opInvokeStatic(((CstMethodRef) cst).getPrototype());
1206             }
1207             case RegOps.INVOKE_VIRTUAL: {
1208                 CstBaseMethodRef cstMeth = (CstMethodRef) cst;
1209                 Prototype meth = cstMeth.getPrototype();
1210                 CstType definer = cstMeth.getDefiningClass();
1211                 meth = meth.withFirstParameter(definer.getClassType());
1212                 return opInvokeVirtual(meth);
1213             }
1214             case RegOps.INVOKE_SUPER: {
1215                 CstBaseMethodRef cstMeth = (CstMethodRef) cst;
1216                 Prototype meth = cstMeth.getPrototype();
1217                 CstType definer = cstMeth.getDefiningClass();
1218                 meth = meth.withFirstParameter(definer.getClassType());
1219                 return opInvokeSuper(meth);
1220             }
1221             case RegOps.INVOKE_DIRECT: {
1222                 CstBaseMethodRef cstMeth = (CstMethodRef) cst;
1223                 Prototype meth = cstMeth.getPrototype();
1224                 CstType definer = cstMeth.getDefiningClass();
1225                 meth = meth.withFirstParameter(definer.getClassType());
1226                 return opInvokeDirect(meth);
1227             }
1228             case RegOps.INVOKE_INTERFACE: {
1229                 CstBaseMethodRef cstMeth = (CstMethodRef) cst;
1230                 Prototype meth = cstMeth.getPrototype();
1231                 CstType definer = cstMeth.getDefiningClass();
1232                 meth = meth.withFirstParameter(definer.getClassType());
1233                 return opInvokeInterface(meth);
1234             }
1235             case RegOps.INVOKE_POLYMORPHIC: {
1236                 CstBaseMethodRef cstMeth = (CstMethodRef) cst;
1237                 Prototype proto = cstMeth.getPrototype();
1238                 CstType definer = cstMeth.getDefiningClass();
1239                 Prototype meth = proto.withFirstParameter(definer.getClassType());
1240                 return opInvokePolymorphic(meth);
1241             }
1242             case RegOps.INVOKE_CUSTOM: {
1243                 CstCallSiteRef cstInvokeDynamicRef = (CstCallSiteRef) cst;
1244                 Prototype proto = cstInvokeDynamicRef.getPrototype();
1245                 return opInvokeCustom(proto);
1246             }
1247         }
1248 
1249         throw new RuntimeException("unknown opcode " + RegOps.opName(opcode));
1250     }
1251 
1252     /**
1253      * Returns the appropriate {@code move} rop for the given type. The
1254      * result is a shared instance.
1255      *
1256      * @param type {@code non-null;} type of value being moved
1257      * @return {@code non-null;} an appropriate instance
1258      */
opMove(TypeBearer type)1259     public static Rop opMove(TypeBearer type) {
1260         switch (type.getBasicFrameType()) {
1261             case Type.BT_INT:    return MOVE_INT;
1262             case Type.BT_LONG:   return MOVE_LONG;
1263             case Type.BT_FLOAT:  return MOVE_FLOAT;
1264             case Type.BT_DOUBLE: return MOVE_DOUBLE;
1265             case Type.BT_OBJECT: return MOVE_OBJECT;
1266             case Type.BT_ADDR:   return MOVE_RETURN_ADDRESS;
1267         }
1268 
1269         return throwBadType(type);
1270     }
1271 
1272     /**
1273      * Returns the appropriate {@code move-param} rop for the
1274      * given type. The result is a shared instance.
1275      *
1276      * @param type {@code non-null;} type of value being moved
1277      * @return {@code non-null;} an appropriate instance
1278      */
opMoveParam(TypeBearer type)1279     public static Rop opMoveParam(TypeBearer type) {
1280         switch (type.getBasicFrameType()) {
1281             case Type.BT_INT:    return MOVE_PARAM_INT;
1282             case Type.BT_LONG:   return MOVE_PARAM_LONG;
1283             case Type.BT_FLOAT:  return MOVE_PARAM_FLOAT;
1284             case Type.BT_DOUBLE: return MOVE_PARAM_DOUBLE;
1285             case Type.BT_OBJECT: return MOVE_PARAM_OBJECT;
1286         }
1287 
1288         return throwBadType(type);
1289     }
1290 
1291     /**
1292      * Returns the appropriate {@code move-exception} rop for the
1293      * given type. The result may be a shared instance.
1294      *
1295      * @param type {@code non-null;} type of the exception
1296      * @return {@code non-null;} an appropriate instance
1297      */
opMoveException(TypeBearer type)1298     public static Rop opMoveException(TypeBearer type) {
1299         return new Rop(RegOps.MOVE_EXCEPTION, type.getType(),
1300                        StdTypeList.EMPTY, (String) null);
1301     }
1302 
1303     /**
1304      * Returns the appropriate {@code move-result} rop for the
1305      * given type. The result may be a shared instance.
1306      *
1307      * @param type {@code non-null;} type of the parameter
1308      * @return {@code non-null;} an appropriate instance
1309      */
opMoveResult(TypeBearer type)1310     public static Rop opMoveResult(TypeBearer type) {
1311         return new Rop(RegOps.MOVE_RESULT, type.getType(),
1312                        StdTypeList.EMPTY, (String) null);
1313     }
1314 
1315     /**
1316      * Returns the appropriate {@code move-result-pseudo} rop for the
1317      * given type. The result may be a shared instance.
1318      *
1319      * @param type {@code non-null;} type of the parameter
1320      * @return {@code non-null;} an appropriate instance
1321      */
opMoveResultPseudo(TypeBearer type)1322     public static Rop opMoveResultPseudo(TypeBearer type) {
1323         return new Rop(RegOps.MOVE_RESULT_PSEUDO, type.getType(),
1324                        StdTypeList.EMPTY, (String) null);
1325     }
1326 
1327     /**
1328      * Returns the appropriate {@code const} rop for the given
1329      * type. The result is a shared instance.
1330      *
1331      * @param type {@code non-null;} type of the constant
1332      * @return {@code non-null;} an appropriate instance
1333      */
opConst(TypeBearer type)1334     public static Rop opConst(TypeBearer type) {
1335         if (type.getType() == Type.KNOWN_NULL) {
1336             return CONST_OBJECT_NOTHROW;
1337         }
1338 
1339         switch (type.getBasicFrameType()) {
1340             case Type.BT_INT:    return CONST_INT;
1341             case Type.BT_LONG:   return CONST_LONG;
1342             case Type.BT_FLOAT:  return CONST_FLOAT;
1343             case Type.BT_DOUBLE: return CONST_DOUBLE;
1344             case Type.BT_OBJECT: return CONST_OBJECT;
1345         }
1346 
1347         return throwBadType(type);
1348     }
1349 
1350     /**
1351      * Returns the appropriate {@code if-eq} rop for the given
1352      * sources. The result is a shared instance.
1353      *
1354      * @param types {@code non-null;} source types
1355      * @return {@code non-null;} an appropriate instance
1356      */
opIfEq(TypeList types)1357     public static Rop opIfEq(TypeList types) {
1358         return pickIf(types, IF_EQZ_INT, IF_EQZ_OBJECT,
1359                       IF_EQ_INT, IF_EQ_OBJECT);
1360     }
1361 
1362     /**
1363      * Returns the appropriate {@code if-ne} rop for the given
1364      * sources. The result is a shared instance.
1365      *
1366      * @param types {@code non-null;} source types
1367      * @return {@code non-null;} an appropriate instance
1368      */
opIfNe(TypeList types)1369     public static Rop opIfNe(TypeList types) {
1370         return pickIf(types, IF_NEZ_INT, IF_NEZ_OBJECT,
1371                       IF_NE_INT, IF_NE_OBJECT);
1372     }
1373 
1374     /**
1375      * Returns the appropriate {@code if-lt} rop for the given
1376      * sources. The result is a shared instance.
1377      *
1378      * @param types {@code non-null;} source types
1379      * @return {@code non-null;} an appropriate instance
1380      */
opIfLt(TypeList types)1381     public static Rop opIfLt(TypeList types) {
1382         return pickIf(types, IF_LTZ_INT, null, IF_LT_INT, null);
1383     }
1384 
1385     /**
1386      * Returns the appropriate {@code if-ge} rop for the given
1387      * sources. The result is a shared instance.
1388      *
1389      * @param types {@code non-null;} source types
1390      * @return {@code non-null;} an appropriate instance
1391      */
opIfGe(TypeList types)1392     public static Rop opIfGe(TypeList types) {
1393         return pickIf(types, IF_GEZ_INT, null, IF_GE_INT, null);
1394     }
1395 
1396     /**
1397      * Returns the appropriate {@code if-gt} rop for the given
1398      * sources. The result is a shared instance.
1399      *
1400      * @param types {@code non-null;} source types
1401      * @return {@code non-null;} an appropriate instance
1402      */
opIfGt(TypeList types)1403     public static Rop opIfGt(TypeList types) {
1404         return pickIf(types, IF_GTZ_INT, null, IF_GT_INT, null);
1405     }
1406 
1407     /**
1408      * Returns the appropriate {@code if-le} rop for the given
1409      * sources. The result is a shared instance.
1410      *
1411      * @param types {@code non-null;} source types
1412      * @return {@code non-null;} an appropriate instance
1413      */
opIfLe(TypeList types)1414     public static Rop opIfLe(TypeList types) {
1415         return pickIf(types, IF_LEZ_INT, null, IF_LE_INT, null);
1416     }
1417 
1418     /**
1419      * Helper for all the {@code if*}-related methods, which
1420      * checks types and picks one of the four variants, throwing if
1421      * there's a problem.
1422      *
1423      * @param types {@code non-null;} the types
1424      * @param intZ {@code non-null;} the int-to-0 comparison
1425      * @param objZ {@code null-ok;} the object-to-null comparison
1426      * @param intInt {@code non-null;} the int-to-int comparison
1427      * @param objObj {@code non-null;} the object-to-object comparison
1428      * @return {@code non-null;} the appropriate instance
1429      */
pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt, Rop objObj)1430     private static Rop pickIf(TypeList types, Rop intZ, Rop objZ, Rop intInt,
1431                               Rop objObj) {
1432         switch(types.size()) {
1433             case 1: {
1434                 switch (types.getType(0).getBasicFrameType()) {
1435                     case Type.BT_INT: {
1436                         return intZ;
1437                     }
1438                     case Type.BT_OBJECT: {
1439                         if (objZ != null) {
1440                             return objZ;
1441                         }
1442                     }
1443                 }
1444                 break;
1445             }
1446             case 2: {
1447                 int bt = types.getType(0).getBasicFrameType();
1448                 if (bt == types.getType(1).getBasicFrameType()) {
1449                     switch (bt) {
1450                         case Type.BT_INT: {
1451                             return intInt;
1452                         }
1453                         case Type.BT_OBJECT: {
1454                             if (objObj != null) {
1455                                 return objObj;
1456                             }
1457                         }
1458                     }
1459                 }
1460                 break;
1461             }
1462         }
1463 
1464         return throwBadTypes(types);
1465     }
1466 
1467     /**
1468      * Returns the appropriate {@code add} rop for the given
1469      * types. The result is a shared instance.
1470      *
1471      * @param types {@code non-null;} types of the sources
1472      * @return {@code non-null;} an appropriate instance
1473      */
opAdd(TypeList types)1474     public static Rop opAdd(TypeList types) {
1475         return pickBinaryOp(types, ADD_CONST_INT, ADD_CONST_LONG,
1476                             ADD_CONST_FLOAT, ADD_CONST_DOUBLE, ADD_INT,
1477                             ADD_LONG, ADD_FLOAT, ADD_DOUBLE);
1478     }
1479 
1480     /**
1481      * Returns the appropriate {@code sub} rop for the given
1482      * types. The result is a shared instance.
1483      *
1484      * @param types {@code non-null;} types of the sources
1485      * @return {@code non-null;} an appropriate instance
1486      */
opSub(TypeList types)1487     public static Rop opSub(TypeList types) {
1488         return pickBinaryOp(types, SUB_CONST_INT, SUB_CONST_LONG,
1489                             SUB_CONST_FLOAT, SUB_CONST_DOUBLE, SUB_INT,
1490                             SUB_LONG, SUB_FLOAT, SUB_DOUBLE);
1491     }
1492 
1493     /**
1494      * Returns the appropriate {@code mul} rop for the given
1495      * types. The result is a shared instance.
1496      *
1497      * @param types {@code non-null;} types of the sources
1498      * @return {@code non-null;} an appropriate instance
1499      */
opMul(TypeList types)1500     public static Rop opMul(TypeList types) {
1501         return pickBinaryOp(types, MUL_CONST_INT, MUL_CONST_LONG,
1502                             MUL_CONST_FLOAT, MUL_CONST_DOUBLE, MUL_INT,
1503                             MUL_LONG, MUL_FLOAT, MUL_DOUBLE);
1504     }
1505 
1506     /**
1507      * Returns the appropriate {@code div} rop for the given
1508      * types. The result is a shared instance.
1509      *
1510      * @param types {@code non-null;} types of the sources
1511      * @return {@code non-null;} an appropriate instance
1512      */
opDiv(TypeList types)1513     public static Rop opDiv(TypeList types) {
1514         return pickBinaryOp(types, DIV_CONST_INT, DIV_CONST_LONG,
1515                             DIV_CONST_FLOAT, DIV_CONST_DOUBLE, DIV_INT,
1516                             DIV_LONG, DIV_FLOAT, DIV_DOUBLE);
1517     }
1518 
1519     /**
1520      * Returns the appropriate {@code rem} rop for the given
1521      * types. The result is a shared instance.
1522      *
1523      * @param types {@code non-null;} types of the sources
1524      * @return {@code non-null;} an appropriate instance
1525      */
opRem(TypeList types)1526     public static Rop opRem(TypeList types) {
1527         return pickBinaryOp(types, REM_CONST_INT, REM_CONST_LONG,
1528                             REM_CONST_FLOAT, REM_CONST_DOUBLE, REM_INT,
1529                             REM_LONG, REM_FLOAT, REM_DOUBLE);
1530     }
1531 
1532     /**
1533      * Returns the appropriate {@code and} rop for the given
1534      * types. The result is a shared instance.
1535      *
1536      * @param types {@code non-null;} types of the sources
1537      * @return {@code non-null;} an appropriate instance
1538      */
opAnd(TypeList types)1539     public static Rop opAnd(TypeList types) {
1540         return pickBinaryOp(types, AND_CONST_INT, AND_CONST_LONG, null, null,
1541                             AND_INT, AND_LONG, null, null);
1542     }
1543 
1544     /**
1545      * Returns the appropriate {@code or} rop for the given
1546      * types. The result is a shared instance.
1547      *
1548      * @param types {@code non-null;} types of the sources
1549      * @return {@code non-null;} an appropriate instance
1550      */
opOr(TypeList types)1551     public static Rop opOr(TypeList types) {
1552         return pickBinaryOp(types, OR_CONST_INT, OR_CONST_LONG, null, null,
1553                             OR_INT, OR_LONG, null, null);
1554     }
1555 
1556     /**
1557      * Returns the appropriate {@code xor} rop for the given
1558      * types. The result is a shared instance.
1559      *
1560      * @param types {@code non-null;} types of the sources
1561      * @return {@code non-null;} an appropriate instance
1562      */
opXor(TypeList types)1563     public static Rop opXor(TypeList types) {
1564         return pickBinaryOp(types, XOR_CONST_INT, XOR_CONST_LONG, null, null,
1565                             XOR_INT, XOR_LONG, null, null);
1566     }
1567 
1568     /**
1569      * Returns the appropriate {@code shl} rop for the given
1570      * types. The result is a shared instance.
1571      *
1572      * @param types {@code non-null;} types of the sources
1573      * @return {@code non-null;} an appropriate instance
1574      */
opShl(TypeList types)1575     public static Rop opShl(TypeList types) {
1576         return pickBinaryOp(types, SHL_CONST_INT, SHL_CONST_LONG, null, null,
1577                             SHL_INT, SHL_LONG, null, null);
1578     }
1579 
1580     /**
1581      * Returns the appropriate {@code shr} rop for the given
1582      * types. The result is a shared instance.
1583      *
1584      * @param types {@code non-null;} types of the sources
1585      * @return {@code non-null;} an appropriate instance
1586      */
opShr(TypeList types)1587     public static Rop opShr(TypeList types) {
1588         return pickBinaryOp(types, SHR_CONST_INT, SHR_CONST_LONG, null, null,
1589                             SHR_INT, SHR_LONG, null, null);
1590     }
1591 
1592     /**
1593      * Returns the appropriate {@code ushr} rop for the given
1594      * types. The result is a shared instance.
1595      *
1596      * @param types {@code non-null;} types of the sources
1597      * @return {@code non-null;} an appropriate instance
1598      */
opUshr(TypeList types)1599     public static Rop opUshr(TypeList types) {
1600         return pickBinaryOp(types, USHR_CONST_INT, USHR_CONST_LONG, null, null,
1601                             USHR_INT, USHR_LONG, null, null);
1602     }
1603 
1604     /**
1605      * Returns the appropriate binary arithmetic rop for the given type
1606      * and arguments. The result is a shared instance.
1607      *
1608      * @param types {@code non-null;} sources of the operation
1609      * @param int1 {@code non-null;} the int-to-constant rop
1610      * @param long1 {@code non-null;} the long-to-constant rop
1611      * @param float1 {@code null-ok;} the float-to-constant rop, if any
1612      * @param double1 {@code null-ok;} the double-to-constant rop, if any
1613      * @param int2 {@code non-null;} the int-to-int rop
1614      * @param long2 {@code non-null;} the long-to-long or long-to-int rop
1615      * @param float2 {@code null-ok;} the float-to-float rop, if any
1616      * @param double2 {@code null-ok;} the double-to-double rop, if any
1617      * @return {@code non-null;} an appropriate instance
1618      */
pickBinaryOp(TypeList types, Rop int1, Rop long1, Rop float1, Rop double1, Rop int2, Rop long2, Rop float2, Rop double2)1619     private static Rop pickBinaryOp(TypeList types, Rop int1, Rop long1,
1620                                     Rop float1, Rop double1, Rop int2,
1621                                     Rop long2, Rop float2, Rop double2) {
1622         int bt1 = types.getType(0).getBasicFrameType();
1623         Rop result = null;
1624 
1625         switch (types.size()) {
1626             case 1: {
1627                 switch(bt1) {
1628                     case Type.BT_INT:    return int1;
1629                     case Type.BT_LONG:   return long1;
1630                     case Type.BT_FLOAT:  result = float1; break;
1631                     case Type.BT_DOUBLE: result = double1; break;
1632                 }
1633                 break;
1634             }
1635             case 2: {
1636                 switch(bt1) {
1637                     case Type.BT_INT:    return int2;
1638                     case Type.BT_LONG:   return long2;
1639                     case Type.BT_FLOAT:  result = float2; break;
1640                     case Type.BT_DOUBLE: result = double2; break;
1641                 }
1642                 break;
1643             }
1644         }
1645 
1646         if (result == null) {
1647             return throwBadTypes(types);
1648         }
1649 
1650         return result;
1651     }
1652 
1653     /**
1654      * Returns the appropriate {@code neg} rop for the given type. The
1655      * result is a shared instance.
1656      *
1657      * @param type {@code non-null;} type of value being operated on
1658      * @return {@code non-null;} an appropriate instance
1659      */
opNeg(TypeBearer type)1660     public static Rop opNeg(TypeBearer type) {
1661         switch (type.getBasicFrameType()) {
1662             case Type.BT_INT:    return NEG_INT;
1663             case Type.BT_LONG:   return NEG_LONG;
1664             case Type.BT_FLOAT:  return NEG_FLOAT;
1665             case Type.BT_DOUBLE: return NEG_DOUBLE;
1666         }
1667 
1668         return throwBadType(type);
1669     }
1670 
1671     /**
1672      * Returns the appropriate {@code not} rop for the given type. The
1673      * result is a shared instance.
1674      *
1675      * @param type {@code non-null;} type of value being operated on
1676      * @return {@code non-null;} an appropriate instance
1677      */
opNot(TypeBearer type)1678     public static Rop opNot(TypeBearer type) {
1679         switch (type.getBasicFrameType()) {
1680             case Type.BT_INT:  return NOT_INT;
1681             case Type.BT_LONG: return NOT_LONG;
1682         }
1683 
1684         return throwBadType(type);
1685     }
1686 
1687     /**
1688      * Returns the appropriate {@code cmpl} rop for the given type. The
1689      * result is a shared instance.
1690      *
1691      * @param type {@code non-null;} type of value being compared
1692      * @return {@code non-null;} an appropriate instance
1693      */
opCmpl(TypeBearer type)1694     public static Rop opCmpl(TypeBearer type) {
1695         switch (type.getBasicType()) {
1696             case Type.BT_LONG:   return CMPL_LONG;
1697             case Type.BT_FLOAT:  return CMPL_FLOAT;
1698             case Type.BT_DOUBLE: return CMPL_DOUBLE;
1699         }
1700 
1701         return throwBadType(type);
1702     }
1703 
1704     /**
1705      * Returns the appropriate {@code cmpg} rop for the given type. The
1706      * result is a shared instance.
1707      *
1708      * @param type {@code non-null;} type of value being compared
1709      * @return {@code non-null;} an appropriate instance
1710      */
opCmpg(TypeBearer type)1711     public static Rop opCmpg(TypeBearer type) {
1712         switch (type.getBasicType()) {
1713             case Type.BT_FLOAT:  return CMPG_FLOAT;
1714             case Type.BT_DOUBLE: return CMPG_DOUBLE;
1715         }
1716 
1717         return throwBadType(type);
1718     }
1719 
1720     /**
1721      * Returns the appropriate {@code conv} rop for the given types. The
1722      * result is a shared instance.
1723      *
1724      * @param dest {@code non-null;} target value type
1725      * @param source {@code non-null;} source value type
1726      * @return {@code non-null;} an appropriate instance
1727      */
opConv(TypeBearer dest, TypeBearer source)1728     public static Rop opConv(TypeBearer dest, TypeBearer source) {
1729         int dbt = dest.getBasicFrameType();
1730         switch (source.getBasicFrameType()) {
1731             case Type.BT_INT: {
1732                 switch (dbt) {
1733                     case Type.BT_LONG:   return CONV_I2L;
1734                     case Type.BT_FLOAT:  return CONV_I2F;
1735                     case Type.BT_DOUBLE: return CONV_I2D;
1736                     default:             break;
1737                 }
1738             }
1739             case Type.BT_LONG: {
1740                 switch (dbt) {
1741                     case Type.BT_INT:    return CONV_L2I;
1742                     case Type.BT_FLOAT:  return CONV_L2F;
1743                     case Type.BT_DOUBLE: return CONV_L2D;
1744                     default:             break;
1745                 }
1746             }
1747             case Type.BT_FLOAT: {
1748                 switch (dbt) {
1749                     case Type.BT_INT:    return CONV_F2I;
1750                     case Type.BT_LONG:   return CONV_F2L;
1751                     case Type.BT_DOUBLE: return CONV_F2D;
1752                     default:             break;
1753                 }
1754             }
1755             case Type.BT_DOUBLE: {
1756                 switch (dbt) {
1757                     case Type.BT_INT:    return CONV_D2I;
1758                     case Type.BT_LONG:   return CONV_D2L;
1759                     case Type.BT_FLOAT:  return CONV_D2F;
1760                     default:             break;
1761                 }
1762             }
1763         }
1764 
1765         return throwBadTypes(StdTypeList.make(dest.getType(),
1766                                               source.getType()));
1767     }
1768 
1769     /**
1770      * Returns the appropriate {@code return} rop for the given type. The
1771      * result is a shared instance.
1772      *
1773      * @param type {@code non-null;} type of value being returned
1774      * @return {@code non-null;} an appropriate instance
1775      */
opReturn(TypeBearer type)1776     public static Rop opReturn(TypeBearer type) {
1777         switch (type.getBasicFrameType()) {
1778             case Type.BT_INT:    return RETURN_INT;
1779             case Type.BT_LONG:   return RETURN_LONG;
1780             case Type.BT_FLOAT:  return RETURN_FLOAT;
1781             case Type.BT_DOUBLE: return RETURN_DOUBLE;
1782             case Type.BT_OBJECT: return RETURN_OBJECT;
1783             case Type.BT_VOID:   return RETURN_VOID;
1784         }
1785 
1786         return throwBadType(type);
1787     }
1788 
1789     /**
1790      * Returns the appropriate {@code aget} rop for the given type. The
1791      * result is a shared instance.
1792      *
1793      * @param type {@code non-null;} element type of array being accessed
1794      * @return {@code non-null;} an appropriate instance
1795      */
opAget(TypeBearer type)1796     public static Rop opAget(TypeBearer type) {
1797         switch (type.getBasicType()) {
1798             case Type.BT_INT:     return AGET_INT;
1799             case Type.BT_LONG:    return AGET_LONG;
1800             case Type.BT_FLOAT:   return AGET_FLOAT;
1801             case Type.BT_DOUBLE:  return AGET_DOUBLE;
1802             case Type.BT_OBJECT:  return AGET_OBJECT;
1803             case Type.BT_BOOLEAN: return AGET_BOOLEAN;
1804             case Type.BT_BYTE:    return AGET_BYTE;
1805             case Type.BT_CHAR:    return AGET_CHAR;
1806             case Type.BT_SHORT:   return AGET_SHORT;
1807         }
1808 
1809         return throwBadType(type);
1810     }
1811 
1812     /**
1813      * Returns the appropriate {@code aput} rop for the given type. The
1814      * result is a shared instance.
1815      *
1816      * @param type {@code non-null;} element type of array being accessed
1817      * @return {@code non-null;} an appropriate instance
1818      */
opAput(TypeBearer type)1819     public static Rop opAput(TypeBearer type) {
1820         switch (type.getBasicType()) {
1821             case Type.BT_INT:     return APUT_INT;
1822             case Type.BT_LONG:    return APUT_LONG;
1823             case Type.BT_FLOAT:   return APUT_FLOAT;
1824             case Type.BT_DOUBLE:  return APUT_DOUBLE;
1825             case Type.BT_OBJECT:  return APUT_OBJECT;
1826             case Type.BT_BOOLEAN: return APUT_BOOLEAN;
1827             case Type.BT_BYTE:    return APUT_BYTE;
1828             case Type.BT_CHAR:    return APUT_CHAR;
1829             case Type.BT_SHORT:   return APUT_SHORT;
1830         }
1831 
1832         return throwBadType(type);
1833     }
1834 
1835     /**
1836      * Returns the appropriate {@code new-array} rop for the given
1837      * type. The result is a shared instance.
1838      *
1839      * @param arrayType {@code non-null;} array type of array being created
1840      * @return {@code non-null;} an appropriate instance
1841      */
opNewArray(TypeBearer arrayType)1842     public static Rop opNewArray(TypeBearer arrayType) {
1843         Type type = arrayType.getType();
1844         Type elementType = type.getComponentType();
1845 
1846         switch (elementType.getBasicType()) {
1847             case Type.BT_INT:     return NEW_ARRAY_INT;
1848             case Type.BT_LONG:    return NEW_ARRAY_LONG;
1849             case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
1850             case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
1851             case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
1852             case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
1853             case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
1854             case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
1855             case Type.BT_OBJECT: {
1856                 return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
1857                         Exceptions.LIST_Error_NegativeArraySizeException,
1858                         "new-array-object");
1859             }
1860         }
1861 
1862         return throwBadType(type);
1863     }
1864 
1865     /**
1866      * Returns the appropriate {@code filled-new-array} rop for the given
1867      * type. The result may be a shared instance.
1868      *
1869      * @param arrayType {@code non-null;} type of array being created
1870      * @param count {@code count >= 0;} number of elements that the array should have
1871      * @return {@code non-null;} an appropriate instance
1872      */
opFilledNewArray(TypeBearer arrayType, int count)1873     public static Rop opFilledNewArray(TypeBearer arrayType, int count) {
1874         Type type = arrayType.getType();
1875         Type elementType = type.getComponentType();
1876 
1877         if (elementType.isCategory2()) {
1878             return throwBadType(arrayType);
1879         }
1880 
1881         if (count < 0) {
1882             throw new IllegalArgumentException("count < 0");
1883         }
1884 
1885         StdTypeList sourceTypes = new StdTypeList(count);
1886 
1887         for (int i = 0; i < count; i++) {
1888             sourceTypes.set(i, elementType);
1889         }
1890 
1891         // Note: The resulting rop is considered call-like.
1892         return new Rop(RegOps.FILLED_NEW_ARRAY,
1893                        sourceTypes,
1894                        Exceptions.LIST_Error);
1895     }
1896 
1897     /**
1898      * Returns the appropriate {@code get-field} rop for the given
1899      * type. The result is a shared instance.
1900      *
1901      * @param type {@code non-null;} type of the field in question
1902      * @return {@code non-null;} an appropriate instance
1903      */
opGetField(TypeBearer type)1904     public static Rop opGetField(TypeBearer type) {
1905         switch (type.getBasicType()) {
1906             case Type.BT_INT:     return GET_FIELD_INT;
1907             case Type.BT_LONG:    return GET_FIELD_LONG;
1908             case Type.BT_FLOAT:   return GET_FIELD_FLOAT;
1909             case Type.BT_DOUBLE:  return GET_FIELD_DOUBLE;
1910             case Type.BT_OBJECT:  return GET_FIELD_OBJECT;
1911             case Type.BT_BOOLEAN: return GET_FIELD_BOOLEAN;
1912             case Type.BT_BYTE:    return GET_FIELD_BYTE;
1913             case Type.BT_CHAR:    return GET_FIELD_CHAR;
1914             case Type.BT_SHORT:   return GET_FIELD_SHORT;
1915         }
1916 
1917         return throwBadType(type);
1918     }
1919 
1920     /**
1921      * Returns the appropriate {@code put-field} rop for the given
1922      * type. The result is a shared instance.
1923      *
1924      * @param type {@code non-null;} type of the field in question
1925      * @return {@code non-null;} an appropriate instance
1926      */
opPutField(TypeBearer type)1927     public static Rop opPutField(TypeBearer type) {
1928         switch (type.getBasicType()) {
1929             case Type.BT_INT:     return PUT_FIELD_INT;
1930             case Type.BT_LONG:    return PUT_FIELD_LONG;
1931             case Type.BT_FLOAT:   return PUT_FIELD_FLOAT;
1932             case Type.BT_DOUBLE:  return PUT_FIELD_DOUBLE;
1933             case Type.BT_OBJECT:  return PUT_FIELD_OBJECT;
1934             case Type.BT_BOOLEAN: return PUT_FIELD_BOOLEAN;
1935             case Type.BT_BYTE:    return PUT_FIELD_BYTE;
1936             case Type.BT_CHAR:    return PUT_FIELD_CHAR;
1937             case Type.BT_SHORT:   return PUT_FIELD_SHORT;
1938         }
1939 
1940         return throwBadType(type);
1941     }
1942 
1943     /**
1944      * Returns the appropriate {@code get-static} rop for the given
1945      * type. The result is a shared instance.
1946      *
1947      * @param type {@code non-null;} type of the field in question
1948      * @return {@code non-null;} an appropriate instance
1949      */
opGetStatic(TypeBearer type)1950     public static Rop opGetStatic(TypeBearer type) {
1951         switch (type.getBasicType()) {
1952             case Type.BT_INT:     return GET_STATIC_INT;
1953             case Type.BT_LONG:    return GET_STATIC_LONG;
1954             case Type.BT_FLOAT:   return GET_STATIC_FLOAT;
1955             case Type.BT_DOUBLE:  return GET_STATIC_DOUBLE;
1956             case Type.BT_OBJECT:  return GET_STATIC_OBJECT;
1957             case Type.BT_BOOLEAN: return GET_STATIC_BOOLEAN;
1958             case Type.BT_BYTE:    return GET_STATIC_BYTE;
1959             case Type.BT_CHAR:    return GET_STATIC_CHAR;
1960             case Type.BT_SHORT:   return GET_STATIC_SHORT;
1961         }
1962 
1963         return throwBadType(type);
1964     }
1965 
1966     /**
1967      * Returns the appropriate {@code put-static} rop for the given
1968      * type. The result is a shared instance.
1969      *
1970      * @param type {@code non-null;} type of the field in question
1971      * @return {@code non-null;} an appropriate instance
1972      */
opPutStatic(TypeBearer type)1973     public static Rop opPutStatic(TypeBearer type) {
1974         switch (type.getBasicType()) {
1975             case Type.BT_INT:     return PUT_STATIC_INT;
1976             case Type.BT_LONG:    return PUT_STATIC_LONG;
1977             case Type.BT_FLOAT:   return PUT_STATIC_FLOAT;
1978             case Type.BT_DOUBLE:  return PUT_STATIC_DOUBLE;
1979             case Type.BT_OBJECT:  return PUT_STATIC_OBJECT;
1980             case Type.BT_BOOLEAN: return PUT_STATIC_BOOLEAN;
1981             case Type.BT_BYTE:    return PUT_STATIC_BYTE;
1982             case Type.BT_CHAR:    return PUT_STATIC_CHAR;
1983             case Type.BT_SHORT:   return PUT_STATIC_SHORT;
1984         }
1985 
1986         return throwBadType(type);
1987     }
1988 
1989     /**
1990      * Returns the appropriate {@code invoke-static} rop for the
1991      * given type. The result is typically a newly-allocated instance.
1992      *
1993      * @param meth {@code non-null;} descriptor of the method
1994      * @return {@code non-null;} an appropriate instance
1995      */
opInvokeStatic(Prototype meth)1996     public static Rop opInvokeStatic(Prototype meth) {
1997         return new Rop(RegOps.INVOKE_STATIC,
1998                        meth.getParameterFrameTypes(),
1999                        StdTypeList.THROWABLE);
2000     }
2001 
2002     /**
2003      * Returns the appropriate {@code invoke-virtual} rop for the
2004      * given type. The result is typically a newly-allocated instance.
2005      *
2006      * @param meth {@code non-null;} descriptor of the method, including the
2007      * {@code this} parameter
2008      * @return {@code non-null;} an appropriate instance
2009      */
opInvokeVirtual(Prototype meth)2010     public static Rop opInvokeVirtual(Prototype meth) {
2011         return new Rop(RegOps.INVOKE_VIRTUAL,
2012                        meth.getParameterFrameTypes(),
2013                        StdTypeList.THROWABLE);
2014     }
2015 
2016     /**
2017      * Returns the appropriate {@code invoke-super} rop for the
2018      * given type. The result is typically a newly-allocated instance.
2019      *
2020      * @param meth {@code non-null;} descriptor of the method, including the
2021      * {@code this} parameter
2022      * @return {@code non-null;} an appropriate instance
2023      */
opInvokeSuper(Prototype meth)2024     public static Rop opInvokeSuper(Prototype meth) {
2025         return new Rop(RegOps.INVOKE_SUPER,
2026                        meth.getParameterFrameTypes(),
2027                        StdTypeList.THROWABLE);
2028     }
2029 
2030     /**
2031      * Returns the appropriate {@code invoke-direct} rop for the
2032      * given type. The result is typically a newly-allocated instance.
2033      *
2034      * @param meth {@code non-null;} descriptor of the method, including the
2035      * {@code this} parameter
2036      * @return {@code non-null;} an appropriate instance
2037      */
opInvokeDirect(Prototype meth)2038     public static Rop opInvokeDirect(Prototype meth) {
2039         return new Rop(RegOps.INVOKE_DIRECT,
2040                        meth.getParameterFrameTypes(),
2041                        StdTypeList.THROWABLE);
2042     }
2043 
2044     /**
2045      * Returns the appropriate {@code invoke-interface} rop for the
2046      * given type. The result is typically a newly-allocated instance.
2047      *
2048      * @param meth {@code non-null;} descriptor of the method, including the
2049      * {@code this} parameter
2050      * @return {@code non-null;} an appropriate instance
2051      */
opInvokeInterface(Prototype meth)2052     public static Rop opInvokeInterface(Prototype meth) {
2053         return new Rop(RegOps.INVOKE_INTERFACE,
2054                        meth.getParameterFrameTypes(),
2055                        StdTypeList.THROWABLE);
2056     }
2057 
2058     /**
2059      * Returns the appropriate {@code invoke-polymorphic} rop for the
2060      * given type. The result is typically a newly-allocated instance.
2061      *
2062      * @param meth {@code non-null;} descriptor of the method, including the
2063      * {@code this} parameter
2064      * @return {@code non-null;} an appropriate instance
2065      */
opInvokePolymorphic(Prototype meth)2066     public static Rop opInvokePolymorphic(Prototype meth) {
2067         return new Rop(RegOps.INVOKE_POLYMORPHIC,
2068                        meth.getParameterFrameTypes(),
2069                        StdTypeList.THROWABLE);
2070     }
2071 
2072     /**
2073      * Returns the appropriate {@code invoke-dynamic} rop for the
2074      * given type. The result is typically a newly-allocated instance.
2075      *
2076      * @param meth {@code non-null;} descriptor of the method, including the
2077      * {@code this} parameter
2078      * @return {@code non-null;} an appropriate instance
2079      */
opInvokeCustom(Prototype meth)2080     private static Rop opInvokeCustom(Prototype meth) {
2081         return new Rop(RegOps.INVOKE_CUSTOM,
2082                        meth.getParameterFrameTypes(),
2083                        StdTypeList.THROWABLE);
2084     }
2085 
2086     /**
2087      * Returns the appropriate {@code mark-local} rop for the given type.
2088      * The result is a shared instance.
2089      *
2090      * @param type {@code non-null;} type of value being marked
2091      * @return {@code non-null;} an appropriate instance
2092      */
opMarkLocal(TypeBearer type)2093     public static Rop opMarkLocal(TypeBearer type) {
2094         switch (type.getBasicFrameType()) {
2095             case Type.BT_INT:    return MARK_LOCAL_INT;
2096             case Type.BT_LONG:   return MARK_LOCAL_LONG;
2097             case Type.BT_FLOAT:  return MARK_LOCAL_FLOAT;
2098             case Type.BT_DOUBLE: return MARK_LOCAL_DOUBLE;
2099             case Type.BT_OBJECT: return MARK_LOCAL_OBJECT;
2100         }
2101 
2102         return throwBadType(type);
2103     }
2104 
2105     /**
2106      * This class is uninstantiable.
2107      */
Rops()2108     private Rops() {
2109         // This space intentionally left blank.
2110     }
2111 
2112     /**
2113      * Throws the right exception to complain about a bogus type.
2114      *
2115      * @param type {@code non-null;} the bad type
2116      * @return never
2117      */
throwBadType(TypeBearer type)2118     private static Rop throwBadType(TypeBearer type) {
2119         throw new IllegalArgumentException("bad type: " + type);
2120     }
2121 
2122     /**
2123      * Throws the right exception to complain about a bogus list of types.
2124      *
2125      * @param types {@code non-null;} the bad types
2126      * @return never
2127      */
throwBadTypes(TypeList types)2128     private static Rop throwBadTypes(TypeList types) {
2129         throw new IllegalArgumentException("bad types: " + types);
2130     }
2131 }
2132