1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* forward declarations of goto targets */
2ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(filledNewArray, bool methodCallRange);
3ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeVirtual, bool methodCallRange);
4ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeSuper, bool methodCallRange);
5ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeInterface, bool methodCallRange);
6ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeDirect, bool methodCallRange);
7ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeStatic, bool methodCallRange);
8ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeVirtualQuick, bool methodCallRange);
9ab35b50311951feea3782151dd5422ee944685c2Elliott HughesGOTO_TARGET_DECL(invokeSuperQuick, bool methodCallRange);
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_DECL(invokeMethod, bool methodCallRange, const Method* methodToCall,
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2 count, u2 regs);
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_DECL(returnFromMethod);
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGOTO_TARGET_DECL(exceptionThrown);
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * What follows are opcode definitions shared between multiple opcodes with
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * minor substitutions handled by the C pre-processor.  These should probably
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use the mterp substitution mechanism instead, with the code here moved
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into common fragment files (like the asm "binop.S"), although it's hard
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to give up the C preprocessor in favor of the much simpler text subst.
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_NUMCONV(_opcode, _opname, _fromtype, _totype)                \
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_totype(vdst,                                         \
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER##_fromtype(vsrc1));                                \
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_FLOAT_TO_INT(_opcode, _opname, _fromvtype, _fromrtype,       \
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _tovtype, _tortype)                                                 \
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* spec defines specific handling for +/- inf and NaN values */     \
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _fromvtype val;                                                     \
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _tovtype intMin, intMax, result;                                    \
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        val = GET_REGISTER##_fromrtype(vsrc1);                              \
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intMin = (_tovtype) 1 << (sizeof(_tovtype) * 8 -1);                 \
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        intMax = ~intMin;                                                   \
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (_tovtype) val;                                            \
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (val >= intMax)          /* +inf */                              \
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = intMax;                                                \
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else if (val <= intMin)     /* -inf */                              \
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = intMin;                                                \
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else if (val != val)        /* NaN */                               \
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = 0;                                                     \
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else                                                                \
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = (_tovtype) val;                                        \
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_tortype(vdst, result);                               \
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(1);
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_INT_TO_SMALL(_opcode, _opname, _type)                        \
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|int-to-%s v%d,v%d", (_opname), vdst, vsrc1);                \
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER(vdst, (_type) GET_REGISTER(vsrc1));                    \
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* NOTE: the comparison result is always a signed 4-byte integer */
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_CMPX(_opcode, _opname, _varType, _type, _nanVal)          \
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int result;                                                         \
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 regs;                                                            \
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _varType val1, val2;                                                \
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        regs = FETCH(1);                                                    \
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = regs & 0xff;                                                \
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = regs >> 8;                                                  \
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|cmp%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);         \
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        val1 = GET_REGISTER##_type(vsrc1);                                  \
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        val2 = GET_REGISTER##_type(vsrc2);                                  \
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (val1 == val2)                                                   \
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = 0;                                                     \
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else if (val1 < val2)                                               \
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = -1;                                                    \
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else if (val1 > val2)                                               \
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = 1;                                                     \
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else                                                                \
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = (_nanVal);                                             \
9260fc806b679a3655c228b4093058c59941a49cfeDan Bornstein        ILOGV("+ result=%d", result);                                       \
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER(vdst, result);                                         \
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_IF_XX(_opcode, _opname, _cmp)                             \
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, +CCCC*/)                                \
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_A(inst);                                               \
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = INST_B(inst);                                               \
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((s4) GET_REGISTER(vsrc1) _cmp (s4) GET_REGISTER(vsrc2)) {       \
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int branchOffset = (s2)FETCH(1);    /* sign-extended */         \
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|if-%s v%d,v%d,+0x%04x", (_opname), vsrc1, vsrc2,        \
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                branchOffset);                                              \
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("> branch taken");                                        \
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (branchOffset < 0)                                           \
1079a3147c7412f4794434b4c2604aa2ba784867774buzbee                PERIODIC_CHECKS(branchOffset);                              \
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(branchOffset);                                           \
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|if-%s v%d,v%d,-", (_opname), vsrc1, vsrc2);             \
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(2);                                                      \
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_IF_XXZ(_opcode, _opname, _cmp)                            \
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, +BBBB*/)                                   \
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_AA(inst);                                              \
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((s4) GET_REGISTER(vsrc1) _cmp 0) {                              \
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int branchOffset = (s2)FETCH(1);    /* sign-extended */         \
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|if-%s v%d,+0x%04x", (_opname), vsrc1, branchOffset);    \
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("> branch taken");                                        \
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (branchOffset < 0)                                           \
1229a3147c7412f4794434b4c2604aa2ba784867774buzbee                PERIODIC_CHECKS(branchOffset);                              \
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(branchOffset);                                           \
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ILOGV("|if-%s v%d,-", (_opname), vsrc1);                        \
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            FINISH(2);                                                      \
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_UNOP(_opcode, _opname, _pfx, _sfx, _type)                    \
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1);                       \
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_type(vdst, _pfx GET_REGISTER##_type(vsrc1) _sfx);    \
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_INT(_opcode, _opname, _op, _chkdiv)                     \
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1);                   \
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s4 firstVal, secondVal, result;                                 \
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER(vsrc1);                                 \
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            secondVal = GET_REGISTER(vsrc2);                                \
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (secondVal == 0) {                                           \
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
152d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u4)firstVal == 0x80000000 && secondVal == -1) {            \
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op secondVal;                            \
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst, result);                                     \
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* non-div/rem case */                                          \
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst,                                              \
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (s4) GET_REGISTER(vsrc1) _op (s4) GET_REGISTER(vsrc2));     \
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_SHX_INT(_opcode, _opname, _cast, _op)                     \
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1);                   \
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER(vdst,                                                  \
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _cast GET_REGISTER(vsrc1) _op (GET_REGISTER(vsrc2) & 0x1f));    \
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_INT_LIT16(_opcode, _opname, _op, _chkdiv)               \
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, #+CCCC*/)                               \
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = FETCH(1);                                                   \
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int/lit16 v%d,v%d,#+0x%04x",                             \
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (_opname), vdst, vsrc1, vsrc2);                                 \
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s4 firstVal, result;                                            \
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER(vsrc1);                                 \
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((s2) vsrc2 == 0) {                                          \
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
198d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
199d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                GOTO_exceptionThrown();                                     \
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u4)firstVal == 0x80000000 && ((s2) vsrc2) == -1) {         \
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* won't generate /lit16 instr for this; check anyway */    \
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op (s2) vsrc2;                           \
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst, result);                                     \
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* non-div/rem case */                                          \
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst, GET_REGISTER(vsrc1) _op (s2) vsrc2);         \
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(2);
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_INT_LIT8(_opcode, _opname, _op, _chkdiv)                \
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/)                               \
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 litInfo;                                                         \
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        litInfo = FETCH(1);                                                 \
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = litInfo & 0xff;                                             \
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = litInfo >> 8;       /* constant */                          \
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x",                              \
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (_opname), vdst, vsrc1, vsrc2);                                 \
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s4 firstVal, result;                                            \
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER(vsrc1);                                 \
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((s1) vsrc2 == 0) {                                          \
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
232d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u4)firstVal == 0x80000000 && ((s1) vsrc2) == -1) {         \
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op ((s1) vsrc2);                         \
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst, result);                                     \
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst,                                              \
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (s4) GET_REGISTER(vsrc1) _op (s1) vsrc2);                   \
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_SHX_INT_LIT8(_opcode, _opname, _cast, _op)                \
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/)                               \
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 litInfo;                                                         \
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        litInfo = FETCH(1);                                                 \
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = litInfo & 0xff;                                             \
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = litInfo >> 8;       /* constant */                          \
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x",                              \
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (_opname), vdst, vsrc1, vsrc2);                                 \
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER(vdst,                                                  \
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _cast GET_REGISTER(vsrc1) _op (vsrc2 & 0x1f));                  \
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_INT_2ADDR(_opcode, _opname, _op, _chkdiv)               \
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1);             \
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s4 firstVal, secondVal, result;                                 \
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER(vdst);                                  \
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            secondVal = GET_REGISTER(vsrc1);                                \
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (secondVal == 0) {                                           \
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
277d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u4)firstVal == 0x80000000 && secondVal == -1) {            \
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op secondVal;                            \
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst, result);                                     \
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER(vdst,                                              \
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (s4) GET_REGISTER(vdst) _op (s4) GET_REGISTER(vsrc1));      \
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_SHX_INT_2ADDR(_opcode, _opname, _cast, _op)               \
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1);             \
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER(vdst,                                                  \
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _cast GET_REGISTER(vdst) _op (GET_REGISTER(vsrc1) & 0x1f));     \
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_LONG(_opcode, _opname, _op, _chkdiv)                    \
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);       \
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s8 firstVal, secondVal, result;                                 \
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER_WIDE(vsrc1);                            \
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            secondVal = GET_REGISTER_WIDE(vsrc2);                           \
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (secondVal == 0LL) {                                         \
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
319d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u8)firstVal == 0x8000000000000000ULL &&                    \
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                secondVal == -1LL)                                          \
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {                                                               \
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op secondVal;                            \
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER_WIDE(vdst, result);                                \
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER_WIDE(vdst,                                         \
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (s8) GET_REGISTER_WIDE(vsrc1) _op (s8) GET_REGISTER_WIDE(vsrc2)); \
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_SHX_LONG(_opcode, _opname, _cast, _op)                    \
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);       \
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_WIDE(vdst,                                             \
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _cast GET_REGISTER_WIDE(vsrc1) _op (GET_REGISTER(vsrc2) & 0x3f)); \
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_LONG_2ADDR(_opcode, _opname, _op, _chkdiv)              \
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1);            \
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (_chkdiv != 0) {                                                 \
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s8 firstVal, secondVal, result;                                 \
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstVal = GET_REGISTER_WIDE(vdst);                             \
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            secondVal = GET_REGISTER_WIDE(vsrc1);                           \
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (secondVal == 0LL) {                                         \
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                EXPORT_PC();                                                \
365d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein                dvmThrowArithmeticException("divide by zero");              \
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if ((u8)firstVal == 0x8000000000000000ULL &&                    \
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                secondVal == -1LL)                                          \
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {                                                               \
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (_chkdiv == 1)                                           \
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = firstVal;  /* division */                      \
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                else                                                        \
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    result = 0;         /* remainder */                     \
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {                                                        \
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                result = firstVal _op secondVal;                            \
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER_WIDE(vdst, result);                                \
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {                                                            \
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SET_REGISTER_WIDE(vdst,                                         \
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (s8) GET_REGISTER_WIDE(vdst) _op (s8)GET_REGISTER_WIDE(vsrc1));\
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_SHX_LONG_2ADDR(_opcode, _opname, _cast, _op)              \
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1);            \
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_WIDE(vdst,                                             \
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            _cast GET_REGISTER_WIDE(vdst) _op (GET_REGISTER(vsrc1) & 0x3f)); \
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_FLOAT(_opcode, _opname, _op)                            \
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-float v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);      \
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_FLOAT(vdst,                                            \
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER_FLOAT(vsrc1) _op GET_REGISTER_FLOAT(vsrc2));       \
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_DOUBLE(_opcode, _opname, _op)                           \
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 srcRegs;                                                         \
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        srcRegs = FETCH(1);                                                 \
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = srcRegs & 0xff;                                             \
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = srcRegs >> 8;                                               \
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-double v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);     \
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_DOUBLE(vdst,                                           \
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER_DOUBLE(vsrc1) _op GET_REGISTER_DOUBLE(vsrc2));     \
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_FLOAT_2ADDR(_opcode, _opname, _op)                      \
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-float-2addr v%d,v%d", (_opname), vdst, vsrc1);           \
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_FLOAT(vdst,                                            \
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER_FLOAT(vdst) _op GET_REGISTER_FLOAT(vsrc1));        \
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_X_DOUBLE_2ADDR(_opcode, _opname, _op)                     \
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB*/)                                       \
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);                                               \
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|%s-double-2addr v%d,v%d", (_opname), vdst, vsrc1);          \
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER_DOUBLE(vdst,                                           \
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER_DOUBLE(vdst) _op GET_REGISTER_DOUBLE(vsrc1));      \
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FINISH(1);
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_AGET(_opcode, _opname, _type, _regsize)                   \
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayObject* arrayObj;                                              \
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 arrayInfo;                                                       \
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();                                                        \
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        arrayInfo = FETCH(1);                                               \
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = arrayInfo & 0xff;    /* array ptr */                        \
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = arrayInfo >> 8;      /* index */                            \
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|aget%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);        \
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        arrayObj = (ArrayObject*) GET_REGISTER(vsrc1);                      \
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull((Object*) arrayObj))                              \
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
45574501e600dcb5634aa26aee0a3f57f2b45b213f2Dan Bornstein            dvmThrowArrayIndexOutOfBoundsException(                         \
45647f58250c5177adba475b0b11a36151ac0ce9ab9Dan Bornstein                arrayObj->length, GET_REGISTER(vsrc2));                     \
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_regsize(vdst,                                        \
460cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro            ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)]);      \
461291c84f60853d30e1c0d79dd08c5e5164f588e26Dan Bornstein        ILOGV("+ AGET[%d]=%#x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));   \
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_OP_APUT(_opcode, _opname, _type, _regsize)                   \
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/)                                \
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ArrayObject* arrayObj;                                              \
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u2 arrayInfo;                                                       \
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();                                                        \
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);       /* AA: source value */                  \
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        arrayInfo = FETCH(1);                                               \
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = arrayInfo & 0xff;   /* BB: array ptr */                     \
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc2 = arrayInfo >> 8;     /* CC: index */                         \
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|aput%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2);        \
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        arrayObj = (ArrayObject*) GET_REGISTER(vsrc1);                      \
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull((Object*) arrayObj))                              \
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (GET_REGISTER(vsrc2) >= arrayObj->length) {                      \
48074501e600dcb5634aa26aee0a3f57f2b45b213f2Dan Bornstein            dvmThrowArrayIndexOutOfBoundsException(                         \
48147f58250c5177adba475b0b11a36151ac0ce9ab9Dan Bornstein                arrayObj->length, GET_REGISTER(vsrc2));                     \
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\
485cd8f5e701547739f241594b43e9470c92d98e9cfCarl Shapiro        ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)] =          \
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER##_regsize(vdst);                                   \
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It's possible to get a bad value out of a field with sub-32-bit stores
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because the -quick versions always operate on 32 bits.  Consider:
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   short foo = -1  (sets a 32-bit register to 0xffffffff)
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   iput-quick foo  (writes all 32 bits to the field)
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   short bar = 1   (sets a 32-bit register to 0x00000001)
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   iput-short      (writes the low 16 bits to the field)
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   iget-quick foo  (reads all 32 bits from the field, yielding 0xffff0001)
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This can only happen when optimized and non-optimized code has interleaved
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * access to the same field.  This is unlikely but possible.
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The easiest way to fix this is to always read/write 32 bits at a time.  On
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a device with a 16-bit data bus this is sub-optimal.  (The alternative
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * approach is to have sub-int versions of iget-quick, but now we're wasting
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dalvik instruction space and making it less likely that handler code will
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * already be in the CPU i-cache.)
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_IGET_X(_opcode, _opname, _ftype, _regsize)                   \
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        InstField* ifield;                                                  \
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* obj;                                                        \
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();                                                        \
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);   /* object ptr */                            \
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field ref */                             \
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|iget%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        obj = (Object*) GET_REGISTER(vsrc1);                                \
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull(obj))                                             \
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref);  \
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ifield == NULL) {                                               \
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ifield = dvmResolveInstField(curMethod->clazz, ref);            \
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (ifield == NULL)                                             \
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_regsize(vdst,                                        \
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmGetField##_ftype(obj, ifield->byteOffset));                  \
52846f3fd49ebda372887192fa32b16040ed6710f58Chris Dearman        ILOGV("+ IGET '%s'=0x%08llx", ifield->name,                         \
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (u8) GET_REGISTER##_regsize(vdst));                             \
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_IGET_X_QUICK(_opcode, _opname, _ftype, _regsize)             \
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* obj;                                                        \
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);   /* object ptr */                            \
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field offset */                          \
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|iget%s-quick v%d,v%d,field@+%u",                            \
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (_opname), vdst, vsrc1, ref);                                   \
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        obj = (Object*) GET_REGISTER(vsrc1);                                \
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNullExportPC(obj, fp, pc))                             \
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_regsize(vdst, dvmGetField##_ftype(obj, ref));        \
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("+ IGETQ %d=0x%08llx", ref,                                   \
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (u8) GET_REGISTER##_regsize(vdst));                             \
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_IPUT_X(_opcode, _opname, _ftype, _regsize)                   \
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        InstField* ifield;                                                  \
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* obj;                                                        \
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EXPORT_PC();                                                        \
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);   /* object ptr */                            \
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field ref */                             \
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|iput%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        obj = (Object*) GET_REGISTER(vsrc1);                                \
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNull(obj))                                             \
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref);  \
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ifield == NULL) {                                               \
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ifield = dvmResolveInstField(curMethod->clazz, ref);            \
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (ifield == NULL)                                             \
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetField##_ftype(obj, ifield->byteOffset,                        \
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GET_REGISTER##_regsize(vdst));                                  \
57246f3fd49ebda372887192fa32b16040ed6710f58Chris Dearman        ILOGV("+ IPUT '%s'=0x%08llx", ifield->name,                         \
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (u8) GET_REGISTER##_regsize(vdst));                             \
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_IPUT_X_QUICK(_opcode, _opname, _ftype, _regsize)             \
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/)                           \
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object* obj;                                                        \
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_A(inst);                                                \
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vsrc1 = INST_B(inst);   /* object ptr */                            \
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field offset */                          \
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|iput%s-quick v%d,v%d,field@0x%04x",                         \
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (_opname), vdst, vsrc1, ref);                                   \
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        obj = (Object*) GET_REGISTER(vsrc1);                                \
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkForNullExportPC(obj, fp, pc))                             \
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            GOTO_exceptionThrown();                                         \
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetField##_ftype(obj, ref, GET_REGISTER##_regsize(vdst));        \
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("+ IPUTQ %d=0x%08llx", ref,                                   \
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (u8) GET_REGISTER##_regsize(vdst));                             \
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
595fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom/*
596fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom * The JIT needs dvmDexGetResolvedField() to return non-null.
5979a3147c7412f4794434b4c2604aa2ba784867774buzbee * Because the portable interpreter is not involved with the JIT
5989a3147c7412f4794434b4c2604aa2ba784867774buzbee * and trace building, we only need the extra check here when this
5999a3147c7412f4794434b4c2604aa2ba784867774buzbee * code is massaged into a stub called from an assembly interpreter.
6009a3147c7412f4794434b4c2604aa2ba784867774buzbee * This is controlled by the JIT_STUB_HACK maco.
601fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom */
6029a3147c7412f4794434b4c2604aa2ba784867774buzbee
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_SGET_X(_opcode, _opname, _ftype, _regsize)                   \
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/)                              \
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StaticField* sfield;                                                \
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field ref */                             \
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|sget%s v%d,sfield@0x%04x", (_opname), vdst, ref);           \
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sfield == NULL) {                                               \
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            EXPORT_PC();                                                    \
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sfield = dvmResolveStaticField(curMethod->clazz, ref);          \
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (sfield == NULL)                                             \
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
616fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom            if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) {      \
61760fc806b679a3655c228b4093058c59941a49cfeDan Bornstein                JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc));               \
618fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom            }                                                               \
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SET_REGISTER##_regsize(vdst, dvmGetStaticField##_ftype(sfield));    \
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("+ SGET '%s'=0x%08llx",                                       \
62246f3fd49ebda372887192fa32b16040ed6710f58Chris Dearman            sfield->name, (u8)GET_REGISTER##_regsize(vdst));                \
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HANDLE_SPUT_X(_opcode, _opname, _ftype, _regsize)                   \
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/)                              \
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StaticField* sfield;                                                \
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        vdst = INST_AA(inst);                                               \
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ref = FETCH(1);         /* field ref */                             \
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("|sput%s v%d,sfield@0x%04x", (_opname), vdst, ref);           \
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sfield == NULL) {                                               \
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            EXPORT_PC();                                                    \
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sfield = dvmResolveStaticField(curMethod->clazz, ref);          \
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (sfield == NULL)                                             \
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                GOTO_exceptionThrown();                                     \
639fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom            if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) {      \
64060fc806b679a3655c228b4093058c59941a49cfeDan Bornstein                JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc));               \
641fbdcfb9ea9e2a78f295834424c3f24986ea45dacBrian Carlstrom            }                                                               \
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmSetStaticField##_ftype(sfield, GET_REGISTER##_regsize(vdst));    \
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ILOGV("+ SPUT '%s'=0x%08llx",                                       \
64546f3fd49ebda372887192fa32b16040ed6710f58Chris Dearman            sfield->name, (u8)GET_REGISTER##_regsize(vdst));                \
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FINISH(2);
648