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