165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org/* 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * This file was generated automatically by gen-mterp.py for 'armv5te-vfp'. 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * --> DO NOT EDIT <-- 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* File: c/header.cpp */ 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Copyright (C) 2008 The Android Open Source Project 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Licensed under the Apache License, Version 2.0 (the "License"); 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * you may not use this file except in compliance with the License. 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * You may obtain a copy of the License at 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * http://www.apache.org/licenses/LICENSE-2.0 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Unless required by applicable law or agreed to in writing, software 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * distributed under the License is distributed on an "AS IS" BASIS, 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * See the License for the specific language governing permissions and 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * limitations under the License. 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* common includes */ 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "Dalvik.h" 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "interp/InterpDefs.h" 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "mterp/Mterp.h" 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include <math.h> // needed for fmod, fmodf 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "mterp/common/FindInterface.h" 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/* 3240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org * Configuration defines. These affect the C implementations, i.e. the 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * portable interpreter(s) and C stubs. 3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org * 3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org * Some defines are controlled by the Makefile, e.g.: 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * WITH_INSTR_CHECKS 3713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org * WITH_TRACKREF_CHECKS 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * EASY_GDB 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * NDEBUG 400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org */ 410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org#ifdef WITH_INSTR_CHECKS /* instruction-level paranoia (slow!) */ 43ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org# define CHECK_BRANCH_OFFSETS 440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org# define CHECK_REGISTER_INDICES 451af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#endif 460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 475c838251403b0be9a882540f1922577abba4c872ager@chromium.org/* 4857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org * Some architectures require 64-bit alignment for access to 64-bit data 490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * types. We can't just use pointers to copy 64-bit values out of our 500b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * interpreted register set, because gcc may assume the pointer target is 51ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org * aligned and generate invalid code. 52ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org * 530b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * There are two common approaches: 540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * (1) Use a union that defines a 32-bit pair and a 64-bit value. 550b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * (2) Call memcpy(). 560b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * 570b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org * Depending upon what compiler you're using and what options are specified, 585c838251403b0be9a882540f1922577abba4c872ager@chromium.org * one may be faster than the other. For example, the compiler might 59ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org * convert a memcpy() of 8 bytes into a series of instructions and omit 609fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org * the call. The union version could cause some strange side-effects, 6125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org * e.g. for a while ARM gcc thought it needed separate storage for each 62ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org * inlined instance, and generated instructions to zero out ~700 bytes of 6377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org * stack space at the top of the interpreter. 64b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org * 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * The default is to use memcpy(). The current gcc for ARM seems to do 66e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org * better with the union. 67e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org */ 6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#if defined(__ARM_EABI__) 6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define NO_UNALIGN_64__UNION 7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * MIPS ABI requires 64-bit alignment for access to 64-bit data types. 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Use memcpy() to do the transfer 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#if defined(__mips__) 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* # define NO_UNALIGN_64__UNION */ 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//#define LOG_INSTR /* verbose debugging */ 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* set and adjust ANDROID_LOG_TAGS='*:i jdwp:i dalvikvm:i dalvikvmi:i' */ 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Export another copy of the PC on every instruction; this is largely 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * redundant with EXPORT_PC and the debugger code. This value can be 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * compared against what we have stored on the stack with EXPORT_PC to 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * help ensure that we aren't missing any export calls. 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#if WITH_EXTRA_GC_CHECKS > 1 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define EXPORT_EXTRA_PC() (self->currentPc2 = pc) 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define EXPORT_EXTRA_PC() 94ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif 9564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Adjust the program counter. "_offset" is a signed int, in 16-bit units. 98fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * 99fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * Assumes the existence of "const u2* pc" and "const u2* curMethod->insns". 100fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * 101fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * We don't advance the program counter until we finish an instruction or 10264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org * branch, because we do want to have to unroll the PC if there's an 10364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org * exception. 104ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org */ 105d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org#ifdef CHECK_BRANCH_OFFSETS 106fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org# define ADJUST_PC(_offset) do { \ 107fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int myoff = _offset; /* deref only once */ \ 108fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (pc + myoff < curMethod->insns || \ 10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen pc + myoff >= curMethod->insns + dvmGetMethodInsnsSize(curMethod)) \ 11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen { \ 1113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org char* desc; \ 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen desc = dexProtoCopyMethodDescriptor(&curMethod->prototype); \ 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ALOGE("Invalid branch %d at 0x%04x in %s.%s %s", \ 11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen myoff, (int) (pc - curMethod->insns), \ 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen curMethod->clazz->descriptor, curMethod->name, desc); \ 116236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org free(desc); \ 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dvmAbort(); \ 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } \ 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen pc += myoff; \ 120c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org EXPORT_EXTRA_PC(); \ 12113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } while (false) 122c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org#else 12313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org# define ADJUST_PC(_offset) do { \ 124c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org pc += _offset; \ 12513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org EXPORT_EXTRA_PC(); \ 12613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } while (false) 12713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org#endif 12813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 129c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org/* 130236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org * If enabled, log instructions as we execute them. 131236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org */ 13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef LOG_INSTR 13369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org# define ILOGD(...) ILOG(LOG_DEBUG, __VA_ARGS__) 13469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org# define ILOGV(...) ILOG(LOG_VERBOSE, __VA_ARGS__) 13569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org# define ILOG(_level, ...) do { \ 13669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org char debugStrBuf[128]; \ 1378432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org snprintf(debugStrBuf, sizeof(debugStrBuf), __VA_ARGS__); \ 1388432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (curMethod != NULL) \ 13965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org ALOG(_level, LOG_TAG"i", "%-2d|%04x%s", \ 14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen self->threadId, (int)(pc - curMethod->insns), debugStrBuf); \ 1418e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org else \ 1428e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org ALOG(_level, LOG_TAG"i", "%-2d|####%s", \ 1438e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org self->threadId, debugStrBuf); \ 1448e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } while(false) 1458e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgvoid dvmDumpRegs(const Method* method, const u4* framePtr, bool inOnly); 14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define DUMP_REGS(_meth, _frame, _inOnly) dvmDumpRegs(_meth, _frame, _inOnly) 14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const char kSpacing[] = " "; 14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else 149ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org# define ILOGD(...) ((void)0) 15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define ILOGV(...) ((void)0) 15165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org# define DUMP_REGS(_meth, _frame, _inOnly) ((void)0) 15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org/* get a long from an array of u4 */ 15565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgstatic inline s8 getLongFromArray(const u4* ptr, int idx) 15643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen{ 15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#if defined(NO_UNALIGN_64__UNION) 158c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org union { s8 ll; u4 parts[2]; } conv; 159c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 160c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ptr += idx; 161c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org conv.parts[0] = ptr[0]; 162c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org conv.parts[1] = ptr[1]; 163c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org return conv.ll; 16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else 16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen s8 val; 16664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org memcpy(&val, &ptr[idx], 8); 16764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return val; 168d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org#endif 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org/* store a long into an array of u4 */ 172ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline void putLongToArray(u4* ptr, int idx, s8 val) 173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org{ 174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#if defined(NO_UNALIGN_64__UNION) 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen union { s8 ll; u4 parts[2]; } conv; 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ptr += idx; 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen conv.ll = val; 179f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org ptr[0] = conv.parts[0]; 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ptr[1] = conv.parts[1]; 1812efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#else 1822efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org memcpy(&ptr[idx], &val, 8); 1832efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#endif 1842efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 1852efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1862efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org/* get a double from an array of u4 */ 1872efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgstatic inline double getDoubleFromArray(const u4* ptr, int idx) 1882efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org{ 1892efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#if defined(NO_UNALIGN_64__UNION) 1902efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org union { double d; u4 parts[2]; } conv; 1912efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1922efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ptr += idx; 193fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org conv.parts[0] = ptr[0]; 194fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org conv.parts[1] = ptr[1]; 195fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return conv.d; 196fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org#else 197fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org double dval; 1984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org memcpy(&dval, &ptr[idx], 8); 199fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return dval; 200bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#endif 2016e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 202f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 203fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org/* store a double into an array of u4 */ 204d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgstatic inline void putDoubleToArray(u4* ptr, int idx, double dval) 205d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org{ 20657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org#if defined(NO_UNALIGN_64__UNION) 2072efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org union { double d; u4 parts[2]; } conv; 2082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 2092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ptr += idx; 2102efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org conv.d = dval; 2112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ptr[0] = conv.parts[0]; 2122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ptr[1] = conv.parts[1]; 2132efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#else 2142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org memcpy(&ptr[idx], &dval, 8); 215d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org#endif 216d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org} 217d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 218d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org/* 219068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org * If enabled, validate the register number on every access. Otherwise, 220068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org * just do an array access. 221068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org * 222068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org * Assumes the existence of "u4* fp". 223fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * 224d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org * "_idx" may be referenced more than once. 225d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org */ 2262efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#ifdef CHECK_REGISTER_INDICES 227d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org# define GET_REGISTER(_idx) \ 22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ( (_idx) < curMethod->registersSize ? \ 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (fp[(_idx)]) : (assert(!"bad reg"),1969) ) 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER(_idx, _val) \ 23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ( (_idx) < curMethod->registersSize ? \ 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (fp[(_idx)] = (u4)(_val)) : (assert(!"bad reg"),1969) ) 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_AS_OBJECT(_idx) ((Object *)GET_REGISTER(_idx)) 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_AS_OBJECT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 23543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_INT(_idx) ((s4) GET_REGISTER(_idx)) 23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 23731e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager# define GET_REGISTER_WIDE(_idx) \ 238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ( (_idx) < curMethod->registersSize-1 ? \ 239ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org getLongFromArray(fp, (_idx)) : (assert(!"bad reg"),1969) ) 240fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org# define SET_REGISTER_WIDE(_idx, _val) \ 241fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ( (_idx) < curMethod->registersSize-1 ? \ 242fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org (void)putLongToArray(fp, (_idx), (_val)) : assert(!"bad reg") ) 243c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org# define GET_REGISTER_FLOAT(_idx) \ 244fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ( (_idx) < curMethod->registersSize ? \ 24531e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager (*((float*) &fp[(_idx)])) : (assert(!"bad reg"),1969.0f) ) 24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_FLOAT(_idx, _val) \ 24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ( (_idx) < curMethod->registersSize ? \ 24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (*((float*) &fp[(_idx)]) = (_val)) : (assert(!"bad reg"),1969.0f) ) 24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_DOUBLE(_idx) \ 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ( (_idx) < curMethod->registersSize-1 ? \ 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen getDoubleFromArray(fp, (_idx)) : (assert(!"bad reg"),1969.0) ) 25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_DOUBLE(_idx, _val) \ 25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ( (_idx) < curMethod->registersSize-1 ? \ 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (void)putDoubleToArray(fp, (_idx), (_val)) : assert(!"bad reg") ) 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else 25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER(_idx) (fp[(_idx)]) 25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER(_idx, _val) (fp[(_idx)] = (_val)) 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_AS_OBJECT(_idx) ((Object*) fp[(_idx)]) 25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_AS_OBJECT(_idx, _val) (fp[(_idx)] = (u4)(_val)) 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_INT(_idx) ((s4)GET_REGISTER(_idx)) 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_INT(_idx, _val) SET_REGISTER(_idx, (s4)_val) 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_WIDE(_idx) getLongFromArray(fp, (_idx)) 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define SET_REGISTER_WIDE(_idx, _val) putLongToArray(fp, (_idx), (_val)) 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen# define GET_REGISTER_FLOAT(_idx) (*((float*) &fp[(_idx)])) 2651af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org# define SET_REGISTER_FLOAT(_idx, _val) (*((float*) &fp[(_idx)]) = (_val)) 26640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org# define GET_REGISTER_DOUBLE(_idx) getDoubleFromArray(fp, (_idx)) 26740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org# define SET_REGISTER_DOUBLE(_idx, _val) putDoubleToArray(fp, (_idx), (_val)) 26840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#endif 26940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com/* 271fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * Get 16 bits from the specified offset of the program counter. We always 272303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org * want to load 16 bits at a time from the instruction stream -- it's more 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * efficient than 8 and won't have the alignment problems that 32 might. 2741af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org * 275394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Assumes existence of "const u2* pc". 276394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com */ 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define FETCH(_offset) (pc[(_offset)]) 278fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 2790511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com/* 280394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Extract instruction byte from 16-bit fetch (_inst is a u2). 281394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com */ 282394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define INST_INST(_inst) ((_inst) & 0xff) 283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com/* 285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Replace the opcode (used when handling breakpoints). _opcode is a u1. 286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com */ 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define INST_REPLACE_OP(_inst, _opcode) (((_inst) & 0xff00) | _opcode) 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Extract the "vA, vB" 4-bit registers from the instruction word (_inst is u2). 291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com */ 292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define INST_A(_inst) (((_inst) >> 8) & 0x0f) 293394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define INST_B(_inst) ((_inst) >> 12) 294394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2959258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org/* 2963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org * Get the 8-bit "vAA" 8-bit register index from the instruction word. 297b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org * (_inst is u2) 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 29940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#define INST_AA(_inst) ((_inst) >> 8) 300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 301394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com/* 302394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * The current PC must be available to Throwable constructors, e.g. 303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * those created by the various exception throw routines, so that the 304394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * exception stack trace can be generated correctly. If we don't do this, 305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * the offset within the current method won't be shown correctly. See the 306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * notes in Exception.c. 307394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * 308394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * This is also used to determine the address for precise GC. 309394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * 310394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Assumes existence of "u4* fp" and "const u2* pc". 311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com */ 312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define EXPORT_PC() (SAVEAREA_FROM_FP(fp)->xtra.currentPc = pc) 313394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 314d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org/* 315d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org * Check to see if "obj" is NULL. If so, throw an exception. Assumes the 316d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org * pc has already been exported to the stack. 317394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * 318394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Perform additional checks on debug builds. 31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Use this to check for NULL when the instruction handler calls into 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * something that could throw an exception (so we have already called 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * EXPORT_PC at the top). 3231af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org */ 3241af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgstatic inline bool checkForNull(Object* obj) 325fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org{ 326fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (obj == NULL) { 327fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org dvmThrowNullPointerException(NULL); 328ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return false; 329ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 3301af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#ifdef WITH_EXTRA_OBJECT_VALIDATION 3311af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (!dvmIsHeapAddress(obj)) { 33240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ALOGE("Invalid object %p", obj); 33340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org dvmAbort(); 334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#endif 33640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#ifndef NDEBUG 337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) { 33840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org /* probable heap corruption */ 33940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ALOGE("Invalid object class %p (in %p)", obj->clazz, obj); 340394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com dvmAbort(); 341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 342394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#endif 343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return true; 34440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 34540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 34640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org/* 347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Check to see if "obj" is NULL. If so, export the PC into the stack 348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * frame and throw an exception. 349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * 350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * Perform additional checks on debug builds. 351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * 352fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * Use this to check for NULL when the instruction handler doesn't do 353fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * anything else that can throw an exception. 354fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org */ 355fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgstatic inline bool checkForNullExportPC(Object* obj, u4* fp, const u2* pc) 356fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org{ 357fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (obj == NULL) { 358fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org EXPORT_PC(); 3591af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org dvmThrowNullPointerException(NULL); 3601af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org return false; 3611af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 3621af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#ifdef WITH_EXTRA_OBJECT_VALIDATION 3631af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (!dvmIsHeapAddress(obj)) { 364ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ALOGE("Invalid object %p", obj); 365ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org dvmAbort(); 3661af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 3671af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#endif 3681af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#ifndef NDEBUG 369fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (obj->clazz == NULL || ((u4) obj->clazz) <= 65536) { 370303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org /* probable heap corruption */ 3711af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org ALOGE("Invalid object class %p (in %p)", obj->clazz, obj); 3721af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org dvmAbort(); 3731af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 3741af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org#endif 3751af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org return true; 376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 378394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com/* File: cstubs/stubdefs.cpp */ 379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com/* 380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * In the C mterp stubs, "goto" is a function call followed immediately 381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com * by a return. 3821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org */ 3831af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 3847b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org#define GOTO_TARGET_DECL(_target, ...) \ 3851af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org extern "C" void dvmMterp_##_target(Thread* self, ## __VA_ARGS__); 3861af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 3871af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org/* (void)xxx to quiet unused variable compiler warnings. */ 38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define GOTO_TARGET(_target, ...) \ 38943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void dvmMterp_##_target(Thread* self, ## __VA_ARGS__) { \ 390e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org u2 ref, vsrc1, vsrc2, vdst; \ 391003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org u2 inst = FETCH(0); \ 392ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const Method* methodToCall; \ 39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen StackSaveArea* debugSaveArea; \ 39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst; \ 3955c838251403b0be9a882540f1922577abba4c872ager@chromium.org (void)methodToCall; (void)debugSaveArea; 3965c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3975c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define GOTO_TARGET_END } 3985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Redefine what used to be local variable accesses into Thread struct 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * references. (These are undefined down in "footer.cpp".) 402d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org */ 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define retval self->interpSave.retval 404fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org#define pc self->interpSave.pc 405003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#define fp self->interpSave.curFrame 406003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#define curMethod self->interpSave.method 4076bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#define methodClassDex self->interpSave.methodClassDex 4086bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#define debugTrackedRefStart self->interpSave.debugTrackedRefStart 4096bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 4104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org/* ugh */ 411d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#define STUB_HACK(x) x 412003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#if defined(WITH_JIT) 413003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org#define JIT_STUB_HACK(x) x 4146bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#else 4156bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#define JIT_STUB_HACK(x) 4166bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#endif 4176bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * InterpSave's pc and fp must be valid when breaking out to a 420003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org * "Reportxxx" routine. Because the portable interpreter uses local 421003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org * variables for these, we must flush prior. Stubs, however, use 422003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org * the interpSave vars directly, so this is a nop for stubs. 423bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org */ 4242efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#define PC_FP_TO_SELF() 4252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#define PC_TO_SELF() 4262efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 4272efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org/* 42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * Opcode handler framing macros. Here, each opcode is a separate function 4296bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org * that takes a "self" argument and returns void. We can't declare 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * these "static" because they may be called from an assembly stub. 4313d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org * (void)xxx to quiet unused variable compiler warnings. 4323d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org */ 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define HANDLE_OPCODE(_op) \ 434fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org extern "C" void dvmMterp_##_op(Thread* self); \ 4358e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org void dvmMterp_##_op(Thread* self) { \ 4368e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org u4 ref; \ 4378e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org u2 vsrc1, vsrc2, vdst; \ 438fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org u2 inst = FETCH(0); \ 4396bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org (void)ref; (void)vsrc1; (void)vsrc2; (void)vdst; (void)inst; 4408e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define OP_END } 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4432efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org/* 4442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org * Like the "portable" FINISH, but don't reload "inst", and return to caller 4452efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org * when done. Further, debugger/profiler checks are handled 4462efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org * before handler execution in mterp, so we don't do them here either. 4472efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org */ 4483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org#if defined(WITH_JIT) 4495ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define FINISH(_offset) { \ 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ADJUST_PC(_offset); \ 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (self->interpBreak.ctl.subMode & kSubModeJitTraceBuild) { \ 45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dvmCheckJit(pc, self); \ 45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } \ 45459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return; \ 45559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 45659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#else 45759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#define FINISH(_offset) { \ 45859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ADJUST_PC(_offset); \ 45959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return; \ 460003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 461ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#endif 462e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 463e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#define FINISH_BKPT(_opcode) /* FIXME? */ 464ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#define DISPATCH_EXTENDED(_opcode) /* FIXME? */ 465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen/* 467fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * The "goto label" statements turn into function calls followed by 468ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org * return statements. Some of the functions take arguments, which in the 46959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org * portable interpreter are handled by assigning values to globals. 47043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#define GOTO_exceptionThrown() \ 4735c838251403b0be9a882540f1922577abba4c872ager@chromium.org do { \ 474ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org dvmMterp_exceptionThrown(self); \ 47559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return; \ 476ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } while(false) 4775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 47859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org#define GOTO_returnFromMethod() \ 4795c838251403b0be9a882540f1922577abba4c872ager@chromium.org do { \ 48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dvmMterp_returnFromMethod(self); \ 4810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return; \ 4825c838251403b0be9a882540f1922577abba4c872ager@chromium.org } while(false) 4837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org 4843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#define GOTO_invoke(_target, _methodCallRange) \ 485eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org do { \ 486eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org dvmMterp_##_target(self, _methodCallRange); \ 487eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org return; \ 488eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org } while(false) 489eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org 490eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org#define GOTO_invokeMethod(_methodCallRange, _methodToCall, _vsrc1, _vdst) \ 491eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org do { \ 492ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org dvmMterp_invokeMethod(self, _methodCallRange, _methodToCall, \ 493ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org _vsrc1, _vdst); \ 494ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org return; \ 495003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } while(false) 496003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 4976bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org/* 4986bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org * As a special case, "goto bail" turns into a longjmp. 4996bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org */ 5006bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#define GOTO_bail() \ 5016bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org dvmMterpStdBail(self) 5026bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 5034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org/* 5044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org * Periodically check for thread suspension. 5054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org * 5066bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org * While we're at it, see if a debugger has attached or the profiler has 50757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org * started. 50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen */ 5096bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org#define PERIODIC_CHECKS(_pcadj) { \ 51043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (dvmCheckSuspendQuick(self)) { \ 5113d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org EXPORT_PC(); /* need for precise GC */ \ 5123d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org dvmCheckSuspendPending(self); \ 51343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } \ 5148e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 5158e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 5168e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org/* File: c/opcommon.cpp */ 5176bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org/* forward declarations of goto targets */ 5188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgGOTO_TARGET_DECL(filledNewArray, bool methodCallRange); 51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenGOTO_TARGET_DECL(invokeVirtual, bool methodCallRange); 520394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comGOTO_TARGET_DECL(invokeSuper, bool methodCallRange); 521394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comGOTO_TARGET_DECL(invokeInterface, bool methodCallRange); 5225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgGOTO_TARGET_DECL(invokeDirect, bool methodCallRange); 523394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comGOTO_TARGET_DECL(invokeStatic, bool methodCallRange); 524394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comGOTO_TARGET_DECL(invokeVirtualQuick, bool methodCallRange); 5257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.orgGOTO_TARGET_DECL(invokeSuperQuick, bool methodCallRange); 526003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgGOTO_TARGET_DECL(invokeMethod, bool methodCallRange, const Method* methodToCall, 527003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org u2 count, u2 regs); 528003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgGOTO_TARGET_DECL(returnFromMethod); 5295c838251403b0be9a882540f1922577abba4c872ager@chromium.orgGOTO_TARGET_DECL(exceptionThrown); 5303d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 53137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com/* 53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * =========================================================================== 53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * 53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * What follows are opcode definitions shared between multiple opcodes with 53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * minor substitutions handled by the C pre-processor. These should probably 53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * use the mterp substitution mechanism instead, with the code here moved 53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen * into common fragment files (like the asm "binop.S"), although it's hard 538fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * to give up the C preprocessor in favor of the much simpler text subst. 539fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * 540fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org * =========================================================================== 541003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org */ 542ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define HANDLE_NUMCONV(_opcode, _opname, _fromtype, _totype) \ 544fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 545fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vdst = INST_A(inst); \ 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen vsrc1 = INST_B(inst); \ 54757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1); \ 548b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org SET_REGISTER##_totype(vdst, \ 5493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org GET_REGISTER##_fromtype(vsrc1)); \ 5503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org FINISH(1); 5513d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define HANDLE_FLOAT_TO_INT(_opcode, _opname, _fromvtype, _fromrtype, \ 553496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org _tovtype, _tortype) \ 5549ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 55569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org { \ 556b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org /* spec defines specific handling for +/- inf and NaN values */ \ 557b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org _fromvtype val; \ 55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen _tovtype intMin, intMax, result; \ 559003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org vdst = INST_A(inst); \ 560003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org vsrc1 = INST_B(inst); \ 561003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1); \ 562003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org val = GET_REGISTER##_fromrtype(vsrc1); \ 563003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org intMin = (_tovtype) 1 << (sizeof(_tovtype) * 8 -1); \ 564003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org intMax = ~intMin; \ 565003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org result = (_tovtype) val; \ 5666bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (val >= intMax) /* +inf */ \ 5676bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org result = intMax; \ 5686bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org else if (val <= intMin) /* -inf */ \ 569fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = intMin; \ 570fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org else if (val != val) /* NaN */ \ 571fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = 0; \ 572fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org else \ 573fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = (_tovtype) val; \ 5746bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org SET_REGISTER##_tortype(vdst, result); \ 5756bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } \ 576b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org FINISH(1); 577fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 578fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org#define HANDLE_INT_TO_SMALL(_opcode, _opname, _type) \ 579fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 580fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vdst = INST_A(inst); \ 581fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc1 = INST_B(inst); \ 582b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ILOGV("|int-to-%s v%d,v%d", (_opname), vdst, vsrc1); \ 583fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SET_REGISTER(vdst, (_type) GET_REGISTER(vsrc1)); \ 5842efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org FINISH(1); 5852efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 5862efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org/* NOTE: the comparison result is always a signed 4-byte integer */ 5872efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org#define HANDLE_OP_CMPX(_opcode, _opname, _varType, _type, _nanVal) \ 5882efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 5892efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org { \ 5902efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org int result; \ 5912efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org u2 regs; \ 5928e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org _varType val1, val2; \ 593fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vdst = INST_AA(inst); \ 5948e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org regs = FETCH(1); \ 595fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc1 = regs & 0xff; \ 596fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc2 = regs >> 8; \ 597fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("|cmp%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 598fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org val1 = GET_REGISTER##_type(vsrc1); \ 599fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org val2 = GET_REGISTER##_type(vsrc2); \ 600fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (val1 == val2) \ 601fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = 0; \ 602fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org else if (val1 < val2) \ 6033d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org result = -1; \ 604fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org else if (val1 > val2) \ 6056bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org result = 1; \ 606fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org else \ 607fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = (_nanVal); \ 608fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("+ result=%d", result); \ 609fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SET_REGISTER(vdst, result); \ 610fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } \ 6116bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org FINISH(2); 6126bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define HANDLE_OP_IF_XX(_opcode, _opname, _cmp) \ 61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE_OPCODE(_opcode /*vA, vB, +CCCC*/) \ 615d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org vsrc1 = INST_A(inst); \ 616d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org vsrc2 = INST_B(inst); \ 617d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if ((s4) GET_REGISTER(vsrc1) _cmp (s4) GET_REGISTER(vsrc2)) { \ 618d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org int branchOffset = (s2)FETCH(1); /* sign-extended */ \ 6192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ILOGV("|if-%s v%d,v%d,+0x%04x", (_opname), vsrc1, vsrc2, \ 6202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org branchOffset); \ 6212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ILOGV("> branch taken"); \ 6222efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (branchOffset < 0) \ 62343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PERIODIC_CHECKS(branchOffset); \ 6246bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org FINISH(branchOffset); \ 6259ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } else { \ 6269ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org ILOGV("|if-%s v%d,v%d,-", (_opname), vsrc1, vsrc2); \ 62765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org FINISH(2); \ 62865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 6299ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 6309ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org#define HANDLE_OP_IF_XXZ(_opcode, _opname, _cmp) \ 6319ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org HANDLE_OPCODE(_opcode /*vAA, +BBBB*/) \ 632fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc1 = INST_AA(inst); \ 633fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if ((s4) GET_REGISTER(vsrc1) _cmp 0) { \ 634fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int branchOffset = (s2)FETCH(1); /* sign-extended */ \ 635fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("|if-%s v%d,+0x%04x", (_opname), vsrc1, branchOffset); \ 636fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("> branch taken"); \ 637fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (branchOffset < 0) \ 638fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org PERIODIC_CHECKS(branchOffset); \ 639496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org FINISH(branchOffset); \ 640fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } else { \ 6413d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org ILOGV("|if-%s v%d,-", (_opname), vsrc1); \ 642ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org FINISH(2); \ 643fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } 644fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define HANDLE_UNOP(_opcode, _opname, _pfx, _sfx, _type) \ 64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE_OPCODE(_opcode /*vA, vB*/) \ 64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen vdst = INST_A(inst); \ 64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen vsrc1 = INST_B(inst); \ 64933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org ILOGV("|%s v%d,v%d", (_opname), vdst, vsrc1); \ 65033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org SET_REGISTER##_type(vdst, _pfx GET_REGISTER##_type(vsrc1) _sfx); \ 65133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org FINISH(1); 65233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org 65333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#define HANDLE_OP_X_INT(_opcode, _opname, _op, _chkdiv) \ 65433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 65533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org { \ 65633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org u2 srcRegs; \ 65733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org vdst = INST_AA(inst); \ 65833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org srcRegs = FETCH(1); \ 65933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org vsrc1 = srcRegs & 0xff; \ 66033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org vsrc2 = srcRegs >> 8; \ 661003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1); \ 66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (_chkdiv != 0) { \ 6637bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org s4 firstVal, secondVal, result; \ 6647bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org firstVal = GET_REGISTER(vsrc1); \ 665ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org secondVal = GET_REGISTER(vsrc2); \ 666ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (secondVal == 0) { \ 66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen EXPORT_PC(); \ 668fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org dvmThrowArithmeticException("divide by zero"); \ 669303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org GOTO_exceptionThrown(); \ 670ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } \ 67159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org if ((u4)firstVal == 0x80000000 && secondVal == -1) { \ 67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (_chkdiv == 1) \ 67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = firstVal; /* division */ \ 674ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org else \ 67559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org result = 0; /* remainder */ \ 676ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } else { \ 6773d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org result = firstVal _op secondVal; \ 6783d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } \ 6793d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org SET_REGISTER(vdst, result); \ 68059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } else { \ 681ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org /* non-div/rem case */ \ 6829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org SET_REGISTER(vdst, \ 6839ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org (s4) GET_REGISTER(vsrc1) _op (s4) GET_REGISTER(vsrc2)); \ 6849ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } \ 6857b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } \ 68643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FINISH(2); 687ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 688ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#define HANDLE_OP_SHX_INT(_opcode, _opname, _cast, _op) \ 689ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 69057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org { \ 6916bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org u2 srcRegs; \ 6928e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org vdst = INST_AA(inst); \ 693fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org srcRegs = FETCH(1); \ 6943d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org vsrc1 = srcRegs & 0xff; \ 695fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc2 = srcRegs >> 8; \ 696fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("|%s-int v%d,v%d", (_opname), vdst, vsrc1); \ 697fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SET_REGISTER(vdst, \ 698fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org _cast GET_REGISTER(vsrc1) _op (GET_REGISTER(vsrc2) & 0x1f)); \ 699fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } \ 700fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org FINISH(2); 701fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 7023d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org#define HANDLE_OP_X_INT_LIT16(_opcode, _opname, _op, _chkdiv) \ 7032efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org HANDLE_OPCODE(_opcode /*vA, vB, #+CCCC*/) \ 7042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org vdst = INST_A(inst); \ 7052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org vsrc1 = INST_B(inst); \ 7062efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org vsrc2 = FETCH(1); \ 7072efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org ILOGV("|%s-int/lit16 v%d,v%d,#+0x%04x", \ 7082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org (_opname), vdst, vsrc1, vsrc2); \ 7092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (_chkdiv != 0) { \ 7106bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org s4 firstVal, result; \ 711fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org firstVal = GET_REGISTER(vsrc1); \ 712fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if ((s2) vsrc2 == 0) { \ 713fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org EXPORT_PC(); \ 714fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org dvmThrowArithmeticException("divide by zero"); \ 715fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org GOTO_exceptionThrown(); \ 7166bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } \ 71743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if ((u4)firstVal == 0x80000000 && ((s2) vsrc2) == -1) { \ 718003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org /* won't generate /lit16 instr for this; check anyway */ \ 719fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (_chkdiv == 1) \ 720bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org result = firstVal; /* division */ \ 7216bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org else \ 7229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org result = 0; /* remainder */ \ 7239ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } else { \ 724fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org result = firstVal _op (s2) vsrc2; \ 7259ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } \ 7269ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org SET_REGISTER(vdst, result); \ 7279ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org } else { \ 72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen /* non-div/rem case */ \ 729fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SET_REGISTER(vdst, GET_REGISTER(vsrc1) _op (s2) vsrc2); \ 730fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } \ 731fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org FINISH(2); 732fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 733fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org#define HANDLE_OP_X_INT_LIT8(_opcode, _opname, _op, _chkdiv) \ 734fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/) \ 735fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org { \ 7369ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org u2 litInfo; \ 737fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vdst = INST_AA(inst); \ 738fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org litInfo = FETCH(1); \ 739fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc1 = litInfo & 0xff; \ 740fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org vsrc2 = litInfo >> 8; /* constant */ \ 741fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x", \ 742fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org (_opname), vdst, vsrc1, vsrc2); \ 743fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (_chkdiv != 0) { \ 744394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com s4 firstVal, result; \ 745fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org firstVal = GET_REGISTER(vsrc1); \ 746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if ((s1) vsrc2 == 0) { \ 747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EXPORT_PC(); \ 7487b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org dvmThrowArithmeticException("divide by zero"); \ 74943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GOTO_exceptionThrown(); \ 7503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } \ 751eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if ((u4)firstVal == 0x80000000 && ((s1) vsrc2) == -1) { \ 752750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (_chkdiv == 1) \ 753750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org result = firstVal; /* division */ \ 754750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org else \ 755003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org result = 0; /* remainder */ \ 756003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else { \ 757750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org result = firstVal _op ((s1) vsrc2); \ 758003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } \ 75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SET_REGISTER(vdst, result); \ 76043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { \ 76143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SET_REGISTER(vdst, \ 76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (s4) GET_REGISTER(vsrc1) _op (s1) vsrc2); \ 763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } \ 76440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } \ 765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org FINISH(2); 766a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 767a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define HANDLE_OP_SHX_INT_LIT8(_opcode, _opname, _cast, _op) \ 768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, #+CC*/) \ 769a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { \ 7708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org u2 litInfo; \ 7717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org vdst = INST_AA(inst); \ 772fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org litInfo = FETCH(1); \ 773a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vsrc1 = litInfo & 0xff; \ 774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vsrc2 = litInfo >> 8; /* constant */ \ 775a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ILOGV("|%s-int/lit8 v%d,v%d,#+0x%02x", \ 77625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org (_opname), vdst, vsrc1, vsrc2); \ 777a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SET_REGISTER(vdst, \ 77825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org _cast GET_REGISTER(vsrc1) _op (vsrc2 & 0x1f)); \ 779a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } \ 780a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org FINISH(2); 781a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 78225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org#define HANDLE_OP_X_INT_2ADDR(_opcode, _opname, _op, _chkdiv) \ 78325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 784a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vdst = INST_A(inst); \ 785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vsrc1 = INST_B(inst); \ 786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (_chkdiv != 0) { \ 788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org s4 firstVal, secondVal, result; \ 7898432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org firstVal = GET_REGISTER(vdst); \ 7908432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org secondVal = GET_REGISTER(vsrc1); \ 7918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (secondVal == 0) { \ 7928432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org EXPORT_PC(); \ 7934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org dvmThrowArithmeticException("divide by zero"); \ 7948432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org GOTO_exceptionThrown(); \ 795a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } \ 796a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if ((u4)firstVal == 0x80000000 && secondVal == -1) { \ 797fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (_chkdiv == 1) \ 7988432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org result = firstVal; /* division */ \ 799fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org else \ 8004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org result = 0; /* remainder */ \ 8014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } else { \ 8028432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org result = firstVal _op secondVal; \ 8038432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org } \ 804a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SET_REGISTER(vdst, result); \ 805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { \ 806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org SET_REGISTER(vdst, \ 807b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org (s4) GET_REGISTER(vdst) _op (s4) GET_REGISTER(vsrc1)); \ 808b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } \ 809b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org FINISH(1); 810b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 811b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org#define HANDLE_OP_SHX_INT_2ADDR(_opcode, _opname, _cast, _op) \ 812b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 813b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org vdst = INST_A(inst); \ 814b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org vsrc1 = INST_B(inst); \ 815b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ILOGV("|%s-int-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 816b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org SET_REGISTER(vdst, \ 817b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org _cast GET_REGISTER(vdst) _op (GET_REGISTER(vsrc1) & 0x1f)); \ 818b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org FINISH(1); 81941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 820ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define HANDLE_OP_X_LONG(_opcode, _opname, _op, _chkdiv) \ 821ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 822a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org { \ 823a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org u2 srcRegs; \ 824a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vdst = INST_AA(inst); \ 825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org srcRegs = FETCH(1); \ 826fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org vsrc1 = srcRegs & 0xff; \ 827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org vsrc2 = srcRegs >> 8; \ 8288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (_chkdiv != 0) { \ 830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org s8 firstVal, secondVal, result; \ 831a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org firstVal = GET_REGISTER_WIDE(vsrc1); \ 832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org secondVal = GET_REGISTER_WIDE(vsrc2); \ 833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (secondVal == 0LL) { \ 834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org EXPORT_PC(); \ 835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org dvmThrowArithmeticException("divide by zero"); \ 836fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GOTO_exceptionThrown(); \ 837fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } \ 838fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if ((u8)firstVal == 0x8000000000000000ULL && \ 839fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org secondVal == -1LL) \ 840fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org { \ 841fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (_chkdiv == 1) \ 842fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org result = firstVal; /* division */ \ 843fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org else \ 844a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result = 0; /* remainder */ \ 845a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { \ 846a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org result = firstVal _op secondVal; \ 847a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } \ 8483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org SET_REGISTER_WIDE(vdst, result); \ 849212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } else { \ 8503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org SET_REGISTER_WIDE(vdst, \ 851212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org (s8) GET_REGISTER_WIDE(vsrc1) _op (s8) GET_REGISTER_WIDE(vsrc2)); \ 852a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } \ 853212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } \ 854212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org FINISH(2); 855a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 856a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define HANDLE_OP_SHX_LONG(_opcode, _opname, _cast, _op) \ 8579fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 858ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org { \ 859ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org u2 srcRegs; \ 860ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org vdst = INST_AA(inst); \ 861ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org srcRegs = FETCH(1); \ 862ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org vsrc1 = srcRegs & 0xff; \ 863ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org vsrc2 = srcRegs >> 8; \ 864ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org ILOGV("|%s-long v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 865ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org SET_REGISTER_WIDE(vdst, \ 866ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org _cast GET_REGISTER_WIDE(vsrc1) _op (GET_REGISTER(vsrc2) & 0x3f)); \ 867ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } \ 868837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org FINISH(2); 869ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 870ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org#define HANDLE_OP_X_LONG_2ADDR(_opcode, _opname, _op, _chkdiv) \ 871ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HANDLE_OPCODE(_opcode /*vA, vB*/) \ 872ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org vdst = INST_A(inst); \ 8739fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org vsrc1 = INST_B(inst); \ 8749fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 875b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org if (_chkdiv != 0) { \ 8769fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org s8 firstVal, secondVal, result; \ 877b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org firstVal = GET_REGISTER_WIDE(vdst); \ 8789fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org secondVal = GET_REGISTER_WIDE(vsrc1); \ 8799fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org if (secondVal == 0LL) { \ 8809fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org EXPORT_PC(); \ 88140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org dvmThrowArithmeticException("divide by zero"); \ 882212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org GOTO_exceptionThrown(); \ 883212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } \ 884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if ((u8)firstVal == 0x8000000000000000ULL && \ 885e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org secondVal == -1LL) \ 8867bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org { \ 887e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (_chkdiv == 1) \ 888e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org result = firstVal; /* division */ \ 889ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org else \ 89025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org result = 0; /* remainder */ \ 891ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { \ 892b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org result = firstVal _op secondVal; \ 893ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } \ 89459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org SET_REGISTER_WIDE(vdst, result); \ 89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { \ 89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SET_REGISTER_WIDE(vdst, \ 89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen (s8) GET_REGISTER_WIDE(vdst) _op (s8)GET_REGISTER_WIDE(vsrc1));\ 898 } \ 899 FINISH(1); 900 901#define HANDLE_OP_SHX_LONG_2ADDR(_opcode, _opname, _cast, _op) \ 902 HANDLE_OPCODE(_opcode /*vA, vB*/) \ 903 vdst = INST_A(inst); \ 904 vsrc1 = INST_B(inst); \ 905 ILOGV("|%s-long-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 906 SET_REGISTER_WIDE(vdst, \ 907 _cast GET_REGISTER_WIDE(vdst) _op (GET_REGISTER(vsrc1) & 0x3f)); \ 908 FINISH(1); 909 910#define HANDLE_OP_X_FLOAT(_opcode, _opname, _op) \ 911 HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 912 { \ 913 u2 srcRegs; \ 914 vdst = INST_AA(inst); \ 915 srcRegs = FETCH(1); \ 916 vsrc1 = srcRegs & 0xff; \ 917 vsrc2 = srcRegs >> 8; \ 918 ILOGV("|%s-float v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 919 SET_REGISTER_FLOAT(vdst, \ 920 GET_REGISTER_FLOAT(vsrc1) _op GET_REGISTER_FLOAT(vsrc2)); \ 921 } \ 922 FINISH(2); 923 924#define HANDLE_OP_X_DOUBLE(_opcode, _opname, _op) \ 925 HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 926 { \ 927 u2 srcRegs; \ 928 vdst = INST_AA(inst); \ 929 srcRegs = FETCH(1); \ 930 vsrc1 = srcRegs & 0xff; \ 931 vsrc2 = srcRegs >> 8; \ 932 ILOGV("|%s-double v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 933 SET_REGISTER_DOUBLE(vdst, \ 934 GET_REGISTER_DOUBLE(vsrc1) _op GET_REGISTER_DOUBLE(vsrc2)); \ 935 } \ 936 FINISH(2); 937 938#define HANDLE_OP_X_FLOAT_2ADDR(_opcode, _opname, _op) \ 939 HANDLE_OPCODE(_opcode /*vA, vB*/) \ 940 vdst = INST_A(inst); \ 941 vsrc1 = INST_B(inst); \ 942 ILOGV("|%s-float-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 943 SET_REGISTER_FLOAT(vdst, \ 944 GET_REGISTER_FLOAT(vdst) _op GET_REGISTER_FLOAT(vsrc1)); \ 945 FINISH(1); 946 947#define HANDLE_OP_X_DOUBLE_2ADDR(_opcode, _opname, _op) \ 948 HANDLE_OPCODE(_opcode /*vA, vB*/) \ 949 vdst = INST_A(inst); \ 950 vsrc1 = INST_B(inst); \ 951 ILOGV("|%s-double-2addr v%d,v%d", (_opname), vdst, vsrc1); \ 952 SET_REGISTER_DOUBLE(vdst, \ 953 GET_REGISTER_DOUBLE(vdst) _op GET_REGISTER_DOUBLE(vsrc1)); \ 954 FINISH(1); 955 956#define HANDLE_OP_AGET(_opcode, _opname, _type, _regsize) \ 957 HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 958 { \ 959 ArrayObject* arrayObj; \ 960 u2 arrayInfo; \ 961 EXPORT_PC(); \ 962 vdst = INST_AA(inst); \ 963 arrayInfo = FETCH(1); \ 964 vsrc1 = arrayInfo & 0xff; /* array ptr */ \ 965 vsrc2 = arrayInfo >> 8; /* index */ \ 966 ILOGV("|aget%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 967 arrayObj = (ArrayObject*) GET_REGISTER(vsrc1); \ 968 if (!checkForNull((Object*) arrayObj)) \ 969 GOTO_exceptionThrown(); \ 970 if (GET_REGISTER(vsrc2) >= arrayObj->length) { \ 971 dvmThrowArrayIndexOutOfBoundsException( \ 972 arrayObj->length, GET_REGISTER(vsrc2)); \ 973 GOTO_exceptionThrown(); \ 974 } \ 975 SET_REGISTER##_regsize(vdst, \ 976 ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)]); \ 977 ILOGV("+ AGET[%d]=%#x", GET_REGISTER(vsrc2), GET_REGISTER(vdst)); \ 978 } \ 979 FINISH(2); 980 981#define HANDLE_OP_APUT(_opcode, _opname, _type, _regsize) \ 982 HANDLE_OPCODE(_opcode /*vAA, vBB, vCC*/) \ 983 { \ 984 ArrayObject* arrayObj; \ 985 u2 arrayInfo; \ 986 EXPORT_PC(); \ 987 vdst = INST_AA(inst); /* AA: source value */ \ 988 arrayInfo = FETCH(1); \ 989 vsrc1 = arrayInfo & 0xff; /* BB: array ptr */ \ 990 vsrc2 = arrayInfo >> 8; /* CC: index */ \ 991 ILOGV("|aput%s v%d,v%d,v%d", (_opname), vdst, vsrc1, vsrc2); \ 992 arrayObj = (ArrayObject*) GET_REGISTER(vsrc1); \ 993 if (!checkForNull((Object*) arrayObj)) \ 994 GOTO_exceptionThrown(); \ 995 if (GET_REGISTER(vsrc2) >= arrayObj->length) { \ 996 dvmThrowArrayIndexOutOfBoundsException( \ 997 arrayObj->length, GET_REGISTER(vsrc2)); \ 998 GOTO_exceptionThrown(); \ 999 } \ 1000 ILOGV("+ APUT[%d]=0x%08x", GET_REGISTER(vsrc2), GET_REGISTER(vdst));\ 1001 ((_type*)(void*)arrayObj->contents)[GET_REGISTER(vsrc2)] = \ 1002 GET_REGISTER##_regsize(vdst); \ 1003 } \ 1004 FINISH(2); 1005 1006/* 1007 * It's possible to get a bad value out of a field with sub-32-bit stores 1008 * because the -quick versions always operate on 32 bits. Consider: 1009 * short foo = -1 (sets a 32-bit register to 0xffffffff) 1010 * iput-quick foo (writes all 32 bits to the field) 1011 * short bar = 1 (sets a 32-bit register to 0x00000001) 1012 * iput-short (writes the low 16 bits to the field) 1013 * iget-quick foo (reads all 32 bits from the field, yielding 0xffff0001) 1014 * This can only happen when optimized and non-optimized code has interleaved 1015 * access to the same field. This is unlikely but possible. 1016 * 1017 * The easiest way to fix this is to always read/write 32 bits at a time. On 1018 * a device with a 16-bit data bus this is sub-optimal. (The alternative 1019 * approach is to have sub-int versions of iget-quick, but now we're wasting 1020 * Dalvik instruction space and making it less likely that handler code will 1021 * already be in the CPU i-cache.) 1022 */ 1023#define HANDLE_IGET_X(_opcode, _opname, _ftype, _regsize) \ 1024 HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/) \ 1025 { \ 1026 InstField* ifield; \ 1027 Object* obj; \ 1028 EXPORT_PC(); \ 1029 vdst = INST_A(inst); \ 1030 vsrc1 = INST_B(inst); /* object ptr */ \ 1031 ref = FETCH(1); /* field ref */ \ 1032 ILOGV("|iget%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \ 1033 obj = (Object*) GET_REGISTER(vsrc1); \ 1034 if (!checkForNull(obj)) \ 1035 GOTO_exceptionThrown(); \ 1036 ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref); \ 1037 if (ifield == NULL) { \ 1038 ifield = dvmResolveInstField(curMethod->clazz, ref); \ 1039 if (ifield == NULL) \ 1040 GOTO_exceptionThrown(); \ 1041 } \ 1042 SET_REGISTER##_regsize(vdst, \ 1043 dvmGetField##_ftype(obj, ifield->byteOffset)); \ 1044 ILOGV("+ IGET '%s'=0x%08llx", ifield->name, \ 1045 (u8) GET_REGISTER##_regsize(vdst)); \ 1046 } \ 1047 FINISH(2); 1048 1049#define HANDLE_IGET_X_QUICK(_opcode, _opname, _ftype, _regsize) \ 1050 HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/) \ 1051 { \ 1052 Object* obj; \ 1053 vdst = INST_A(inst); \ 1054 vsrc1 = INST_B(inst); /* object ptr */ \ 1055 ref = FETCH(1); /* field offset */ \ 1056 ILOGV("|iget%s-quick v%d,v%d,field@+%u", \ 1057 (_opname), vdst, vsrc1, ref); \ 1058 obj = (Object*) GET_REGISTER(vsrc1); \ 1059 if (!checkForNullExportPC(obj, fp, pc)) \ 1060 GOTO_exceptionThrown(); \ 1061 SET_REGISTER##_regsize(vdst, dvmGetField##_ftype(obj, ref)); \ 1062 ILOGV("+ IGETQ %d=0x%08llx", ref, \ 1063 (u8) GET_REGISTER##_regsize(vdst)); \ 1064 } \ 1065 FINISH(2); 1066 1067#define HANDLE_IPUT_X(_opcode, _opname, _ftype, _regsize) \ 1068 HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/) \ 1069 { \ 1070 InstField* ifield; \ 1071 Object* obj; \ 1072 EXPORT_PC(); \ 1073 vdst = INST_A(inst); \ 1074 vsrc1 = INST_B(inst); /* object ptr */ \ 1075 ref = FETCH(1); /* field ref */ \ 1076 ILOGV("|iput%s v%d,v%d,field@0x%04x", (_opname), vdst, vsrc1, ref); \ 1077 obj = (Object*) GET_REGISTER(vsrc1); \ 1078 if (!checkForNull(obj)) \ 1079 GOTO_exceptionThrown(); \ 1080 ifield = (InstField*) dvmDexGetResolvedField(methodClassDex, ref); \ 1081 if (ifield == NULL) { \ 1082 ifield = dvmResolveInstField(curMethod->clazz, ref); \ 1083 if (ifield == NULL) \ 1084 GOTO_exceptionThrown(); \ 1085 } \ 1086 dvmSetField##_ftype(obj, ifield->byteOffset, \ 1087 GET_REGISTER##_regsize(vdst)); \ 1088 ILOGV("+ IPUT '%s'=0x%08llx", ifield->name, \ 1089 (u8) GET_REGISTER##_regsize(vdst)); \ 1090 } \ 1091 FINISH(2); 1092 1093#define HANDLE_IPUT_X_QUICK(_opcode, _opname, _ftype, _regsize) \ 1094 HANDLE_OPCODE(_opcode /*vA, vB, field@CCCC*/) \ 1095 { \ 1096 Object* obj; \ 1097 vdst = INST_A(inst); \ 1098 vsrc1 = INST_B(inst); /* object ptr */ \ 1099 ref = FETCH(1); /* field offset */ \ 1100 ILOGV("|iput%s-quick v%d,v%d,field@0x%04x", \ 1101 (_opname), vdst, vsrc1, ref); \ 1102 obj = (Object*) GET_REGISTER(vsrc1); \ 1103 if (!checkForNullExportPC(obj, fp, pc)) \ 1104 GOTO_exceptionThrown(); \ 1105 dvmSetField##_ftype(obj, ref, GET_REGISTER##_regsize(vdst)); \ 1106 ILOGV("+ IPUTQ %d=0x%08llx", ref, \ 1107 (u8) GET_REGISTER##_regsize(vdst)); \ 1108 } \ 1109 FINISH(2); 1110 1111/* 1112 * The JIT needs dvmDexGetResolvedField() to return non-null. 1113 * Because the portable interpreter is not involved with the JIT 1114 * and trace building, we only need the extra check here when this 1115 * code is massaged into a stub called from an assembly interpreter. 1116 * This is controlled by the JIT_STUB_HACK maco. 1117 */ 1118 1119#define HANDLE_SGET_X(_opcode, _opname, _ftype, _regsize) \ 1120 HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/) \ 1121 { \ 1122 StaticField* sfield; \ 1123 vdst = INST_AA(inst); \ 1124 ref = FETCH(1); /* field ref */ \ 1125 ILOGV("|sget%s v%d,sfield@0x%04x", (_opname), vdst, ref); \ 1126 sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \ 1127 if (sfield == NULL) { \ 1128 EXPORT_PC(); \ 1129 sfield = dvmResolveStaticField(curMethod->clazz, ref); \ 1130 if (sfield == NULL) \ 1131 GOTO_exceptionThrown(); \ 1132 if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) { \ 1133 JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc)); \ 1134 } \ 1135 } \ 1136 SET_REGISTER##_regsize(vdst, dvmGetStaticField##_ftype(sfield)); \ 1137 ILOGV("+ SGET '%s'=0x%08llx", \ 1138 sfield->name, (u8)GET_REGISTER##_regsize(vdst)); \ 1139 } \ 1140 FINISH(2); 1141 1142#define HANDLE_SPUT_X(_opcode, _opname, _ftype, _regsize) \ 1143 HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/) \ 1144 { \ 1145 StaticField* sfield; \ 1146 vdst = INST_AA(inst); \ 1147 ref = FETCH(1); /* field ref */ \ 1148 ILOGV("|sput%s v%d,sfield@0x%04x", (_opname), vdst, ref); \ 1149 sfield = (StaticField*)dvmDexGetResolvedField(methodClassDex, ref); \ 1150 if (sfield == NULL) { \ 1151 EXPORT_PC(); \ 1152 sfield = dvmResolveStaticField(curMethod->clazz, ref); \ 1153 if (sfield == NULL) \ 1154 GOTO_exceptionThrown(); \ 1155 if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) { \ 1156 JIT_STUB_HACK(dvmJitEndTraceSelect(self,pc)); \ 1157 } \ 1158 } \ 1159 dvmSetStaticField##_ftype(sfield, GET_REGISTER##_regsize(vdst)); \ 1160 ILOGV("+ SPUT '%s'=0x%08llx", \ 1161 sfield->name, (u8)GET_REGISTER##_regsize(vdst)); \ 1162 } \ 1163 FINISH(2); 1164 1165/* File: cstubs/enddefs.cpp */ 1166 1167/* undefine "magic" name remapping */ 1168#undef retval 1169#undef pc 1170#undef fp 1171#undef curMethod 1172#undef methodClassDex 1173#undef self 1174#undef debugTrackedRefStart 1175 1176/* File: armv5te/debug.cpp */ 1177#include <inttypes.h> 1178 1179/* 1180 * Dump the fixed-purpose ARM registers, along with some other info. 1181 * 1182 * This function MUST be compiled in ARM mode -- THUMB will yield bogus 1183 * results. 1184 * 1185 * This will NOT preserve r0-r3/ip. 1186 */ 1187void dvmMterpDumpArmRegs(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3) 1188{ 1189 // TODO: Clang does not support asm declaration syntax. 1190#ifndef __clang__ 1191 register uint32_t rPC asm("r4"); 1192 register uint32_t rFP asm("r5"); 1193 register uint32_t rSELF asm("r6"); 1194 register uint32_t rINST asm("r7"); 1195 register uint32_t rIBASE asm("r8"); 1196 register uint32_t r9 asm("r9"); 1197 register uint32_t r10 asm("r10"); 1198 1199 //extern char dvmAsmInstructionStart[]; 1200 1201 printf("REGS: r0=%08x r1=%08x r2=%08x r3=%08x\n", r0, r1, r2, r3); 1202 printf(" : rPC=%08x rFP=%08x rSELF=%08x rINST=%08x\n", 1203 rPC, rFP, rSELF, rINST); 1204 printf(" : rIBASE=%08x r9=%08x r10=%08x\n", rIBASE, r9, r10); 1205#endif 1206 1207 //Thread* self = (Thread*) rSELF; 1208 //const Method* method = self->method; 1209 printf(" + self is %p\n", dvmThreadSelf()); 1210 //printf(" + currently in %s.%s %s\n", 1211 // method->clazz->descriptor, method->name, method->shorty); 1212 //printf(" + dvmAsmInstructionStart = %p\n", dvmAsmInstructionStart); 1213 //printf(" + next handler for 0x%02x = %p\n", 1214 // rINST & 0xff, dvmAsmInstructionStart + (rINST & 0xff) * 64); 1215} 1216 1217/* 1218 * Dump the StackSaveArea for the specified frame pointer. 1219 */ 1220void dvmDumpFp(void* fp, StackSaveArea* otherSaveArea) 1221{ 1222 StackSaveArea* saveArea = SAVEAREA_FROM_FP(fp); 1223 printf("StackSaveArea for fp %p [%p/%p]:\n", fp, saveArea, otherSaveArea); 1224#ifdef EASY_GDB 1225 printf(" prevSave=%p, prevFrame=%p savedPc=%p meth=%p curPc=%p\n", 1226 saveArea->prevSave, saveArea->prevFrame, saveArea->savedPc, 1227 saveArea->method, saveArea->xtra.currentPc); 1228#else 1229 printf(" prevFrame=%p savedPc=%p meth=%p curPc=%p fp[0]=0x%08x\n", 1230 saveArea->prevFrame, saveArea->savedPc, 1231 saveArea->method, saveArea->xtra.currentPc, 1232 *(u4*)fp); 1233#endif 1234} 1235 1236/* 1237 * Does the bulk of the work for common_printMethod(). 1238 */ 1239void dvmMterpPrintMethod(Method* method) 1240{ 1241 /* 1242 * It is a direct (non-virtual) method if it is static, private, 1243 * or a constructor. 1244 */ 1245 bool isDirect = 1246 ((method->accessFlags & (ACC_STATIC|ACC_PRIVATE)) != 0) || 1247 (method->name[0] == '<'); 1248 1249 char* desc = dexProtoCopyMethodDescriptor(&method->prototype); 1250 1251 printf("<%c:%s.%s %s> ", 1252 isDirect ? 'D' : 'V', 1253 method->clazz->descriptor, 1254 method->name, 1255 desc); 1256 1257 free(desc); 1258} 1259 1260