1/*
2 * Copyright (C) 2012 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
18/*! \file Lower.cpp
19    \brief This file implements the high-level wrapper for lowering
20
21*/
22
23//#include "uthash.h"
24#include "libdex/DexOpcodes.h"
25#include "libdex/DexFile.h"
26#include <math.h>
27#include <sys/mman.h>
28#include "Translator.h"
29#include "Lower.h"
30#include "enc_wrapper.h"
31#include "vm/mterp/Mterp.h"
32#include "NcgHelper.h"
33#include "libdex/DexCatch.h"
34#include "compiler/CompilerIR.h"
35
36//statistics for optimization
37int num_removed_nullCheck;
38
39PhysicalReg scratchRegs[4];
40
41LowOp* ops[BUFFER_SIZE];
42LowOp* op;
43u2* rPC; //PC pointer to bytecode
44u2 inst; //current bytecode
45int offsetPC/*offset in bytecode*/, offsetNCG/*byte offset in native code*/;
46int ncg_rPC;
47//! map from PC in bytecode to PC in native code
48int mapFromBCtoNCG[BYTECODE_SIZE_PER_METHOD]; //initially mapped to -1
49char* streamStart = NULL; //start of the Pure CodeItem?, not include the global symbols
50char* streamCode = NULL; //start of the Pure CodeItem?, not include the global symbols
51char* streamMethodStart; //start of the method
52char* stream; //current stream pointer
53int lowOpTimeStamp = 0;
54Method* currentMethod = NULL;
55int currentExceptionBlockIdx = -1;
56LowOpBlockLabel* traceLabelList = NULL;
57BasicBlock* traceCurrentBB = NULL;
58MIR* traceCurrentMIR = NULL;
59bool scheduling_is_on = false;
60
61int common_invokeMethodNoRange();
62int common_invokeMethodRange();
63int common_invokeArgsDone(ArgsDoneType, bool);
64
65//data section of .ia32:
66char globalData[128];
67
68char strClassCastException[] = "Ljava/lang/ClassCastException;";
69char strInstantiationError[] = "Ljava/lang/InstantiationError;";
70char strInternalError[] = "Ljava/lang/InternalError;";
71char strFilledNewArrayNotImpl[] = "filled-new-array only implemented for 'int'";
72char strArithmeticException[] = "Ljava/lang/ArithmeticException;";
73char strArrayIndexException[] = "Ljava/lang/ArrayIndexOutOfBoundsException;";
74char strArrayStoreException[] = "Ljava/lang/ArrayStoreException;";
75char strDivideByZero[] = "divide by zero";
76char strNegativeArraySizeException[] = "Ljava/lang/NegativeArraySizeException;";
77char strNoSuchMethodError[] = "Ljava/lang/NoSuchMethodError;";
78char strNullPointerException[] = "Ljava/lang/NullPointerException;";
79char strStringIndexOutOfBoundsException[] = "Ljava/lang/StringIndexOutOfBoundsException;";
80
81int LstrClassCastExceptionPtr, LstrInstantiationErrorPtr, LstrInternalError, LstrFilledNewArrayNotImpl;
82int LstrArithmeticException, LstrArrayIndexException, LstrArrayStoreException, LstrStringIndexOutOfBoundsException;
83int LstrDivideByZero, LstrNegativeArraySizeException, LstrNoSuchMethodError, LstrNullPointerException;
84int LdoubNeg, LvaluePosInfLong, LvalueNegInfLong, LvalueNanLong, LshiftMask, Lvalue64, L64bits, LintMax, LintMin;
85
86void initConstDataSec() {
87    char* tmpPtr = globalData;
88
89    LdoubNeg = (int)tmpPtr;
90    *((u4*)tmpPtr) = 0x00000000;
91    tmpPtr += sizeof(u4);
92    *((u4*)tmpPtr) = 0x80000000;
93    tmpPtr += sizeof(u4);
94
95    LvaluePosInfLong = (int)tmpPtr;
96    *((u4*)tmpPtr) = 0xFFFFFFFF;
97    tmpPtr += sizeof(u4);
98    *((u4*)tmpPtr) = 0x7FFFFFFF;
99    tmpPtr += sizeof(u4);
100
101    LvalueNegInfLong = (int)tmpPtr;
102    *((u4*)tmpPtr) = 0x00000000;
103    tmpPtr += sizeof(u4);
104    *((u4*)tmpPtr) = 0x80000000;
105    tmpPtr += sizeof(u4);
106
107    LvalueNanLong = (int)tmpPtr;
108    *((u4*)tmpPtr) = 0;
109    tmpPtr += sizeof(u4);
110    *((u4*)tmpPtr) = 0;
111    tmpPtr += sizeof(u4);
112
113    LshiftMask = (int)tmpPtr;
114    *((u4*)tmpPtr) = 0x3f;
115    tmpPtr += sizeof(u4);
116    *((u4*)tmpPtr) = 0;
117    tmpPtr += sizeof(u4);
118
119    Lvalue64 = (int)tmpPtr;
120    *((u4*)tmpPtr) = 0x40;
121    tmpPtr += sizeof(u4);
122    *((u4*)tmpPtr) = 0;
123    tmpPtr += sizeof(u4);
124
125    L64bits = (int)tmpPtr;
126    *((u4*)tmpPtr) = 0xFFFFFFFF;
127    tmpPtr += sizeof(u4);
128    *((u4*)tmpPtr) = 0xFFFFFFFF;
129    tmpPtr += sizeof(u4);
130
131    LintMin = (int)tmpPtr;
132    *((u4*)tmpPtr) = 0x80000000;
133    tmpPtr += sizeof(u4);
134
135    LintMax = (int)tmpPtr;
136    *((u4*)tmpPtr) = 0x7FFFFFFF;
137    tmpPtr += sizeof(u4);
138
139    LstrClassCastExceptionPtr = (int)strClassCastException;
140    LstrInstantiationErrorPtr = (int)strInstantiationError;
141    LstrInternalError = (int)strInternalError;
142    LstrFilledNewArrayNotImpl = (int)strFilledNewArrayNotImpl;
143    LstrArithmeticException = (int)strArithmeticException;
144    LstrArrayIndexException = (int)strArrayIndexException;
145    LstrArrayStoreException = (int)strArrayStoreException;
146    LstrDivideByZero = (int)strDivideByZero;
147    LstrNegativeArraySizeException = (int)strNegativeArraySizeException;
148    LstrNoSuchMethodError = (int)strNoSuchMethodError;
149    LstrNullPointerException = (int)strNullPointerException;
150    LstrStringIndexOutOfBoundsException = (int)strStringIndexOutOfBoundsException;
151}
152
153//declarations of functions used in this file
154int spill_reg(int reg, bool isPhysical);
155int unspill_reg(int reg, bool isPhysical);
156
157int const_string_resolve();
158int sget_sput_resolve();
159int new_instance_needinit();
160int new_instance_abstract();
161int invoke_virtual_resolve();
162int invoke_direct_resolve();
163int invoke_static_resolve();
164int filled_new_array_notimpl();
165int resolve_class2(
166                   int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
167                   bool indexPhysical,
168                   int thirdArg);
169int resolve_method2(
170                    int startLR/*logical register index*/, bool isPhysical, int indexReg/*const pool index*/,
171                    bool indexPhysical,
172                    int thirdArg/*VIRTUAL*/);
173int resolve_inst_field2(
174                        int startLR/*logical register index*/, bool isPhysical,
175                        int indexReg/*const pool index*/,
176                        bool indexPhysical);
177int resolve_static_field2(
178                          int startLR/*logical register index*/, bool isPhysical,
179                          int indexReg/*const pool index*/,
180                          bool indexPhysical);
181
182int invokeMethodNoRange_1_helper();
183int invokeMethodNoRange_2_helper();
184int invokeMethodNoRange_3_helper();
185int invokeMethodNoRange_4_helper();
186int invokeMethodNoRange_5_helper();
187int invokeMethodRange_helper();
188
189int invoke_virtual_helper();
190int invoke_virtual_quick_helper();
191int invoke_static_helper();
192int invoke_direct_helper();
193int new_instance_helper();
194int sget_sput_helper(int flag);
195int aput_obj_helper();
196int aget_helper(int flag);
197int aput_helper(int flag);
198int monitor_enter_helper();
199int monitor_exit_helper();
200int throw_helper();
201int const_string_helper();
202int array_length_helper();
203int invoke_super_helper();
204int invoke_interface_helper();
205int iget_iput_helper(int flag);
206int check_cast_helper(bool instance);
207int new_array_helper();
208
209int common_returnFromMethod();
210
211/*!
212\brief dump helper functions
213
214*/
215int performCGWorklist() {
216    filled_new_array_notimpl();
217    freeShortMap();
218    const_string_resolve();
219    freeShortMap();
220
221    resolve_class2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, 0);
222    freeShortMap();
223    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_VIRTUAL);
224    freeShortMap();
225    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_DIRECT);
226    freeShortMap();
227    resolve_method2(PhysicalReg_EAX, true, PhysicalReg_EAX, true, METHOD_STATIC);
228    freeShortMap();
229    resolve_inst_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
230    freeShortMap();
231    resolve_static_field2(PhysicalReg_EAX, true, PhysicalReg_EAX, true);
232    freeShortMap();
233    throw_exception_message(PhysicalReg_ECX, PhysicalReg_EAX, true, PhysicalReg_Null, true);
234    freeShortMap();
235    throw_exception(PhysicalReg_ECX, PhysicalReg_EAX, PhysicalReg_Null, true);
236    freeShortMap();
237    new_instance_needinit();
238    freeShortMap();
239    return 0;
240}
241
242int aput_object_count;
243int common_periodicChecks_entry();
244int common_periodicChecks4();
245/*!
246\brief for debugging purpose, dump the sequence of native code for each bytecode
247
248*/
249int ncgMethodFake(Method* method) {
250    //to measure code size expansion, no need to patch up labels
251    methodDataWorklist = NULL;
252    globalShortWorklist = NULL;
253    globalNCGWorklist = NULL;
254    streamMethodStart = stream;
255
256    //initialize mapFromBCtoNCG
257    memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
258    unsigned int i;
259    u2* rStart = (u2*)malloc(5*sizeof(u2));
260    if(rStart == NULL) {
261        ALOGE("Memory allocation failed");
262        return -1;
263    }
264    rPC = rStart;
265    method->insns = rStart;
266    for(i = 0; i < 5; i++) *rPC++ = 0;
267    for(i = 0; i < 256; i++) {
268        rPC = rStart;
269        //modify the opcode
270        char* tmp = (char*)rStart;
271        *tmp++ = i;
272        *tmp = i;
273        inst = FETCH(0);
274        char* tmpStart = stream;
275        lowerByteCode(method); //use inst, rPC, method, modify rPC
276        int size_in_u2 = rPC - rStart;
277        if(stream - tmpStart  > 0)
278            ALOGI("LOWER bytecode %x size in u2: %d ncg size in byte: %d", i, size_in_u2, stream - tmpStart);
279    }
280    exit(0);
281}
282
283bool existATryBlock(Method* method, int startPC, int endPC) {
284    const DexCode* pCode = dvmGetMethodCode(method);
285    u4 triesSize = pCode->triesSize;
286    const DexTry* pTries = dexGetTries(pCode);
287    unsigned int i;
288    for (i = 0; i < triesSize; i++) {
289        const DexTry* pTry = &pTries[i];
290        u4 start = pTry->startAddr; //offsetPC
291        u4 end = start + pTry->insnCount;
292        //if [start, end] overlaps with [startPC, endPC] returns true
293        if((int)end < startPC || (int)start > endPC) { //no overlap
294        } else {
295            return true;
296        }
297    }
298    return false;
299}
300
301int mm_bytecode_size = 0;
302int mm_ncg_size = 0;
303int mm_relocation_size = 0;
304int mm_map_size = 0;
305void resetCodeSize() {
306    mm_bytecode_size = 0;
307    mm_ncg_size = 0;
308    mm_relocation_size = 0;
309    mm_map_size = 0;
310}
311
312bool bytecodeIsRemoved(const Method* method, u4 bytecodeOffset) {
313    if(gDvm.executionMode == kExecutionModeNcgO0) return false;
314    u4 ncgOff = mapFromBCtoNCG[bytecodeOffset];
315    int k = bytecodeOffset+1;
316    u2 insnsSize = dvmGetMethodInsnsSize(method);
317    while(k < insnsSize) {
318        if(mapFromBCtoNCG[k] < 0) {
319            k++;
320            continue;
321        }
322        if(mapFromBCtoNCG[k] == (int)ncgOff) return true;
323        return false;
324    }
325    return false;
326}
327
328int invoke_super_nsm();
329void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG); //forward declaration
330void initGlobalMethods(); //forward declaration
331
332//called once when compiler thread starts up
333void initJIT(const char* curFileName, DvmDex *pDvmDex) {
334    init_common(curFileName, pDvmDex, false);
335}
336
337void init_common(const char* curFileName, DvmDex *pDvmDex, bool forNCG) {
338    if(!gDvm.constInit) {
339        globalMapNum = 0;
340        globalMap = NULL;
341        initConstDataSec();
342        gDvm.constInit = true;
343    }
344
345    //for initJIT: stream is already set
346    if(!gDvm.commonInit) {
347        initGlobalMethods();
348        gDvm.commonInit = true;
349    }
350}
351
352void initGlobalMethods() {
353    dump_x86_inst = false; /* DEBUG */
354    // generate native code for function ncgGetEIP
355    insertLabel("ncgGetEIP", false);
356    move_mem_to_reg(OpndSize_32, 0, PhysicalReg_ESP, true, PhysicalReg_EDX, true);
357    x86_return();
358
359    //generate code for common labels
360    //jumps within a helper function is treated as short labels
361    globalShortMap = NULL;
362    common_periodicChecks_entry();
363    freeShortMap();
364    common_periodicChecks4();
365    freeShortMap();
366    //common_invokeMethodNoRange();
367    //common_invokeMethodRange();
368
369    if(dump_x86_inst) ALOGI("ArgsDone_Normal start");
370    common_invokeArgsDone(ArgsDone_Normal, false);
371    freeShortMap();
372    if(dump_x86_inst) ALOGI("ArgsDone_Native start");
373    common_invokeArgsDone(ArgsDone_Native, false);
374    freeShortMap();
375    if(dump_x86_inst) ALOGI("ArgsDone_Full start");
376    common_invokeArgsDone(ArgsDone_Full, true/*isJitFull*/);
377    if(dump_x86_inst) ALOGI("ArgsDone_Full end");
378    freeShortMap();
379
380    common_backwardBranch();
381    freeShortMap();
382    common_exceptionThrown();
383    freeShortMap();
384    common_errNullObject();
385    freeShortMap();
386    common_errArrayIndex();
387    freeShortMap();
388    common_errArrayStore();
389    freeShortMap();
390    common_errNegArraySize();
391    freeShortMap();
392    common_errNoSuchMethod();
393    freeShortMap();
394    common_errDivideByZero();
395    freeShortMap();
396    common_gotoBail();
397    freeShortMap();
398    common_gotoBail_0();
399    freeShortMap();
400    invoke_super_nsm();
401    freeShortMap();
402
403    performCGWorklist(); //generate code for helper functions
404    performLabelWorklist(); //it is likely that the common labels will jump to other common labels
405
406    dump_x86_inst = false;
407}
408
409ExecutionMode origMode;
410//when to update streamMethodStart
411bool lowerByteCodeJit(const Method* method, const u2* codePtr, MIR* mir) {
412    rPC = (u2*)codePtr;
413    inst = FETCH(0);
414    traceCurrentMIR = mir;
415    int retCode = lowerByteCode(method);
416    traceCurrentMIR = NULL;
417    freeShortMap();
418    if(retCode >= 0) return false; //handled
419    return true; //not handled
420}
421
422void startOfBasicBlock(BasicBlock* bb) {
423    traceCurrentBB = bb;
424    if(gDvm.executionMode == kExecutionModeNcgO0) {
425        isScratchPhysical = true;
426    } else {
427        isScratchPhysical = false;
428    }
429}
430
431void startOfTrace(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId,
432                  CompilationUnit *cUnit) {
433    origMode = gDvm.executionMode;
434    gDvm.executionMode = kExecutionModeNcgO1;
435    if(gDvm.executionMode == kExecutionModeNcgO0) {
436        isScratchPhysical = true;
437    } else {
438        isScratchPhysical = false;
439    }
440    currentMethod = (Method*)method;
441    currentExceptionBlockIdx = exceptionBlockId;
442    methodDataWorklist = NULL;
443    globalShortWorklist = NULL;
444    globalNCGWorklist = NULL;
445
446    streamMethodStart = stream;
447    //initialize mapFromBCtoNCG
448    memset(&mapFromBCtoNCG[0], -1, BYTECODE_SIZE_PER_METHOD * sizeof(mapFromBCtoNCG[0]));
449    traceLabelList = labelList;
450    if(gDvm.executionMode == kExecutionModeNcgO1)
451        startOfTraceO1(method, labelList, exceptionBlockId, cUnit);
452}
453
454void endOfTrace(bool freeOnly) {
455    if(freeOnly) {
456        freeLabelWorklist();
457        freeNCGWorklist();
458        freeDataWorklist();
459        freeChainingWorklist();
460    }
461    else {
462        performLabelWorklist();
463        performNCGWorklist(); //handle forward jump (GOTO, IF)
464        performDataWorklist(); //handle SWITCH & FILL_ARRAY_DATA
465        performChainingWorklist();
466    }
467    if(gDvm.executionMode == kExecutionModeNcgO1) {
468        endOfTraceO1();
469    }
470    gDvm.executionMode = origMode;
471}
472
473///////////////////////////////////////////////////////////////////
474//!
475//! each bytecode is translated to a sequence of machine codes
476int lowerByteCode(const Method* method) { //inputs: rPC & inst & stream & streamMethodStart
477    /* offsetPC is used in O1 code generator, where it is defined as the sequence number
478       use a local version to avoid overwriting */
479    int offsetPC = rPC - (u2*)method->insns;
480
481    if(dump_x86_inst)
482        ALOGI("LOWER bytecode %x at offsetPC %x offsetNCG %x @%p",
483              INST_INST(inst), offsetPC, stream - streamMethodStart, stream);
484
485    //update mapFromBCtoNCG
486    offsetNCG = stream - streamMethodStart;
487    if(offsetPC >= BYTECODE_SIZE_PER_METHOD) ALOGE("offsetPC %d exceeds BYTECODE_SIZE_PER_METHOD", offsetPC);
488    mapFromBCtoNCG[offsetPC] = offsetNCG;
489#if defined(ENABLE_TRACING) && defined(TRACING_OPTION2)
490    insertMapWorklist(offsetPC, mapFromBCtoNCG[offsetPC], 1);
491#endif
492    //return number of LowOps generated
493    switch (INST_INST(inst)) {
494    case OP_NOP:
495        return op_nop();
496    case OP_MOVE:
497    case OP_MOVE_OBJECT:
498        return op_move();
499    case OP_MOVE_FROM16:
500    case OP_MOVE_OBJECT_FROM16:
501        return op_move_from16();
502    case OP_MOVE_16:
503    case OP_MOVE_OBJECT_16:
504        return op_move_16();
505    case OP_MOVE_WIDE:
506        return op_move_wide();
507    case OP_MOVE_WIDE_FROM16:
508        return op_move_wide_from16();
509    case OP_MOVE_WIDE_16:
510        return op_move_wide_16();
511    case OP_MOVE_RESULT:
512    case OP_MOVE_RESULT_OBJECT:
513        return op_move_result();
514    case OP_MOVE_RESULT_WIDE:
515        return op_move_result_wide();
516    case OP_MOVE_EXCEPTION:
517        return op_move_exception();
518    case OP_RETURN_VOID:
519    case OP_RETURN_VOID_BARRIER:
520        return op_return_void();
521    case OP_RETURN:
522    case OP_RETURN_OBJECT:
523        return op_return();
524    case OP_RETURN_WIDE:
525        return op_return_wide();
526    case OP_CONST_4:
527        return op_const_4();
528    case OP_CONST_16:
529        return op_const_16();
530    case OP_CONST:
531        return op_const();
532    case OP_CONST_HIGH16:
533        return op_const_high16();
534    case OP_CONST_WIDE_16:
535        return op_const_wide_16();
536    case OP_CONST_WIDE_32:
537        return op_const_wide_32();
538    case OP_CONST_WIDE:
539        return op_const_wide();
540    case OP_CONST_WIDE_HIGH16:
541        return op_const_wide_high16();
542    case OP_CONST_STRING:
543        return op_const_string();
544    case OP_CONST_STRING_JUMBO:
545        return op_const_string_jumbo();
546    case OP_CONST_CLASS:
547        return op_const_class();
548    case OP_MONITOR_ENTER:
549        return op_monitor_enter();
550    case OP_MONITOR_EXIT:
551        return op_monitor_exit();
552    case OP_CHECK_CAST:
553        return op_check_cast();
554    case OP_INSTANCE_OF:
555        return op_instance_of();
556    case OP_ARRAY_LENGTH:
557        return op_array_length();
558    case OP_NEW_INSTANCE:
559        return op_new_instance();
560    case OP_NEW_ARRAY:
561        return op_new_array();
562    case OP_FILLED_NEW_ARRAY:
563        return op_filled_new_array();
564    case OP_FILLED_NEW_ARRAY_RANGE:
565        return op_filled_new_array_range();
566    case OP_FILL_ARRAY_DATA:
567        return op_fill_array_data();
568    case OP_THROW:
569        return op_throw();
570    case OP_THROW_VERIFICATION_ERROR:
571        return op_throw_verification_error();
572    case OP_GOTO:
573        return op_goto();
574    case OP_GOTO_16:
575        return op_goto_16();
576    case OP_GOTO_32:
577        return op_goto_32();
578    case OP_PACKED_SWITCH:
579        return op_packed_switch();
580    case OP_SPARSE_SWITCH:
581        return op_sparse_switch();
582    case OP_CMPL_FLOAT:
583        return op_cmpl_float();
584    case OP_CMPG_FLOAT:
585        return op_cmpg_float();
586    case OP_CMPL_DOUBLE:
587        return op_cmpl_double();
588    case OP_CMPG_DOUBLE:
589        return op_cmpg_double();
590    case OP_CMP_LONG:
591        return op_cmp_long();
592    case OP_IF_EQ:
593        return op_if_eq();
594    case OP_IF_NE:
595        return op_if_ne();
596    case OP_IF_LT:
597        return op_if_lt();
598    case OP_IF_GE:
599        return op_if_ge();
600    case OP_IF_GT:
601        return op_if_gt();
602    case OP_IF_LE:
603        return op_if_le();
604    case OP_IF_EQZ:
605        return op_if_eqz();
606    case OP_IF_NEZ:
607        return op_if_nez();
608    case OP_IF_LTZ:
609        return op_if_ltz();
610    case OP_IF_GEZ:
611        return op_if_gez();
612    case OP_IF_GTZ:
613        return op_if_gtz();
614    case OP_IF_LEZ:
615        return op_if_lez();
616    case OP_AGET:
617        return op_aget();
618    case OP_AGET_WIDE:
619        return op_aget_wide();
620    case OP_AGET_OBJECT:
621        return op_aget_object();
622    case OP_AGET_BOOLEAN:
623        return op_aget_boolean();
624    case OP_AGET_BYTE:
625        return op_aget_byte();
626    case OP_AGET_CHAR:
627        return op_aget_char();
628    case OP_AGET_SHORT:
629        return op_aget_short();
630    case OP_APUT:
631        return op_aput();
632    case OP_APUT_WIDE:
633        return op_aput_wide();
634    case OP_APUT_OBJECT:
635        return op_aput_object();
636    case OP_APUT_BOOLEAN:
637        return op_aput_boolean();
638    case OP_APUT_BYTE:
639        return op_aput_byte();
640    case OP_APUT_CHAR:
641        return op_aput_char();
642    case OP_APUT_SHORT:
643        return op_aput_short();
644    case OP_IGET:
645    case OP_IGET_VOLATILE:
646        return op_iget();
647    case OP_IGET_WIDE:
648        return op_iget_wide(false); // isVolatile==false
649    case OP_IGET_WIDE_VOLATILE:
650        return op_iget_wide(true);  // isVolatile==true
651    case OP_IGET_OBJECT:
652    case OP_IGET_OBJECT_VOLATILE:
653        return op_iget_object();
654    case OP_IGET_BOOLEAN:
655        return op_iget_boolean();
656    case OP_IGET_BYTE:
657        return op_iget_byte();
658    case OP_IGET_CHAR:
659        return op_iget_char();
660    case OP_IGET_SHORT:
661        return op_iget_short();
662    case OP_IPUT:
663    case OP_IPUT_VOLATILE:
664        return op_iput();
665    case OP_IPUT_WIDE:
666        return op_iput_wide(false); // isVolatile==false
667    case OP_IPUT_WIDE_VOLATILE:
668        return op_iput_wide(true);  // isVolatile==true
669    case OP_IPUT_OBJECT:
670    case OP_IPUT_OBJECT_VOLATILE:
671        return op_iput_object();
672    case OP_IPUT_BOOLEAN:
673        return op_iput_boolean();
674    case OP_IPUT_BYTE:
675        return op_iput_byte();
676    case OP_IPUT_CHAR:
677        return op_iput_char();
678    case OP_IPUT_SHORT:
679        return op_iput_short();
680    case OP_SGET:
681    case OP_SGET_VOLATILE:
682        return op_sget();
683    case OP_SGET_WIDE:
684        return op_sget_wide(false); // isVolatile==false
685    case OP_SGET_WIDE_VOLATILE:
686        return op_sget_wide(true);  // isVolatile==true
687    case OP_SGET_OBJECT:
688    case OP_SGET_OBJECT_VOLATILE:
689        return op_sget_object();
690    case OP_SGET_BOOLEAN:
691        return op_sget_boolean();
692    case OP_SGET_BYTE:
693        return op_sget_byte();
694    case OP_SGET_CHAR:
695        return op_sget_char();
696    case OP_SGET_SHORT:
697        return op_sget_short();
698    case OP_SPUT:
699    case OP_SPUT_VOLATILE:
700        return op_sput(false);
701    case OP_SPUT_WIDE:
702        return op_sput_wide(false); // isVolatile==false
703    case OP_SPUT_WIDE_VOLATILE:
704        return op_sput_wide(true);  // isVolatile==true
705    case OP_SPUT_OBJECT:
706    case OP_SPUT_OBJECT_VOLATILE:
707        return op_sput_object();
708    case OP_SPUT_BOOLEAN:
709        return op_sput_boolean();
710    case OP_SPUT_BYTE:
711        return op_sput_byte();
712    case OP_SPUT_CHAR:
713        return op_sput_char();
714    case OP_SPUT_SHORT:
715        return op_sput_short();
716    case OP_INVOKE_VIRTUAL:
717        return op_invoke_virtual();
718    case OP_INVOKE_SUPER:
719        return op_invoke_super();
720    case OP_INVOKE_DIRECT:
721        return op_invoke_direct();
722    case OP_INVOKE_STATIC:
723        return op_invoke_static();
724    case OP_INVOKE_INTERFACE:
725        return op_invoke_interface();
726    case OP_INVOKE_VIRTUAL_RANGE:
727        return op_invoke_virtual_range();
728    case OP_INVOKE_SUPER_RANGE:
729        return op_invoke_super_range();
730    case OP_INVOKE_DIRECT_RANGE:
731        return op_invoke_direct_range();
732    case OP_INVOKE_STATIC_RANGE:
733        return op_invoke_static_range();
734    case OP_INVOKE_INTERFACE_RANGE:
735        return op_invoke_interface_range();
736    case OP_NEG_INT:
737        return op_neg_int();
738    case OP_NOT_INT:
739        return op_not_int();
740    case OP_NEG_LONG:
741        return op_neg_long();
742    case OP_NOT_LONG:
743        return op_not_long();
744    case OP_NEG_FLOAT:
745        return op_neg_float();
746    case OP_NEG_DOUBLE:
747        return op_neg_double();
748    case OP_INT_TO_LONG:
749        return op_int_to_long();
750    case OP_INT_TO_FLOAT:
751        return op_int_to_float();
752    case OP_INT_TO_DOUBLE:
753        return op_int_to_double();
754    case OP_LONG_TO_INT:
755        return op_long_to_int();
756    case OP_LONG_TO_FLOAT:
757        return op_long_to_float();
758    case OP_LONG_TO_DOUBLE:
759        return op_long_to_double();
760    case OP_FLOAT_TO_INT:
761        return op_float_to_int();
762    case OP_FLOAT_TO_LONG:
763        return op_float_to_long();
764    case OP_FLOAT_TO_DOUBLE:
765        return op_float_to_double();
766    case OP_DOUBLE_TO_INT:
767        return op_double_to_int();
768    case OP_DOUBLE_TO_LONG:
769        return op_double_to_long();
770    case OP_DOUBLE_TO_FLOAT:
771        return op_double_to_float();
772    case OP_INT_TO_BYTE:
773        return op_int_to_byte();
774    case OP_INT_TO_CHAR:
775        return op_int_to_char();
776    case OP_INT_TO_SHORT:
777        return op_int_to_short();
778    case OP_ADD_INT:
779        return op_add_int();
780    case OP_SUB_INT:
781        return op_sub_int();
782    case OP_MUL_INT:
783        return op_mul_int();
784    case OP_DIV_INT:
785        return op_div_int();
786    case OP_REM_INT:
787        return op_rem_int();
788    case OP_AND_INT:
789        return op_and_int();
790    case OP_OR_INT:
791        return op_or_int();
792    case OP_XOR_INT:
793        return op_xor_int();
794    case OP_SHL_INT:
795        return op_shl_int();
796    case OP_SHR_INT:
797        return op_shr_int();
798    case OP_USHR_INT:
799        return op_ushr_int();
800    case OP_ADD_LONG:
801        return op_add_long();
802    case OP_SUB_LONG:
803        return op_sub_long();
804    case OP_MUL_LONG:
805        return op_mul_long();
806    case OP_DIV_LONG:
807        return op_div_long();
808    case OP_REM_LONG:
809        return op_rem_long();
810    case OP_AND_LONG:
811        return op_and_long();
812    case OP_OR_LONG:
813        return op_or_long();
814    case OP_XOR_LONG:
815        return op_xor_long();
816    case OP_SHL_LONG:
817        return op_shl_long();
818    case OP_SHR_LONG:
819        return op_shr_long();
820    case OP_USHR_LONG:
821        return op_ushr_long();
822    case OP_ADD_FLOAT:
823        return op_add_float();
824    case OP_SUB_FLOAT:
825        return op_sub_float();
826    case OP_MUL_FLOAT:
827        return op_mul_float();
828    case OP_DIV_FLOAT:
829        return op_div_float();
830    case OP_REM_FLOAT:
831        return op_rem_float();
832    case OP_ADD_DOUBLE:
833        return op_add_double();
834    case OP_SUB_DOUBLE:
835        return op_sub_double();
836    case OP_MUL_DOUBLE:
837        return op_mul_double();
838    case OP_DIV_DOUBLE:
839        return op_div_double();
840    case OP_REM_DOUBLE:
841        return op_rem_double();
842    case OP_ADD_INT_2ADDR:
843        return op_add_int_2addr();
844    case OP_SUB_INT_2ADDR:
845        return op_sub_int_2addr();
846    case OP_MUL_INT_2ADDR:
847        return op_mul_int_2addr();
848    case OP_DIV_INT_2ADDR:
849        return op_div_int_2addr();
850    case OP_REM_INT_2ADDR:
851        return op_rem_int_2addr();
852    case OP_AND_INT_2ADDR:
853        return op_and_int_2addr();
854    case OP_OR_INT_2ADDR:
855        return op_or_int_2addr();
856    case OP_XOR_INT_2ADDR:
857        return op_xor_int_2addr();
858    case OP_SHL_INT_2ADDR:
859        return op_shl_int_2addr();
860    case OP_SHR_INT_2ADDR:
861        return op_shr_int_2addr();
862    case OP_USHR_INT_2ADDR:
863        return op_ushr_int_2addr();
864    case OP_ADD_LONG_2ADDR:
865        return op_add_long_2addr();
866    case OP_SUB_LONG_2ADDR:
867        return op_sub_long_2addr();
868    case OP_MUL_LONG_2ADDR:
869        return op_mul_long_2addr();
870    case OP_DIV_LONG_2ADDR:
871        return op_div_long_2addr();
872    case OP_REM_LONG_2ADDR:
873        return op_rem_long_2addr();
874    case OP_AND_LONG_2ADDR:
875        return op_and_long_2addr();
876    case OP_OR_LONG_2ADDR:
877        return op_or_long_2addr();
878    case OP_XOR_LONG_2ADDR:
879        return op_xor_long_2addr();
880    case OP_SHL_LONG_2ADDR:
881        return op_shl_long_2addr();
882    case OP_SHR_LONG_2ADDR:
883        return op_shr_long_2addr();
884    case OP_USHR_LONG_2ADDR:
885        return op_ushr_long_2addr();
886    case OP_ADD_FLOAT_2ADDR:
887        return op_add_float_2addr();
888    case OP_SUB_FLOAT_2ADDR:
889        return op_sub_float_2addr();
890    case OP_MUL_FLOAT_2ADDR:
891        return op_mul_float_2addr();
892    case OP_DIV_FLOAT_2ADDR:
893        return op_div_float_2addr();
894    case OP_REM_FLOAT_2ADDR:
895        return op_rem_float_2addr();
896    case OP_ADD_DOUBLE_2ADDR:
897        return op_add_double_2addr();
898    case OP_SUB_DOUBLE_2ADDR:
899        return op_sub_double_2addr();
900    case OP_MUL_DOUBLE_2ADDR:
901        return op_mul_double_2addr();
902    case OP_DIV_DOUBLE_2ADDR:
903        return op_div_double_2addr();
904    case OP_REM_DOUBLE_2ADDR:
905        return op_rem_double_2addr();
906    case OP_ADD_INT_LIT16:
907        return op_add_int_lit16();
908    case OP_RSUB_INT:
909        return op_rsub_int();
910    case OP_MUL_INT_LIT16:
911        return op_mul_int_lit16();
912    case OP_DIV_INT_LIT16:
913        return op_div_int_lit16();
914    case OP_REM_INT_LIT16:
915        return op_rem_int_lit16();
916    case OP_AND_INT_LIT16:
917        return op_and_int_lit16();
918    case OP_OR_INT_LIT16:
919        return op_or_int_lit16();
920    case OP_XOR_INT_LIT16:
921        return op_xor_int_lit16();
922    case OP_ADD_INT_LIT8:
923        return op_add_int_lit8();
924    case OP_RSUB_INT_LIT8:
925        return op_rsub_int_lit8();
926    case OP_MUL_INT_LIT8:
927        return op_mul_int_lit8();
928    case OP_DIV_INT_LIT8:
929        return op_div_int_lit8();
930    case OP_REM_INT_LIT8:
931        return op_rem_int_lit8();
932    case OP_AND_INT_LIT8:
933        return op_and_int_lit8();
934    case OP_OR_INT_LIT8:
935        return op_or_int_lit8();
936    case OP_XOR_INT_LIT8:
937        return op_xor_int_lit8();
938    case OP_SHL_INT_LIT8:
939        return op_shl_int_lit8();
940    case OP_SHR_INT_LIT8:
941        return op_shr_int_lit8();
942    case OP_USHR_INT_LIT8:
943        return op_ushr_int_lit8();
944    case OP_EXECUTE_INLINE:
945        return op_execute_inline(false);
946    case OP_EXECUTE_INLINE_RANGE:
947        return op_execute_inline(true);
948    case OP_BREAKPOINT:
949        ALOGE("found bytecode OP_BREAKPOINT");
950        dvmAbort();
951    case OP_INVOKE_OBJECT_INIT_RANGE:
952        return op_invoke_object_init_range();
953    case OP_IGET_QUICK:
954        return op_iget_quick();
955    case OP_IGET_WIDE_QUICK:
956        return op_iget_wide_quick();
957    case OP_IGET_OBJECT_QUICK:
958        return op_iget_object_quick();
959    case OP_IPUT_QUICK:
960        return op_iput_quick();
961    case OP_IPUT_WIDE_QUICK:
962        return op_iput_wide_quick();
963    case OP_IPUT_OBJECT_QUICK:
964        return op_iput_object_quick();
965    case OP_INVOKE_VIRTUAL_QUICK:
966        return op_invoke_virtual_quick();
967    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
968        return op_invoke_virtual_quick_range();
969    case OP_INVOKE_SUPER_QUICK:
970        return op_invoke_super_quick();
971    case OP_INVOKE_SUPER_QUICK_RANGE:
972        return op_invoke_super_quick_range();
973    }
974
975    ALOGE("No JIT support for bytecode %x at offsetPC %x",
976          INST_INST(inst), offsetPC);
977    return -1;
978}
979int op_nop() {
980    rPC++;
981    return 0;
982}
983