summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/x86/BytecodeVisitor.cpp
diff options
context:
space:
mode:
authorDong-Yuan Chen <dong-yuan.chen@intel.com>2012-07-03 13:13:07 -0700
committerElliott Hughes <enh@google.com>2012-07-20 12:27:18 -0700
commit0c2dc522d0e120f346cf0a40c8cf0c93346131c2 (patch)
treef7ca4c8e3ca1150b7e8c5f4b68c60972641dc77f /vm/compiler/codegen/x86/BytecodeVisitor.cpp
parentabede656a1f2330e3d31281fb208be7c04e8eb56 (diff)
downloadandroid_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.gz
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.tar.bz2
android_dalvik-0c2dc522d0e120f346cf0a40c8cf0c93346131c2.zip
[X86] X86 trace JIT compiler support
This patch provides a fully functional x86 trace JIT compiler for Dalvik VM. It is built on top of the existing x86 fast interpreter with bug fixes and needed extension to support trace JIT interface. The x86 trace JIT code generator was developed independent of the existing template-based code generator and thus does not share exactly the same infrastructure. Included in this patch are: * Deprecated and removed the x86-atom fast interpreter that is no longer functional since ICS. * Augmented x86 fast interpreter to provide interfaces for x86 trace JIT compiler. * Added x86 trace JIT code generator with full JDWP debugging support. * Method JIT and self-verification mode are not supported. The x86 code generator uses the x86 instruction encoder/decoder library from the Apache Harmony project. Additional wrapper extension and bug fixes were added to support the x86 trace JIT code generator. The x86 instruction encoder/decoder is embedded inside the x86 code generator under the libenc subdirectory. Change-Id: I241113681963a16c13a3562390813cbaaa6eedf0 Signed-off-by: Dong-Yuan Chen <dong-yuan.chen@intel.com> Signed-off-by: Yixin Shou <yixin.shou@intel.com> Signed-off-by: Johnnie Birch <johnnie.l.birch.jr@intel.com> Signed-off-by: Udayan <udayan.banerji@intel.com> Signed-off-by: Sushma Kyasaralli Thimmappa <sushma.kyasaralli.thimmappa@intel.com> Signed-off-by: Bijoy Jose <bijoy.a.jose@intel.com> Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com> Signed-off-by: Tim Hartley <timothy.d.hartley@intel.com>
Diffstat (limited to 'vm/compiler/codegen/x86/BytecodeVisitor.cpp')
-rw-r--r--vm/compiler/codegen/x86/BytecodeVisitor.cpp5468
1 files changed, 5468 insertions, 0 deletions
diff --git a/vm/compiler/codegen/x86/BytecodeVisitor.cpp b/vm/compiler/codegen/x86/BytecodeVisitor.cpp
new file mode 100644
index 000000000..1d3c70e5d
--- /dev/null
+++ b/vm/compiler/codegen/x86/BytecodeVisitor.cpp
@@ -0,0 +1,5468 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*! \file BytecodeVisitor.cpp
+ \brief This file implements visitors of the bytecode
+*/
+#include "libdex/DexOpcodes.h"
+#include "libdex/DexFile.h"
+#include "Lower.h"
+#include "AnalysisO1.h"
+
+//! Returns size of the current bytecode in u2 unit
+
+//!
+int getByteCodeSize() { //uses inst, unit in u2
+ switch (INST_INST(inst)) {
+ case OP_NOP:
+ return 1;
+ case OP_MOVE:
+ case OP_MOVE_OBJECT:
+ return 1;
+ case OP_MOVE_FROM16:
+ case OP_MOVE_OBJECT_FROM16:
+ return 2;
+ case OP_MOVE_16:
+ case OP_MOVE_OBJECT_16:
+ return 3;
+ case OP_MOVE_WIDE:
+ return 1;
+ case OP_MOVE_WIDE_FROM16:
+ return 2;
+ case OP_MOVE_WIDE_16:
+ return 3;
+ case OP_MOVE_RESULT:
+ case OP_MOVE_RESULT_OBJECT:
+ return 1;
+ case OP_MOVE_RESULT_WIDE:
+ return 1;
+ case OP_MOVE_EXCEPTION:
+ return 1;
+ case OP_RETURN_VOID:
+ case OP_RETURN_VOID_BARRIER:
+ return 1;
+ case OP_RETURN:
+ case OP_RETURN_OBJECT:
+ return 1;
+ case OP_RETURN_WIDE:
+ return 1;
+ case OP_CONST_4:
+ return 1;
+ case OP_CONST_16:
+ return 2;
+ case OP_CONST:
+ return 3;
+ case OP_CONST_HIGH16:
+ return 2;
+ case OP_CONST_WIDE_16:
+ return 2;
+ case OP_CONST_WIDE_32:
+ return 3;
+ case OP_CONST_WIDE:
+ return 5;
+ case OP_CONST_WIDE_HIGH16:
+ return 2;
+ case OP_CONST_STRING:
+ return 2;
+ case OP_CONST_STRING_JUMBO:
+ return 3;
+ case OP_CONST_CLASS:
+ return 2;
+ case OP_MONITOR_ENTER:
+ return 1;
+ case OP_MONITOR_EXIT:
+ return 1;
+ case OP_CHECK_CAST:
+ return 2;
+ case OP_INSTANCE_OF:
+ return 2;
+ case OP_ARRAY_LENGTH:
+ return 1;
+ case OP_NEW_INSTANCE:
+ return 2;
+ case OP_NEW_ARRAY:
+ return 2;
+ case OP_FILLED_NEW_ARRAY:
+ return 3;
+ case OP_FILLED_NEW_ARRAY_RANGE:
+ return 3;
+ case OP_FILL_ARRAY_DATA:
+ return 3;
+ case OP_THROW:
+ return 1;
+ case OP_THROW_VERIFICATION_ERROR:
+ return 2;
+ case OP_GOTO:
+ return 1;
+ case OP_GOTO_16:
+ return 2;
+ case OP_GOTO_32:
+ return 3;
+ case OP_PACKED_SWITCH:
+ return 3;
+ case OP_SPARSE_SWITCH:
+ return 3;
+ case OP_CMPL_FLOAT:
+ return 2;
+ case OP_CMPG_FLOAT:
+ return 2;
+ case OP_CMPL_DOUBLE:
+ return 2;
+ case OP_CMPG_DOUBLE:
+ return 2;
+ case OP_CMP_LONG:
+ return 2;
+ case OP_IF_EQ:
+ return 2;
+ case OP_IF_NE:
+ return 2;
+ case OP_IF_LT:
+ return 2;
+ case OP_IF_GE:
+ return 2;
+ case OP_IF_GT:
+ return 2;
+ case OP_IF_LE:
+ return 2;
+ case OP_IF_EQZ:
+ return 2;
+ case OP_IF_NEZ:
+ return 2;
+ case OP_IF_LTZ:
+ return 2;
+ case OP_IF_GEZ:
+ return 2;
+ case OP_IF_GTZ:
+ return 2;
+ case OP_IF_LEZ:
+ return 2;
+ case OP_AGET:
+ return 2;
+ case OP_AGET_WIDE:
+ return 2;
+ case OP_AGET_OBJECT:
+ return 2;
+ case OP_AGET_BOOLEAN:
+ return 2;
+ case OP_AGET_BYTE:
+ return 2;
+ case OP_AGET_CHAR:
+ return 2;
+ case OP_AGET_SHORT:
+ return 2;
+ case OP_APUT:
+ return 2;
+ case OP_APUT_WIDE:
+ return 2;
+ case OP_APUT_OBJECT:
+ return 2;
+ case OP_APUT_BOOLEAN:
+ return 2;
+ case OP_APUT_BYTE:
+ return 2;
+ case OP_APUT_CHAR:
+ return 2;
+ case OP_APUT_SHORT:
+ return 2;
+ case OP_IGET:
+ case OP_IGET_WIDE:
+ case OP_IGET_OBJECT:
+ case OP_IGET_VOLATILE:
+ case OP_IGET_WIDE_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IGET_BOOLEAN:
+ case OP_IGET_BYTE:
+ case OP_IGET_CHAR:
+ case OP_IGET_SHORT:
+ case OP_IPUT:
+ case OP_IPUT_WIDE:
+ case OP_IPUT_OBJECT:
+ case OP_IPUT_VOLATILE:
+ case OP_IPUT_WIDE_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_IPUT_BOOLEAN:
+ case OP_IPUT_BYTE:
+ case OP_IPUT_CHAR:
+ case OP_IPUT_SHORT:
+ return 2;
+ case OP_SGET:
+ case OP_SGET_WIDE:
+ case OP_SGET_OBJECT:
+ case OP_SGET_VOLATILE:
+ case OP_SGET_WIDE_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SGET_BOOLEAN:
+ case OP_SGET_BYTE:
+ case OP_SGET_CHAR:
+ case OP_SGET_SHORT:
+ case OP_SPUT:
+ case OP_SPUT_WIDE:
+ case OP_SPUT_OBJECT:
+ case OP_SPUT_VOLATILE:
+ case OP_SPUT_WIDE_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
+ case OP_SPUT_BOOLEAN:
+ case OP_SPUT_BYTE:
+ case OP_SPUT_CHAR:
+ case OP_SPUT_SHORT:
+ return 2;
+ case OP_INVOKE_VIRTUAL:
+ case OP_INVOKE_SUPER:
+ case OP_INVOKE_DIRECT:
+ case OP_INVOKE_STATIC:
+ case OP_INVOKE_INTERFACE:
+ case OP_INVOKE_VIRTUAL_RANGE:
+ case OP_INVOKE_SUPER_RANGE:
+ case OP_INVOKE_DIRECT_RANGE:
+ case OP_INVOKE_STATIC_RANGE:
+ case OP_INVOKE_INTERFACE_RANGE:
+ return 3;
+
+ case OP_NEG_INT:
+ case OP_NOT_INT:
+ case OP_NEG_LONG:
+ case OP_NOT_LONG:
+ case OP_NEG_FLOAT:
+ case OP_NEG_DOUBLE:
+ case OP_INT_TO_LONG:
+ case OP_INT_TO_FLOAT:
+ case OP_INT_TO_DOUBLE:
+ case OP_LONG_TO_INT:
+ case OP_LONG_TO_FLOAT:
+ case OP_LONG_TO_DOUBLE:
+ case OP_FLOAT_TO_INT:
+ case OP_FLOAT_TO_LONG:
+ case OP_FLOAT_TO_DOUBLE:
+ case OP_DOUBLE_TO_INT:
+ case OP_DOUBLE_TO_LONG:
+ case OP_DOUBLE_TO_FLOAT:
+ case OP_INT_TO_BYTE:
+ case OP_INT_TO_CHAR:
+ case OP_INT_TO_SHORT:
+ return 1;
+
+ case OP_ADD_INT:
+ case OP_SUB_INT:
+ case OP_MUL_INT:
+ case OP_DIV_INT:
+ case OP_REM_INT:
+ case OP_AND_INT:
+ case OP_OR_INT:
+ case OP_XOR_INT:
+ case OP_SHL_INT:
+ case OP_SHR_INT:
+ case OP_USHR_INT:
+ case OP_ADD_LONG:
+ case OP_SUB_LONG:
+ case OP_MUL_LONG:
+ case OP_DIV_LONG:
+ case OP_REM_LONG:
+ case OP_AND_LONG:
+ case OP_OR_LONG:
+ case OP_XOR_LONG:
+ case OP_SHL_LONG:
+ case OP_SHR_LONG:
+ case OP_USHR_LONG:
+ case OP_ADD_FLOAT:
+ case OP_SUB_FLOAT:
+ case OP_MUL_FLOAT:
+ case OP_DIV_FLOAT:
+ case OP_REM_FLOAT:
+ case OP_ADD_DOUBLE:
+ case OP_SUB_DOUBLE:
+ case OP_MUL_DOUBLE:
+ case OP_DIV_DOUBLE:
+ case OP_REM_DOUBLE:
+ return 2;
+
+ case OP_ADD_INT_2ADDR:
+ case OP_SUB_INT_2ADDR:
+ case OP_MUL_INT_2ADDR:
+ case OP_DIV_INT_2ADDR:
+ case OP_REM_INT_2ADDR:
+ case OP_AND_INT_2ADDR:
+ case OP_OR_INT_2ADDR:
+ case OP_XOR_INT_2ADDR:
+ case OP_SHL_INT_2ADDR:
+ case OP_SHR_INT_2ADDR:
+ case OP_USHR_INT_2ADDR:
+ case OP_ADD_LONG_2ADDR:
+ case OP_SUB_LONG_2ADDR:
+ case OP_MUL_LONG_2ADDR:
+ case OP_DIV_LONG_2ADDR:
+ case OP_REM_LONG_2ADDR:
+ case OP_AND_LONG_2ADDR:
+ case OP_OR_LONG_2ADDR:
+ case OP_XOR_LONG_2ADDR:
+ case OP_SHL_LONG_2ADDR:
+ case OP_SHR_LONG_2ADDR:
+ case OP_USHR_LONG_2ADDR:
+ case OP_ADD_FLOAT_2ADDR:
+ case OP_SUB_FLOAT_2ADDR:
+ case OP_MUL_FLOAT_2ADDR:
+ case OP_DIV_FLOAT_2ADDR:
+ case OP_REM_FLOAT_2ADDR:
+ case OP_ADD_DOUBLE_2ADDR:
+ case OP_SUB_DOUBLE_2ADDR:
+ case OP_MUL_DOUBLE_2ADDR:
+ case OP_DIV_DOUBLE_2ADDR:
+ case OP_REM_DOUBLE_2ADDR:
+ return 1;
+
+ case OP_ADD_INT_LIT16:
+ case OP_RSUB_INT:
+ case OP_MUL_INT_LIT16:
+ case OP_DIV_INT_LIT16:
+ case OP_REM_INT_LIT16:
+ case OP_AND_INT_LIT16:
+ case OP_OR_INT_LIT16:
+ case OP_XOR_INT_LIT16:
+ return 2;
+
+ case OP_ADD_INT_LIT8:
+ case OP_RSUB_INT_LIT8:
+ case OP_MUL_INT_LIT8:
+ case OP_DIV_INT_LIT8:
+ case OP_REM_INT_LIT8:
+ case OP_AND_INT_LIT8:
+ case OP_OR_INT_LIT8:
+ case OP_XOR_INT_LIT8:
+ case OP_SHL_INT_LIT8:
+ case OP_SHR_INT_LIT8:
+ case OP_USHR_INT_LIT8:
+ return 2;
+
+ case OP_EXECUTE_INLINE:
+ case OP_EXECUTE_INLINE_RANGE:
+ return 3;
+#if FIXME
+ case OP_INVOKE_OBJECT_INIT_RANGE:
+ return 3;
+#endif
+
+ case OP_IGET_QUICK:
+ case OP_IGET_WIDE_QUICK:
+ case OP_IGET_OBJECT_QUICK:
+ case OP_IPUT_QUICK:
+ case OP_IPUT_WIDE_QUICK:
+ case OP_IPUT_OBJECT_QUICK:
+ return 2;
+
+ case OP_INVOKE_VIRTUAL_QUICK:
+ case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+ case OP_INVOKE_SUPER_QUICK:
+ case OP_INVOKE_SUPER_QUICK_RANGE:
+ return 3;
+#ifdef SUPPORT_HLO
+ case kExtInstruction:
+ switch(inst) {
+ case OP_X_AGET_QUICK:
+ case OP_X_AGET_WIDE_QUICK:
+ case OP_X_AGET_OBJECT_QUICK:
+ case OP_X_AGET_BOOLEAN_QUICK:
+ case OP_X_AGET_BYTE_QUICK:
+ case OP_X_AGET_CHAR_QUICK:
+ case OP_X_AGET_SHORT_QUICK:
+ case OP_X_APUT_QUICK:
+ case OP_X_APUT_WIDE_QUICK:
+ case OP_X_APUT_OBJECT_QUICK:
+ case OP_X_APUT_BOOLEAN_QUICK:
+ case OP_X_APUT_BYTE_QUICK:
+ case OP_X_APUT_CHAR_QUICK:
+ case OP_X_APUT_SHORT_QUICK:
+ return 3;
+ case OP_X_DEREF_GET:
+ case OP_X_DEREF_GET_OBJECT:
+ case OP_X_DEREF_GET_WIDE:
+ case OP_X_DEREF_GET_BOOLEAN:
+ case OP_X_DEREF_GET_BYTE:
+ case OP_X_DEREF_GET_CHAR:
+ case OP_X_DEREF_GET_SHORT:
+ case OP_X_DEREF_PUT:
+ case OP_X_DEREF_PUT_WIDE:
+ case OP_X_DEREF_PUT_OBJECT:
+ case OP_X_DEREF_PUT_BOOLEAN:
+ case OP_X_DEREF_PUT_BYTE:
+ case OP_X_DEREF_PUT_CHAR:
+ case OP_X_DEREF_PUT_SHORT:
+ return 2;
+ case OP_X_ARRAY_CHECKS:
+ case OP_X_ARRAY_OBJECT_CHECKS:
+ return 3;
+ case OP_X_CHECK_BOUNDS:
+ case OP_X_CHECK_NULL:
+ case OP_X_CHECK_TYPE:
+ return 2;
+ }
+#endif
+ }
+ return -1;
+}
+//! reduces refCount of a virtual register
+
+//!
+void touchOneVR(u2 vA, LowOpndRegType type) {
+ int index = searchCompileTable(LowOpndRegType_virtual | type, vA);
+ if(index < 0) {
+ ALOGE("virtual reg %d type %d not found in touchOneVR", vA, type);
+ return;
+ }
+ compileTable[index].refCount--;
+}
+//! reduces refCount of two virtual registers
+
+//!
+void touchTwoVRs(u2 vA, u2 vB, LowOpndRegType type) {
+ int index = searchCompileTable(LowOpndRegType_virtual | type, vA);
+ if(index < 0) {
+ ALOGE("virtual reg vA %d type %d not found in touchTwoVRs", vA, type);
+ return;
+ }
+ compileTable[index].refCount--;
+ index = searchCompileTable(LowOpndRegType_virtual | type, vB);
+ if(index < 0) {
+ ALOGE("virtual reg vB %d type %d not found in touchTwoVRs", vB, type);
+ return;
+ }
+ compileTable[index].refCount--;
+}
+int num_const_worklist;
+//! worklist to update constVRTable later
+int constWorklist[10];
+
+int num_const_vr; //in a basic block
+//! table to store the constant information for virtual registers
+ConstVRInfo constVRTable[MAX_CONST_REG];
+//! update constVRTable for a given virtual register
+
+//! set "isConst" to false
+void setVRToNonConst(int regNum, OpndSize size) {
+ int k;
+ int indexL = -1;
+ int indexH = -1;
+ for(k = 0; k < num_const_vr; k++) {
+ if(constVRTable[k].regNum == regNum) {
+ indexL = k;
+ continue;
+ }
+ if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) {
+ indexH = k;
+ continue;
+ }
+ }
+ if(indexL >= 0) {
+ //remove this entry??
+ constVRTable[indexL].isConst = false;
+ }
+ if(size == OpndSize_64 && indexH >= 0) {
+ constVRTable[indexH].isConst = false;
+ }
+}
+//! update constVRTable for a given virtual register
+
+//! set "isConst" to true
+void setVRToConst(int regNum, OpndSize size, int* tmpValue) {
+ int k;
+ int indexL = -1;
+ int indexH = -1;
+ for(k = 0; k < num_const_vr; k++) {
+ if(constVRTable[k].regNum == regNum) {
+ indexL = k;
+ continue;
+ }
+ if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) {
+ indexH = k;
+ continue;
+ }
+ }
+ if(indexL < 0) {
+ indexL = num_const_vr;
+ constVRTable[indexL].regNum = regNum;
+ num_const_vr++;
+ }
+ constVRTable[indexL].isConst = true;
+ constVRTable[indexL].value = tmpValue[0];
+ if(size == OpndSize_64) {
+ if(indexH < 0) {
+ indexH = num_const_vr;
+ constVRTable[indexH].regNum = regNum+1;
+ num_const_vr++;
+ }
+ constVRTable[indexH].isConst = true;
+ constVRTable[indexH].value = tmpValue[1];
+ }
+ if(num_const_vr > MAX_CONST_REG) ALOGE("constVRTable overflows");
+ invalidateVRDueToConst(regNum, size);
+}
+
+//! perform work on constWorklist
+
+//!
+void updateConstInfo(BasicBlock_O1* bb) {
+ if(bb == NULL) return;
+ int k;
+ for(k = 0; k < num_const_worklist; k++) {
+ //int indexOrig = constWorklist[k];
+ //compileTable[indexOrig].isConst = false;
+ //int A = compileTable[indexOrig].regNum;
+ //LowOpndRegType type = compileTable[indexOrig].physicalType & MASK_FOR_TYPE;
+ setVRToNonConst(constWorklist[k], OpndSize_32);
+ }
+}
+//! check whether the current bytecode generates a const
+
+//! if yes, update constVRTable; otherwise, update constWorklist
+//! if a bytecode uses vA (const), and updates vA to non const, getConstInfo will return false and update constWorklist to make sure when lowering the bytecode, vA is treated as constant
+bool getConstInfo(BasicBlock_O1* bb) {
+ compileTableEntry* infoArray = compileTable;
+ u2 inst_op = INST_INST(inst);
+ u2 vA = 0, vB = 0, v1, v2;
+ u2 BBBB;
+ u2 tmp_u2;
+ s4 tmp_s4;
+ u4 tmp_u4;
+ int entry, tmpValue[2], tmpValue2[2];
+ num_const_worklist = 0;
+
+ switch(inst_op) {
+ //for other opcode, if update the register, set isConst to false
+ case OP_MOVE:
+ case OP_MOVE_OBJECT:
+ case OP_MOVE_FROM16:
+ case OP_MOVE_OBJECT_FROM16:
+ case OP_MOVE_16:
+ case OP_MOVE_OBJECT_16:
+ if(inst_op == OP_MOVE || inst_op == OP_MOVE_OBJECT) {
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ }
+ else if(inst_op == OP_MOVE_FROM16 || inst_op == OP_MOVE_OBJECT_FROM16) {
+ vA = INST_AA(inst);
+ vB = FETCH(1);
+ }
+ else if(inst_op == OP_MOVE_16 || inst_op == OP_MOVE_OBJECT_16) {
+ vA = FETCH(1);
+ vB = FETCH(2);
+ }
+ if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = tmpValue[0];
+ compileTable[entry].refCount--;
+ touchOneVR(vB, LowOpndRegType_gp);
+ return true;
+ } else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ }
+ return false;
+ case OP_MOVE_WIDE:
+ case OP_MOVE_WIDE_FROM16:
+ case OP_MOVE_WIDE_16:
+ if(inst_op == OP_MOVE_WIDE) {
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ }
+ else if(inst_op == OP_MOVE_WIDE_FROM16) {
+ vA = INST_AA(inst);
+ vB = FETCH(1);
+ }
+ else if(inst_op == OP_MOVE_WIDE_16) {
+ vA = FETCH(1);
+ vB = FETCH(2);
+ }
+ if(isVirtualRegConstant(vB, LowOpndRegType_xmm, tmpValue, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_xmm, true);
+ setVRToConst(vA, OpndSize_64, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(vB, LowOpndRegType_xmm);
+ return true;
+ } else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ }
+ return false;
+ case OP_MOVE_RESULT:
+ case OP_MOVE_RESULT_OBJECT:
+ case OP_MOVE_EXCEPTION:
+ case OP_CONST_STRING:
+ case OP_CONST_STRING_JUMBO:
+ case OP_CONST_CLASS:
+ case OP_NEW_INSTANCE:
+ case OP_CMPL_FLOAT:
+ case OP_CMPG_FLOAT:
+ case OP_CMPL_DOUBLE:
+ case OP_CMPG_DOUBLE:
+ case OP_AGET:
+ case OP_AGET_OBJECT:
+ case OP_AGET_BOOLEAN:
+ case OP_AGET_BYTE:
+ case OP_AGET_CHAR:
+ case OP_AGET_SHORT:
+ case OP_SGET:
+ case OP_SGET_OBJECT:
+ case OP_SGET_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SGET_BOOLEAN:
+ case OP_SGET_BYTE:
+ case OP_SGET_CHAR:
+ case OP_SGET_SHORT:
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_MOVE_RESULT_WIDE:
+ case OP_AGET_WIDE:
+ case OP_SGET_WIDE:
+ case OP_SGET_WIDE_VOLATILE:
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_INSTANCE_OF:
+ case OP_ARRAY_LENGTH:
+ case OP_NEW_ARRAY:
+ case OP_IGET:
+ case OP_IGET_OBJECT:
+ case OP_IGET_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IGET_BOOLEAN:
+ case OP_IGET_BYTE:
+ case OP_IGET_CHAR:
+ case OP_IGET_SHORT:
+ case OP_IGET_QUICK:
+ case OP_IGET_OBJECT_QUICK:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_IGET_WIDE:
+ case OP_IGET_WIDE_VOLATILE:
+ case OP_IGET_WIDE_QUICK:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ //TODO: constant folding for float/double/long ALU
+ case OP_ADD_FLOAT:
+ case OP_SUB_FLOAT:
+ case OP_MUL_FLOAT:
+ case OP_DIV_FLOAT:
+ case OP_REM_FLOAT:
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_ADD_DOUBLE:
+ case OP_SUB_DOUBLE:
+ case OP_MUL_DOUBLE:
+ case OP_DIV_DOUBLE:
+ case OP_REM_DOUBLE:
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_NEG_FLOAT:
+ case OP_INT_TO_FLOAT:
+ case OP_LONG_TO_FLOAT:
+ case OP_FLOAT_TO_INT:
+ case OP_DOUBLE_TO_INT:
+ case OP_ADD_FLOAT_2ADDR:
+ case OP_SUB_FLOAT_2ADDR:
+ case OP_MUL_FLOAT_2ADDR:
+ case OP_DIV_FLOAT_2ADDR:
+ case OP_REM_FLOAT_2ADDR:
+ case OP_DOUBLE_TO_FLOAT:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA; //change constWorklist to point to vA TODO
+ num_const_worklist++;
+ return false;
+ case OP_FLOAT_TO_LONG:
+ case OP_DOUBLE_TO_LONG:
+ case OP_FLOAT_TO_DOUBLE:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_NEG_DOUBLE:
+ case OP_INT_TO_DOUBLE: //fp stack
+ case OP_LONG_TO_DOUBLE:
+ case OP_ADD_DOUBLE_2ADDR:
+ case OP_SUB_DOUBLE_2ADDR:
+ case OP_MUL_DOUBLE_2ADDR:
+ case OP_DIV_DOUBLE_2ADDR:
+ case OP_REM_DOUBLE_2ADDR:
+ //ops on float, double
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_NEG_INT:
+ case OP_NOT_INT:
+ case OP_LONG_TO_INT:
+ case OP_INT_TO_BYTE:
+ case OP_INT_TO_CHAR:
+ case OP_INT_TO_SHORT:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ if(inst_op == OP_NEG_INT)
+ infoArray[entry].value[0] = -tmpValue[0];
+ if(inst_op == OP_NOT_INT)
+ infoArray[entry].value[0] = ~tmpValue[0]; //CHECK
+ if(inst_op == OP_LONG_TO_INT)
+ infoArray[entry].value[0] = tmpValue[0];
+ if(inst_op == OP_INT_TO_BYTE)// sar
+ infoArray[entry].value[0] = (tmpValue[0] << 24) >> 24;
+ if(inst_op == OP_INT_TO_CHAR) //shr
+ infoArray[entry].value[0] = ((unsigned int)(tmpValue[0] << 16)) >> 16;
+ if(inst_op == OP_INT_TO_SHORT) //sar
+ infoArray[entry].value[0] = (tmpValue[0] << 16) >> 16;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ }
+ else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ }
+ case OP_NEG_LONG:
+ case OP_NOT_LONG:
+ case OP_INT_TO_LONG:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1; //fixed on 10/15/2009
+ num_const_worklist++;
+ return false;
+ case OP_DIV_INT_2ADDR:
+ case OP_REM_INT_2ADDR:
+ case OP_REM_INT_LIT16:
+ case OP_DIV_INT_LIT16:
+ case OP_REM_INT_LIT8:
+ case OP_DIV_INT_LIT8:
+ case OP_DIV_INT:
+ case OP_REM_INT:
+ if(inst_op == OP_DIV_INT || inst_op == OP_DIV_INT_LIT8 ||
+ inst_op == OP_REM_INT || inst_op == OP_REM_INT_LIT8)
+ vA = INST_AA(inst);
+ else
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_ADD_INT_2ADDR:
+ case OP_SUB_INT_2ADDR:
+ case OP_MUL_INT_2ADDR:
+ case OP_AND_INT_2ADDR:
+ case OP_OR_INT_2ADDR:
+ case OP_XOR_INT_2ADDR:
+ case OP_SHL_INT_2ADDR:
+ case OP_SHR_INT_2ADDR:
+ case OP_USHR_INT_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ if(isVirtualRegConstant(vA, LowOpndRegType_gp, tmpValue, false) == 3 &&
+ isVirtualRegConstant(v2, LowOpndRegType_gp, tmpValue2, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ if(inst_op == OP_ADD_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] + tmpValue2[0];
+ if(inst_op == OP_SUB_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] - tmpValue2[0];
+ if(inst_op == OP_MUL_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] * tmpValue2[0];
+ if(inst_op == OP_DIV_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] / tmpValue2[0];
+ if(inst_op == OP_REM_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] % tmpValue2[0];
+ if(inst_op == OP_AND_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] & tmpValue2[0];
+ if(inst_op == OP_OR_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] | tmpValue2[0];
+ if(inst_op == OP_XOR_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] ^ tmpValue2[0];
+ if(inst_op == OP_SHL_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] << tmpValue2[0];
+ if(inst_op == OP_SHR_INT_2ADDR)
+ infoArray[entry].value[0] = tmpValue[0] >> tmpValue2[0];
+ if(inst_op == OP_USHR_INT_2ADDR)
+ infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmpValue2[0];
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(v2, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ }
+ else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ }
+ case OP_ADD_INT_LIT16:
+ case OP_RSUB_INT:
+ case OP_MUL_INT_LIT16:
+ case OP_AND_INT_LIT16:
+ case OP_OR_INT_LIT16:
+ case OP_XOR_INT_LIT16:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ tmp_s4 = (s2)FETCH(1);
+ if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ if(inst_op == OP_ADD_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] + tmp_s4;
+ if(inst_op == OP_RSUB_INT)
+ infoArray[entry].value[0] = tmp_s4 - tmpValue[0];
+ if(inst_op == OP_MUL_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] * tmp_s4;
+ if(inst_op == OP_DIV_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] / tmp_s4;
+ if(inst_op == OP_REM_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] % tmp_s4;
+ if(inst_op == OP_AND_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] & tmp_s4;
+ if(inst_op == OP_OR_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] | tmp_s4;
+ if(inst_op == OP_XOR_INT_LIT16)
+ infoArray[entry].value[0] = tmpValue[0] ^ tmp_s4;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ }
+ else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ }
+ case OP_ADD_INT:
+ case OP_SUB_INT:
+ case OP_MUL_INT:
+ case OP_AND_INT:
+ case OP_OR_INT:
+ case OP_XOR_INT:
+ case OP_SHL_INT:
+ case OP_SHR_INT:
+ case OP_USHR_INT:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ if(isVirtualRegConstant(v1, LowOpndRegType_gp, tmpValue, false) == 3 &&
+ isVirtualRegConstant(v2, LowOpndRegType_gp, tmpValue2, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ if(inst_op == OP_ADD_INT)
+ infoArray[entry].value[0] = tmpValue[0] + tmpValue2[0];
+ if(inst_op == OP_SUB_INT)
+ infoArray[entry].value[0] = tmpValue[0] - tmpValue2[0];
+ if(inst_op == OP_MUL_INT)
+ infoArray[entry].value[0] = tmpValue[0] * tmpValue2[0];
+ if(inst_op == OP_DIV_INT)
+ infoArray[entry].value[0] = tmpValue[0] / tmpValue2[0];
+ if(inst_op == OP_REM_INT)
+ infoArray[entry].value[0] = tmpValue[0] % tmpValue2[0];
+ if(inst_op == OP_AND_INT)
+ infoArray[entry].value[0] = tmpValue[0] & tmpValue2[0];
+ if(inst_op == OP_OR_INT)
+ infoArray[entry].value[0] = tmpValue[0] | tmpValue2[0];
+ if(inst_op == OP_XOR_INT)
+ infoArray[entry].value[0] = tmpValue[0] ^ tmpValue2[0];
+ if(inst_op == OP_SHL_INT)
+ infoArray[entry].value[0] = tmpValue[0] << tmpValue2[0];
+ if(inst_op == OP_SHR_INT)
+ infoArray[entry].value[0] = tmpValue[0] >> tmpValue2[0];
+ if(inst_op == OP_USHR_INT)
+ infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmpValue2[0];
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(v1, LowOpndRegType_gp);
+ touchOneVR(v2, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ }
+ else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ }
+ case OP_ADD_INT_LIT8: //INST_AA
+ case OP_RSUB_INT_LIT8:
+ case OP_MUL_INT_LIT8:
+ case OP_AND_INT_LIT8:
+ case OP_OR_INT_LIT8:
+ case OP_XOR_INT_LIT8:
+ case OP_SHL_INT_LIT8:
+ case OP_SHR_INT_LIT8:
+ case OP_USHR_INT_LIT8:
+ vA = INST_AA(inst);
+ vB = (u2)FETCH(1) & 0xff;
+ tmp_s4 = (s2)FETCH(1) >> 8;
+ if(isVirtualRegConstant(vB, LowOpndRegType_gp, tmpValue, false) == 3) {
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ if(inst_op == OP_ADD_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] + tmp_s4;
+ if(inst_op == OP_RSUB_INT_LIT8)
+ infoArray[entry].value[0] = tmp_s4 - tmpValue[0];
+ if(inst_op == OP_MUL_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] * tmp_s4;
+ if(inst_op == OP_DIV_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] / tmp_s4;
+ if(inst_op == OP_REM_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] % tmp_s4;
+ if(inst_op == OP_AND_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] & tmp_s4;
+ if(inst_op == OP_OR_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] | tmp_s4;
+ if(inst_op == OP_XOR_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] ^ tmp_s4;
+ if(inst_op == OP_SHL_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] << tmp_s4;
+ if(inst_op == OP_SHR_INT_LIT8)
+ infoArray[entry].value[0] = tmpValue[0] >> tmp_s4;
+ if(inst_op == OP_USHR_INT_LIT8)
+ infoArray[entry].value[0] = (unsigned int)tmpValue[0] >> tmp_s4;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+ touchOneVR(vB, LowOpndRegType_gp);
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ }
+ else {
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ }
+ case OP_ADD_LONG:
+ case OP_SUB_LONG:
+ case OP_AND_LONG:
+ case OP_OR_LONG:
+ case OP_XOR_LONG:
+ case OP_MUL_LONG:
+ case OP_DIV_LONG:
+ case OP_REM_LONG:
+ case OP_SHL_LONG:
+ case OP_SHR_LONG:
+ case OP_USHR_LONG:
+ //TODO bytecode is not going to update state registers
+ //constant folding
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_CMP_LONG:
+ vA = INST_AA(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_ADD_LONG_2ADDR:
+ case OP_SUB_LONG_2ADDR:
+ case OP_AND_LONG_2ADDR:
+ case OP_OR_LONG_2ADDR:
+ case OP_XOR_LONG_2ADDR:
+ case OP_MUL_LONG_2ADDR:
+ case OP_DIV_LONG_2ADDR:
+ case OP_REM_LONG_2ADDR:
+ case OP_SHL_LONG_2ADDR:
+ case OP_SHR_LONG_2ADDR:
+ case OP_USHR_LONG_2ADDR:
+ vA = INST_A(inst);
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_CONST_4:
+ vA = INST_A(inst);
+ tmp_s4 = (s4) (INST_B(inst) << 28) >> 28;
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = tmp_s4;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, tmp_s4);
+#endif
+ return true;
+ case OP_CONST_16:
+ BBBB = FETCH(1);
+ vA = INST_AA(inst);
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s2)BBBB;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u4)FETCH(2) << 16;
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u4;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST_HIGH16:
+ vA = INST_AA(inst);
+ tmp_u2 = FETCH(1);
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u2<<16;
+ tmpValue[0] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_32, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %d", vA, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST_WIDE_16:
+ vA = INST_AA(inst);
+ tmp_u2 = FETCH(1);
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s2)tmp_u2;
+ tmpValue[0] = infoArray[entry].value[0];
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+ entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s2)tmp_u2>>31;
+ tmpValue[1] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_64, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST_WIDE_32:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u4)FETCH(2) << 16;
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u4;
+ tmpValue[0] = infoArray[entry].value[0];
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+ entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u4>>31;
+ tmpValue[1] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_64, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST_WIDE:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u8)FETCH(2) << 16;
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u4;
+ tmpValue[0] = infoArray[entry].value[0];
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+ tmp_u4 = (u8)FETCH(3);
+ tmp_u4 |= (u8)FETCH(4) << 16;
+ entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u4;
+ tmpValue[1] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_64, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+ return true;
+ case OP_CONST_WIDE_HIGH16:
+ vA = INST_AA(inst);
+ tmp_u2 = FETCH(1);
+ entry = findVirtualRegInTable(vA, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = 0;
+ tmpValue[0] = infoArray[entry].value[0];
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA, infoArray[entry].value[0]);
+#endif
+
+ entry = findVirtualRegInTable(vA+1, LowOpndRegType_gp, true);
+ infoArray[entry].isConst = true;
+ infoArray[entry].value[0] = (s4)tmp_u2<<16;
+ tmpValue[1] = infoArray[entry].value[0];
+ setVRToConst(vA, OpndSize_64, tmpValue);
+ compileTable[entry].refCount--;
+#ifdef DEBUG_CONST
+ LOGD("getConstInfo: set VR %d to %x", vA+1, infoArray[entry].value[0]);
+#endif
+ return true;
+#ifdef SUPPORT_HLO
+ case OP_X_AGET_QUICK:
+ case OP_X_AGET_OBJECT_QUICK:
+ case OP_X_AGET_BOOLEAN_QUICK:
+ case OP_X_AGET_BYTE_QUICK:
+ case OP_X_AGET_CHAR_QUICK:
+ case OP_X_AGET_SHORT_QUICK:
+ vA = FETCH(1) & 0xff;
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_X_AGET_WIDE_QUICK:
+ vA = FETCH(1) & 0xff;
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+ case OP_X_DEREF_GET:
+ case OP_X_DEREF_GET_OBJECT:
+ case OP_X_DEREF_GET_BOOLEAN:
+ case OP_X_DEREF_GET_BYTE:
+ case OP_X_DEREF_GET_CHAR:
+ case OP_X_DEREF_GET_SHORT:
+ vA = FETCH(1) & 0xff;
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ return false;
+ case OP_X_DEREF_GET_WIDE:
+ vA = FETCH(1) & 0xff;
+ constWorklist[num_const_worklist] = vA;
+ num_const_worklist++;
+ constWorklist[num_const_worklist] = vA+1;
+ num_const_worklist++;
+ return false;
+#endif
+ }
+ return false;
+}
+
+//! This function updates infoArray with virtual registers accessed when lowering the bytecode, and returns size of the bytecode in unit of u2
+
+//! uses of virtual registers are added to infoArray first
+int getVirtualRegInfo(VirtualRegInfo* infoArray) {
+ u2 inst_op = INST_INST(inst);
+ u2 vA = 0, vB = 0, vref, vindex;
+ u2 v1, v2, length, vD, vG, vE, vF, count;
+ u4 v1_u4, v2_u4;
+ int kk, num, num_entry;
+ s4 tmp_s4;
+ s2 tmp_s2;
+ u4 tmp_u4;
+ int codeSize = 0;
+ num_regs_per_bytecode = 0;
+ //update infoArray[xx].allocConstraints
+ for(num = 0; num < MAX_REG_PER_BYTECODE; num++) {
+ for(kk = 0; kk < 8; kk++) {
+ infoArray[num].allocConstraints[kk].physicalReg = (PhysicalReg)kk;
+ infoArray[num].allocConstraints[kk].count = 0;
+ }
+ }
+
+ switch (inst_op) {
+ case OP_NOP:
+ codeSize = 1;
+ break;
+ case OP_MOVE:
+ case OP_MOVE_OBJECT:
+ case OP_MOVE_FROM16:
+ case OP_MOVE_OBJECT_FROM16:
+ case OP_MOVE_16:
+ case OP_MOVE_OBJECT_16:
+ if(inst_op == OP_MOVE || inst_op == OP_MOVE_OBJECT) {
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 1;
+ }
+ else if(inst_op == OP_MOVE_FROM16 || inst_op == OP_MOVE_OBJECT_FROM16) {
+ vA = INST_AA(inst);
+ vB = FETCH(1);
+ codeSize = 2;
+ }
+ else if(inst_op == OP_MOVE_16 || inst_op == OP_MOVE_OBJECT_16) {
+ vA = FETCH(1);
+ vB = FETCH(2);
+ codeSize = 3;
+ }
+ infoArray[1].regNum = vA; //dst
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_MOVE_WIDE:
+ case OP_MOVE_WIDE_FROM16:
+ case OP_MOVE_WIDE_16:
+ if(inst_op == OP_MOVE_WIDE) {
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 1;
+ }
+ else if(inst_op == OP_MOVE_WIDE_FROM16) {
+ vA = INST_AA(inst);
+ vB = FETCH(1);
+ codeSize = 2;
+ }
+ else if(inst_op == OP_MOVE_WIDE_16) {
+ vA = FETCH(1);
+ vB = FETCH(2);
+ codeSize = 3;
+ }
+ infoArray[1].regNum = vA; //dst
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = vB; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_MOVE_RESULT: //access memory
+ case OP_MOVE_RESULT_OBJECT:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ codeSize = 1;
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_MOVE_RESULT_WIDE: //note: 2 destinations
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ codeSize = 1;
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_MOVE_EXCEPTION: //access memory
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ codeSize = 1;
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_RETURN_VOID:
+ case OP_RETURN_VOID_BARRIER:
+ codeSize = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ num_regs_per_bytecode = 0;
+ break;
+ case OP_RETURN:
+ case OP_RETURN_OBJECT:
+ vA = INST_AA(inst);
+ codeSize = 1;
+ infoArray[0].regNum = vA; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_RETURN_WIDE:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 1;
+ codeSize = 1;
+ break;
+ case OP_CONST_4:
+ vA = INST_A(inst);
+ tmp_s4 = (s4) (INST_B(inst) << 28) >> 28;
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ codeSize = 1;
+ break;
+ case OP_CONST_16:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ codeSize = 2;
+ break;
+ case OP_CONST:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u4)FETCH(2) << 16;
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ codeSize = 3;
+ break;
+ case OP_CONST_HIGH16:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ codeSize = 2;
+ break;
+ case OP_CONST_WIDE_16:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ codeSize = 2;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_CONST_WIDE_32:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u4)FETCH(2) << 16;
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ codeSize = 3;
+ break;
+ case OP_CONST_WIDE:
+ vA = INST_AA(inst);
+ tmp_u4 = FETCH(1);
+ tmp_u4 |= (u8)FETCH(2) << 16;
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ tmp_u4 = (u8)FETCH(3);
+ tmp_u4 |= (u8)FETCH(4) << 16;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ codeSize = 5;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_CONST_WIDE_HIGH16:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ codeSize = 2;
+ break;
+ case OP_CONST_STRING:
+ case OP_CONST_STRING_JUMBO:
+ case OP_CONST_CLASS:
+ vA = INST_AA(inst);
+ if(inst_op == OP_CONST_STRING || inst_op == OP_CONST_CLASS)
+ codeSize = 2;
+ else if(inst_op == OP_CONST_STRING_JUMBO)
+ codeSize = 3;
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_MONITOR_ENTER:
+ vA = INST_AA(inst);
+ codeSize = 1;
+ infoArray[0].regNum = vA; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_MONITOR_EXIT:
+ vA = INST_AA(inst);
+ codeSize = 1;
+ infoArray[0].regNum = vA; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX); //eax is used as return value from c function
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_CHECK_CAST:
+ codeSize = 2;
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ break;
+ case OP_INSTANCE_OF:
+ codeSize = 2;
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ infoArray[0].regNum = vB; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA; //dst
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_ARRAY_LENGTH:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[0].regNum = vB; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA; //dst
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ //%edx is used in this bytecode, update currentBB->allocConstraints
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_NEW_INSTANCE:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //dst
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ codeSize = 2;
+ break;
+ case OP_NEW_ARRAY:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst); //length
+ infoArray[0].regNum = vB; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA; //dst
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 2;
+ codeSize = 2;
+ break;
+ case OP_FILLED_NEW_ARRAY: {//update return value
+ //can use up to 5 registers to fill the content of array
+ length = INST_B(inst);
+ u2 vv = FETCH(2);
+ v1 = vv & 0xf;
+ v2 = (vv >> 4) & 0xf;
+ u2 v3 = (vv >> 8) & 0xf;
+ u2 v4 = (vv >> 12) & 0xf;
+ u2 v5 = INST_A(inst);
+ if(length >= 1) {
+ infoArray[0].regNum = v1; //src
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 2) {
+ infoArray[1].regNum = v2; //src
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 3) {
+ infoArray[2].regNum = v3; //src
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 4) {
+ infoArray[3].regNum = v4; //src
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_U;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 5) {
+ infoArray[4].regNum = v5; //src
+ infoArray[4].refCount = 1;
+ infoArray[4].accessType = REGACCESS_U;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ }
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = length;
+ codeSize = 3;
+ break;
+ }
+ case OP_FILLED_NEW_ARRAY_RANGE: {//use "length" virtual registers
+ length = INST_AA(inst);
+ u4 vC = (u4)FETCH(2);
+ for(kk = 0; kk < length; kk++) {
+ infoArray[kk].regNum = vC+kk; //src
+ infoArray[kk].refCount = 1;
+ infoArray[kk].accessType = REGACCESS_U;
+ infoArray[kk].physicalType = LowOpndRegType_gp;
+ }
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = length;
+ codeSize = 3;
+ break;
+ }
+ case OP_FILL_ARRAY_DATA: //update content of array, read memory
+ vA = INST_AA(inst); //use virtual register, but has side-effect, update memory
+ infoArray[0].regNum = vA; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ codeSize = 3;
+ break;
+ case OP_THROW: //update glue->exception
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ codeSize = 1;
+ break;
+ case OP_THROW_VERIFICATION_ERROR:
+ num_regs_per_bytecode = 0;
+ codeSize = 2;
+ break;
+ case OP_GOTO:
+ codeSize = 1;
+ num_regs_per_bytecode = 0;
+ break;
+ case OP_GOTO_16:
+ codeSize = 2;
+ num_regs_per_bytecode = 0;
+ break;
+ case OP_GOTO_32:
+ codeSize = 3;
+ num_regs_per_bytecode = 0;
+ break;
+ case OP_PACKED_SWITCH:
+ case OP_SPARSE_SWITCH:
+ vA = INST_AA(inst);
+ codeSize = 3;
+ infoArray[0].regNum = vA; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 1;
+ break;
+
+ case OP_CMPL_FLOAT: //move 32 bits from memory to lower part of XMM register
+ case OP_CMPG_FLOAT:
+ codeSize = 2;
+ vA = INST_AA(inst);
+ v1_u4 = FETCH(1) & 0xff;
+ v2_u4 = FETCH(1) >> 8;
+ num_regs_per_bytecode = 1;
+ infoArray[0].regNum = v1_u4; //use ss or sd CHECK
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss;
+ infoArray[1].regNum = v2_u4; //use
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_ss;
+ num_regs_per_bytecode = 3;
+ num_entry = 2;
+ infoArray[num_entry].regNum = vA; //define
+ infoArray[num_entry].refCount = 1;
+ infoArray[num_entry].accessType = REGACCESS_D;
+ infoArray[num_entry].physicalType = LowOpndRegType_gp;
+ break;
+ case OP_CMPL_DOUBLE: //move 64 bits from memory to lower part of XMM register
+ case OP_CMPG_DOUBLE:
+ case OP_CMP_LONG: //load v1, v1+1, v2, v2+1 to gpr
+ codeSize = 2;
+ vA = INST_AA(inst);
+ v1_u4 = FETCH(1) & 0xff;
+ v2_u4 = FETCH(1) >> 8;
+ num_regs_per_bytecode = 1;
+ if(inst_op == OP_CMP_LONG) {
+ infoArray[0].regNum = v1_u4; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v1_u4 + 1; //use
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = v2_u4; //use
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = v2_u4 + 1; //use
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_U;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 5;
+ num_entry = 4;
+ infoArray[num_entry].regNum = vA; //define
+ infoArray[num_entry].refCount = 2;
+ infoArray[num_entry].accessType = REGACCESS_D;
+ infoArray[num_entry].physicalType = LowOpndRegType_gp;
+ }
+ else {
+ infoArray[0].regNum = v1_u4; //use ss or sd CHECK
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2_u4; //use
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 3;
+ num_entry = 2;
+ infoArray[num_entry].regNum = vA; //define
+ infoArray[num_entry].refCount = 1;
+ infoArray[num_entry].accessType = REGACCESS_D;
+ infoArray[num_entry].physicalType = LowOpndRegType_gp;
+ }
+ break;
+ case OP_IF_EQ:
+ case OP_IF_NE:
+ case OP_IF_LT:
+ case OP_IF_GE:
+ case OP_IF_GT:
+ case OP_IF_LE:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ infoArray[0].regNum = vA; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vB;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ codeSize =12;
+ break;
+ case OP_IF_EQZ:
+ case OP_IF_NEZ:
+ case OP_IF_LTZ:
+ case OP_IF_GEZ:
+ case OP_IF_GTZ:
+ case OP_IF_LEZ:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = vA; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ codeSize = 2;
+ break;
+ case OP_AGET:
+ codeSize = 2;
+ case OP_AGET_WIDE:
+ codeSize = 2;
+ case OP_AGET_OBJECT:
+ codeSize = 2;
+ case OP_AGET_BOOLEAN: //movez 8
+ codeSize = 2;
+ case OP_AGET_BYTE: //moves 8
+ codeSize = 2;
+ case OP_AGET_CHAR: //movez 16
+ codeSize = 2;
+ case OP_AGET_SHORT: //moves 16
+ codeSize = 2;
+ vA = INST_AA(inst);
+ vref = FETCH(1) & 0xff;
+ vindex = FETCH(1) >> 8;
+ if(inst_op == OP_AGET_WIDE) {
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm; //64, 128 not used in lowering
+ } else {
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[0].regNum = vref; //use
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vindex; //use
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_APUT:
+ case OP_APUT_WIDE:
+ case OP_APUT_OBJECT:
+ case OP_APUT_BOOLEAN:
+ case OP_APUT_BYTE:
+ case OP_APUT_CHAR:
+ case OP_APUT_SHORT:
+ vA = INST_AA(inst);
+ vref = FETCH(1) & 0xff;
+ vindex = FETCH(1) >> 8;
+ codeSize = 2;
+ if(inst_op == OP_APUT_WIDE) {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm; //64, 128 not used in lowering
+ } else {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[1].regNum = vref; //use
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = vindex; //use
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ if(inst_op == OP_APUT_OBJECT) {
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ }
+ num_regs_per_bytecode = 3;
+ break;
+
+ case OP_IGET:
+ case OP_IGET_WIDE:
+ case OP_IGET_OBJECT:
+ case OP_IGET_VOLATILE:
+ case OP_IGET_WIDE_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IGET_BOOLEAN:
+ case OP_IGET_BYTE:
+ case OP_IGET_CHAR:
+ case OP_IGET_SHORT:
+ case OP_IGET_QUICK:
+ case OP_IGET_WIDE_QUICK:
+ case OP_IGET_OBJECT_QUICK:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 2;
+ if(inst_op == OP_IGET_WIDE || inst_op == OP_IGET_WIDE_QUICK) {
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_xmm; //64
+ } else if(inst_op == OP_IGET_WIDE_VOLATILE) {
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = vA+1;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ } else {
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[0].regNum = vB; //object instance
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ if(inst_op == OP_IGET_WIDE_VOLATILE)
+ num_regs_per_bytecode = 3;
+ else
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_IPUT:
+ case OP_IPUT_WIDE:
+ case OP_IPUT_OBJECT:
+ case OP_IPUT_VOLATILE:
+ case OP_IPUT_WIDE_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_IPUT_BOOLEAN:
+ case OP_IPUT_BYTE:
+ case OP_IPUT_CHAR:
+ case OP_IPUT_SHORT:
+ case OP_IPUT_QUICK:
+ case OP_IPUT_WIDE_QUICK:
+ case OP_IPUT_OBJECT_QUICK:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 2;
+ if(inst_op == OP_IPUT_WIDE || inst_op == OP_IPUT_WIDE_QUICK || inst_op == OP_IPUT_WIDE_VOLATILE) {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm; //64
+ } else {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[1].regNum = vB; //object instance
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_SGET:
+ case OP_SGET_WIDE:
+ case OP_SGET_OBJECT:
+ case OP_SGET_VOLATILE:
+ case OP_SGET_WIDE_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SGET_BOOLEAN:
+ case OP_SGET_BYTE:
+ case OP_SGET_CHAR:
+ case OP_SGET_SHORT:
+ vA = INST_AA(inst);
+ codeSize = 2;
+ if(inst_op == OP_SGET_WIDE) {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_xmm; //64
+ } else if(inst_op == OP_SGET_WIDE_VOLATILE) {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ } else {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_D;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ if(inst_op == OP_SGET_WIDE_VOLATILE)
+ num_regs_per_bytecode = 2;
+ else
+ num_regs_per_bytecode = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ break;
+ case OP_SPUT:
+ case OP_SPUT_WIDE:
+ case OP_SPUT_OBJECT:
+ case OP_SPUT_VOLATILE:
+ case OP_SPUT_WIDE_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
+ case OP_SPUT_BOOLEAN:
+ case OP_SPUT_BYTE:
+ case OP_SPUT_CHAR:
+ case OP_SPUT_SHORT:
+ vA = INST_AA(inst);
+ codeSize = 2;
+ if(inst_op == OP_SPUT_WIDE || inst_op == OP_SPUT_WIDE_VOLATILE) {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm; //64
+ } else {
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ num_regs_per_bytecode = 1;
+ break;
+
+ case OP_INVOKE_VIRTUAL:
+ case OP_INVOKE_SUPER:
+ case OP_INVOKE_DIRECT:
+ case OP_INVOKE_STATIC:
+ case OP_INVOKE_INTERFACE:
+ case OP_INVOKE_VIRTUAL_QUICK:
+ case OP_INVOKE_SUPER_QUICK:
+ codeSize = 3;
+ vD = FETCH(2) & 0xf; //object for virtual,direct & interface
+ count = INST_B(inst);
+ vE = (FETCH(2) >> 4) & 0xf;
+ vF = (FETCH(2) >> 8) & 0xf;
+ vG = (FETCH(2) >> 12) & 0xf;
+ vA = INST_A(inst); //5th argument
+ if(count == 0) {
+ if(inst_op == OP_INVOKE_VIRTUAL || inst_op == OP_INVOKE_DIRECT ||
+ inst_op == OP_INVOKE_INTERFACE || inst_op == OP_INVOKE_VIRTUAL_QUICK ||
+ inst_op == OP_INVOKE_SUPER_QUICK) {
+ infoArray[0].regNum = vD;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 1;
+ }
+ num_regs_per_bytecode = 0;
+ }
+ else num_regs_per_bytecode = count;
+ if(count >= 1) {
+ infoArray[0].regNum = vD;
+ if(inst_op == OP_INVOKE_VIRTUAL_QUICK ||
+ inst_op == OP_INVOKE_SUPER_QUICK) {
+ infoArray[0].refCount = 2;
+ } else if(inst_op == OP_INVOKE_VIRTUAL || inst_op == OP_INVOKE_DIRECT || inst_op == OP_INVOKE_INTERFACE) {
+ infoArray[0].refCount = 2;
+ } else {
+ infoArray[0].refCount = 1;
+ }
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ if(count >= 2) {
+ infoArray[1].regNum = vE;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ }
+ if(count >= 3) {
+ infoArray[2].regNum = vF;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ }
+ if(count >= 4) {
+ infoArray[3].regNum = vG;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_U;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ }
+ if(count >= 5) {
+ infoArray[4].regNum = vA;
+ infoArray[4].refCount = 1;
+ infoArray[4].accessType = REGACCESS_U;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ }
+ if(inst_op != OP_INVOKE_VIRTUAL_QUICK && inst_op != OP_INVOKE_SUPER_QUICK)
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ break;
+ case OP_INVOKE_VIRTUAL_RANGE:
+ case OP_INVOKE_SUPER_RANGE:
+ case OP_INVOKE_DIRECT_RANGE:
+ case OP_INVOKE_STATIC_RANGE:
+ case OP_INVOKE_INTERFACE_RANGE:
+ case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+ case OP_INVOKE_SUPER_QUICK_RANGE:
+ codeSize = 3;
+ vD = FETCH(2);
+ count = INST_AA(inst);
+ if(count == 0) {
+ if(inst_op == OP_INVOKE_VIRTUAL_RANGE || inst_op == OP_INVOKE_DIRECT_RANGE ||
+ inst_op == OP_INVOKE_INTERFACE_RANGE || inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE ||
+ inst_op == OP_INVOKE_SUPER_QUICK_RANGE) {
+ infoArray[0].regNum = vD;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ }
+ if(count > 0) { //same for count > 10
+ for(kk = 0; kk < count; kk++) {
+ infoArray[kk].regNum = vD+kk; //src
+ if(kk == 0 && (inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE ||
+ inst_op == OP_INVOKE_SUPER_QUICK_RANGE))
+ infoArray[kk].refCount = 2;
+ else if(kk == 0 && (inst_op == OP_INVOKE_VIRTUAL_RANGE ||
+ inst_op == OP_INVOKE_DIRECT_RANGE ||
+ inst_op == OP_INVOKE_INTERFACE_RANGE))
+ infoArray[kk].refCount = 2;
+ else
+ infoArray[kk].refCount = 1;
+ infoArray[kk].accessType = REGACCESS_U;
+ infoArray[kk].physicalType = LowOpndRegType_gp;
+ }
+ }
+ if(inst_op != OP_INVOKE_VIRTUAL_QUICK_RANGE && inst_op != OP_INVOKE_SUPER_QUICK_RANGE)
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = count;
+ break;
+ case OP_NEG_INT:
+ case OP_NOT_INT:
+ case OP_NEG_FLOAT:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ codeSize = 1;
+ break;
+ case OP_NEG_LONG:
+ case OP_NOT_LONG:
+ case OP_NEG_DOUBLE:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_INT_TO_LONG: //hard-coded registers
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp; //save from %eax
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+ infoArray[2].regNum = vA+1;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[2].allocConstraints[PhysicalReg_EDX].count = 1;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_INT_TO_FLOAT: //32 to 32
+ case OP_INT_TO_DOUBLE: //32 to 64
+ case OP_LONG_TO_FLOAT: //64 to 32
+ case OP_LONG_TO_DOUBLE: //64 to 64
+ case OP_FLOAT_TO_DOUBLE: //32 to 64
+ case OP_DOUBLE_TO_FLOAT: //64 to 32
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ if(inst_op == OP_INT_TO_DOUBLE || inst_op == OP_LONG_TO_DOUBLE || inst_op == OP_FLOAT_TO_DOUBLE)
+ infoArray[1].physicalType = LowOpndRegType_fs;
+ else
+ infoArray[1].physicalType = LowOpndRegType_fs_s;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ if(inst_op == OP_INT_TO_FLOAT || inst_op == OP_INT_TO_DOUBLE || inst_op == OP_FLOAT_TO_DOUBLE)
+ infoArray[0].physicalType = LowOpndRegType_fs_s; //float
+ else
+ infoArray[0].physicalType = LowOpndRegType_fs;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_LONG_TO_INT:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ codeSize = 1;
+ break;
+ case OP_FLOAT_TO_INT:
+ case OP_DOUBLE_TO_INT: //for reaching-def analysis
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 3;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_fs_s; //store_int_fp_stack_VR
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ if(inst_op == OP_DOUBLE_TO_INT)
+ infoArray[0].physicalType = LowOpndRegType_fs;
+ else
+ infoArray[0].physicalType = LowOpndRegType_fs_s;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_FLOAT_TO_LONG:
+ case OP_DOUBLE_TO_LONG:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 3;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_fs;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ if(inst_op == OP_DOUBLE_TO_LONG)
+ infoArray[0].physicalType = LowOpndRegType_fs;
+ else
+ infoArray[0].physicalType = LowOpndRegType_fs_s;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_INT_TO_BYTE:
+ case OP_INT_TO_CHAR:
+ case OP_INT_TO_SHORT:
+ vA = INST_A(inst); //destination
+ vB = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+
+ case OP_ADD_INT:
+ case OP_SUB_INT:
+ case OP_MUL_INT:
+ case OP_AND_INT:
+ case OP_OR_INT:
+ case OP_XOR_INT:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_DIV_INT:
+ case OP_REM_INT:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 2;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1; //for v1
+ if(inst_op == OP_REM_INT)
+ infoArray[2].allocConstraints[PhysicalReg_EDX].count = 1;//vA
+ else
+ infoArray[2].allocConstraints[PhysicalReg_EAX].count = 1;//vA
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_SHL_INT:
+ case OP_SHR_INT:
+ case OP_USHR_INT:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v2; // in ecx
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[1].allocConstraints[PhysicalReg_ECX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_ADD_LONG:
+ case OP_SUB_LONG:
+ case OP_AND_LONG:
+ case OP_OR_LONG:
+ case OP_XOR_LONG:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_MUL_LONG: //used int
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v1+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = v2;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = v2+1;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_U;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = vA;
+ infoArray[4].refCount = 1;
+ infoArray[4].accessType = REGACCESS_D;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = vA+1;
+ infoArray[5].refCount = 1;
+ infoArray[5].accessType = REGACCESS_D;
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 6;
+ codeSize = 2;
+ break;
+ case OP_DIV_LONG: //v1: xmm v2,vA:
+ case OP_REM_LONG:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = v2+1;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = vA;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_D;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = vA+1;
+ infoArray[4].refCount = 1;
+ infoArray[4].accessType = REGACCESS_D;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 5;
+ codeSize = 2;
+ break;
+ case OP_SHL_LONG: //v2: 32, move_ss; v1,vA: xmm CHECK
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_ss;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 3;
+ codeSize = 2;
+ break;
+ case OP_SHR_LONG: //v2: 32, move_ss; v1,vA: xmm CHECK
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_ss;
+ infoArray[2].regNum = v1+1;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = vA;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_D;
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 4;
+ codeSize = 2;
+ break;
+ case OP_USHR_LONG: //v2: move_ss; v1,vA: move_sd
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm; //sd
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_ss; //ss
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm; //sd
+ num_regs_per_bytecode = 3;
+ codeSize = 2;
+ break;
+ case OP_ADD_FLOAT: //move_ss
+ case OP_SUB_FLOAT:
+ case OP_MUL_FLOAT:
+ case OP_DIV_FLOAT:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_ss;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_ss;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_REM_FLOAT: //32 bit GPR, fp_stack for output
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_fs_s;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_ADD_DOUBLE: //move_sd
+ case OP_SUB_DOUBLE:
+ case OP_MUL_DOUBLE:
+ case OP_DIV_DOUBLE:
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 3;
+ break;
+ case OP_REM_DOUBLE: //64 bit XMM, fp_stack for output
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ v2 = *((u1*)rPC + 3);
+ codeSize = 2;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_D;
+ infoArray[2].physicalType = LowOpndRegType_fs;
+ infoArray[0].regNum = v1;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 3;
+ break;
+
+ case OP_ADD_INT_2ADDR:
+ case OP_SUB_INT_2ADDR:
+ case OP_MUL_INT_2ADDR:
+ case OP_AND_INT_2ADDR:
+ case OP_OR_INT_2ADDR:
+ case OP_XOR_INT_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD; //use then define
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_DIV_INT_2ADDR:
+ case OP_REM_INT_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 3;
+ infoArray[1].accessType = REGACCESS_UD; //use then define
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1; //for v1 is vA
+ if(inst_op == OP_REM_INT_2ADDR)
+ infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;//vA
+ else
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;//vA
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_SHL_INT_2ADDR:
+ case OP_SHR_INT_2ADDR:
+ case OP_USHR_INT_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD; //use then define
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].allocConstraints[PhysicalReg_ECX].count = 1; //v2
+ updateCurrentBBWithConstraints(PhysicalReg_ECX);
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_ADD_LONG_2ADDR:
+ case OP_SUB_LONG_2ADDR:
+ case OP_AND_LONG_2ADDR:
+ case OP_OR_LONG_2ADDR:
+ case OP_XOR_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_MUL_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ num_regs_per_bytecode = 4;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = v2+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 2;
+ infoArray[2].accessType = REGACCESS_UD;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = vA+1;
+ infoArray[3].refCount = 2;
+ infoArray[3].accessType = REGACCESS_UD;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ break;
+ case OP_DIV_LONG_2ADDR: //vA used as xmm, then updated as gps
+ case OP_REM_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ num_regs_per_bytecode = 5;
+ codeSize = 1;
+ infoArray[0].regNum = vA;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = v2;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = v2+1;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = vA;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_D;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = vA+1;
+ infoArray[4].refCount = 1;
+ infoArray[4].accessType = REGACCESS_D;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ break;
+ case OP_SHL_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ num_regs_per_bytecode = 2;
+ codeSize = 1;
+ infoArray[0].regNum = v2; //ss
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ break;
+ case OP_SHR_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ num_regs_per_bytecode = 3;
+ codeSize = 1;
+ infoArray[0].regNum = v2; //ss
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss;
+ infoArray[1].regNum = vA+1;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = vA;
+ infoArray[2].refCount = 2;
+ infoArray[2].accessType = REGACCESS_UD;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ break;
+ case OP_USHR_LONG_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ num_regs_per_bytecode = 2;
+ codeSize = 1;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss; //ss CHECK
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_xmm; //sd
+ break;
+ case OP_ADD_FLOAT_2ADDR:
+ case OP_SUB_FLOAT_2ADDR:
+ case OP_MUL_FLOAT_2ADDR:
+ case OP_DIV_FLOAT_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_ss;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_ss;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_REM_FLOAT_2ADDR: //load vA as GPR, store from fs
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_gp; //CHECK
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_ADD_DOUBLE_2ADDR:
+ case OP_SUB_DOUBLE_2ADDR:
+ case OP_MUL_DOUBLE_2ADDR:
+ case OP_DIV_DOUBLE_2ADDR:
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_REM_DOUBLE_2ADDR: //load to xmm, store from fs
+ vA = INST_A(inst);
+ v2 = INST_B(inst);
+ codeSize = 1;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 2;
+ infoArray[1].accessType = REGACCESS_UD;
+ infoArray[1].physicalType = LowOpndRegType_xmm; //CHECK
+ infoArray[0].regNum = v2;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ num_regs_per_bytecode = 2;
+ break;
+
+ case OP_ADD_INT_LIT16:
+ case OP_RSUB_INT:
+ case OP_MUL_INT_LIT16:
+ case OP_AND_INT_LIT16:
+ case OP_OR_INT_LIT16:
+ case OP_XOR_INT_LIT16:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 2;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_DIV_INT_LIT16:
+ case OP_REM_INT_LIT16:
+ vA = INST_A(inst);
+ vB = INST_B(inst);
+ codeSize = 2;
+ tmp_s4 = (s2)FETCH(1);
+ tmp_s2 = tmp_s4;
+ if(tmp_s2 == 0) {
+ num_regs_per_bytecode = 0;
+ break;
+ }
+ infoArray[1].regNum = vA; //in edx for rem, in eax
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB; //in eax
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ if(inst_op == OP_DIV_INT_LIT16) {
+ int power = isPowerOfTwo(tmp_s2);
+ if(power >= 1) { /* divide by a power of 2 constant */
+ infoArray[1].refCount = 1;
+ break;
+ }
+ }
+ if(tmp_s2 == -1)
+ infoArray[1].refCount = 2;
+ else
+ infoArray[1].refCount = 1;
+ if(inst_op == OP_REM_INT_LIT16)
+ infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;
+ else
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ break;
+ case OP_ADD_INT_LIT8:
+ case OP_RSUB_INT_LIT8:
+ case OP_MUL_INT_LIT8:
+ case OP_AND_INT_LIT8:
+ case OP_OR_INT_LIT8:
+ case OP_XOR_INT_LIT8:
+ case OP_SHL_INT_LIT8:
+ case OP_SHR_INT_LIT8:
+ case OP_USHR_INT_LIT8:
+ codeSize = 2;
+ vA = INST_AA(inst);
+ vB = (u2)FETCH(1) & 0xff;
+ infoArray[1].regNum = vA;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ break;
+ case OP_DIV_INT_LIT8:
+ case OP_REM_INT_LIT8:
+ codeSize = 2;
+ vA = INST_AA(inst);
+ vB = (u2)FETCH(1) & 0xff;
+ tmp_s2 = (s2)FETCH(1) >> 8;
+ if(tmp_s2 == 0) {
+ num_regs_per_bytecode = 0;
+ break;
+ }
+
+ infoArray[1].regNum = vA;
+ infoArray[1].accessType = REGACCESS_D;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[0].regNum = vB;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ num_regs_per_bytecode = 2;
+ if(inst_op == OP_DIV_INT_LIT8) {
+ int power = isPowerOfTwo(tmp_s2);
+ if(power >= 1) { /* divide by a power of 2 constant */
+ infoArray[1].refCount = 1;
+ break;
+ }
+ }
+
+ if(tmp_s2 == -1)
+ infoArray[1].refCount = 2;
+ else
+ infoArray[1].refCount = 1;
+ if(inst_op == OP_REM_INT_LIT8)
+ infoArray[1].allocConstraints[PhysicalReg_EDX].count = 1;
+ else
+ infoArray[1].allocConstraints[PhysicalReg_EAX].count = 1;
+ infoArray[0].allocConstraints[PhysicalReg_EAX].count = 1;
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ break;
+ case OP_EXECUTE_INLINE: //update glue->retval
+ case OP_EXECUTE_INLINE_RANGE:
+ u4 vC;
+ if(inst_op == OP_EXECUTE_INLINE)
+ num = INST_B(inst);
+ else
+ num = INST_AA(inst);
+ if(inst_op == OP_EXECUTE_INLINE) {
+ vC = FETCH(2) & 0xf;
+ vD = (FETCH(2) >> 4) & 0xf;
+ vE = (FETCH(2) >> 8) & 0xf;
+ vF = FETCH(2) >> 12;
+ } else {
+ vC = FETCH(2);
+ vD = vC + 1;
+ vE = vC + 2;
+ vF = vC + 3;
+ }
+ codeSize = 3;
+ if(num >= 1) {
+ infoArray[0].regNum = vC;
+ infoArray[0].refCount = 1;
+ infoArray[0].accessType = REGACCESS_U;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 2) {
+ infoArray[1].regNum = vD;
+ infoArray[1].refCount = 1;
+ infoArray[1].accessType = REGACCESS_U;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 3) {
+ infoArray[2].regNum = vE;
+ infoArray[2].refCount = 1;
+ infoArray[2].accessType = REGACCESS_U;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 4) {
+ infoArray[3].regNum = vF;
+ infoArray[3].refCount = 1;
+ infoArray[3].accessType = REGACCESS_U;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ }
+ updateCurrentBBWithConstraints(PhysicalReg_EAX);
+ updateCurrentBBWithConstraints(PhysicalReg_EDX);
+ num_regs_per_bytecode = num;
+ break;
+#if FIXME
+ case OP_INVOKE_OBJECT_INIT_RANGE:
+ codeSize = 3;
+ num_regs_per_bytecode = 0;
+ break;
+#endif
+ }
+ return codeSize;
+}
+//! Updates infoArray(TempRegInfo) with temporaries accessed by INVOKE_NO_RANGE
+
+//!
+int updateInvokeNoRange(TempRegInfo* infoArray, int startInd) {
+ int j = startInd;
+ //invokeMethodNoRange
+ int count = INST_B(inst);
+ if(count == 5) {
+ infoArray[j].regNum = 22;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 4) {
+ infoArray[j].regNum = 23;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 3) {
+ infoArray[j].regNum = 24;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 2) {
+ infoArray[j].regNum = 25;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 1) {
+ infoArray[j].regNum = 26;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ return j;
+}
+//! Updates infoArray(TempRegInfo) with temporaries accessed by INVOKE_RANGE
+
+//! LOOP_COUNT is used to indicate a variable is live through a loop
+int updateInvokeRange(TempRegInfo* infoArray, int startIndex) {
+ int j = startIndex;
+ int count = INST_AA(inst);
+ infoArray[j].regNum = 21;
+ if(count <= 10) {
+ infoArray[j].refCount = 1+count; //DU
+ } else {
+ infoArray[j].refCount = 2+3*LOOP_COUNT;
+ }
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ if(count >= 1 && count <= 10) {
+ infoArray[j].regNum = 22;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 2 && count <= 10) {
+ infoArray[j].regNum = 23;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 3 && count <= 10) {
+ infoArray[j].regNum = 24;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 4 && count <= 10) {
+ infoArray[j].regNum = 25;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 5 && count <= 10) {
+ infoArray[j].regNum = 26;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 6 && count <= 10) {
+ infoArray[j].regNum = 27;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 7 && count <= 10) {
+ infoArray[j].regNum = 28;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 8 && count <= 10) {
+ infoArray[j].regNum = 29;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count >= 9 && count <= 10) {
+ infoArray[j].regNum = 30;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count == 10) {
+ infoArray[j].regNum = 31;
+ infoArray[j].refCount = 2; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ if(count > 10) {
+ //NOTE: inside a loop, LOOP_COUNT can't be 1
+ // if LOOP_COUNT is 1, it is likely that a logical register is freed inside the loop
+ // and the next iteration will have incorrect result
+ infoArray[j].regNum = 12;
+ infoArray[j].refCount = 1+3*LOOP_COUNT; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ infoArray[j].regNum = 13;
+ infoArray[j].refCount = 1+LOOP_COUNT; //DU
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ infoArray[j].regNum = 14;
+ //MUST be 2, otherwise, transferToState will think its state was in memory
+ infoArray[j].refCount = 2; //DU local
+ infoArray[j].physicalType = LowOpndRegType_gp;
+ j++;
+ }
+ return j;
+}
+
+/* update temporaries used by RETURN bytecodes
+ a temporary is represented by <number, type of the temporary>
+ */
+int updateReturnCommon(TempRegInfo* infoArray) {
+ int numTmps;
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+ infoArray[2].regNum = PhysicalReg_EAX;
+ infoArray[2].refCount = 5; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[3].regNum = 1;
+#if defined(ENABLE_TRACING)//WITH_DEBUGGER is true WITH_PROFILER can be false
+ infoArray[3].refCount = 6+4;
+#else
+ infoArray[3].refCount = 6; //DU
+#endif
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 2;
+ infoArray[4].refCount = 4; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 5;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ infoArray[6].regNum = 10;
+ infoArray[6].refCount = 3;
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ infoArray[7].regNum = 6;
+ infoArray[7].refCount = 4; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp;
+ infoArray[8].regNum = 3;
+ infoArray[8].refCount = 3;
+ infoArray[8].physicalType = LowOpndRegType_gp;
+ infoArray[9].regNum = 7;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_gp;
+ numTmps = 12;
+#if defined(ENABLE_TRACING)
+ infoArray[12].regNum = 4;
+ infoArray[12].refCount = 3; //DU
+ infoArray[12].physicalType = LowOpndRegType_gp;
+ infoArray[13].regNum = 3;
+ infoArray[13].refCount = 2; //DU
+ infoArray[13].physicalType = LowOpndRegType_scratch;
+ infoArray[14].regNum = 15;
+ infoArray[14].refCount = 2; //DU
+ infoArray[14].physicalType = LowOpndRegType_gp;
+ infoArray[15].regNum = 16;
+ infoArray[15].refCount = 2; //DU
+ infoArray[15].physicalType = LowOpndRegType_gp;
+ infoArray[16].regNum = PhysicalReg_EDX;
+ infoArray[16].refCount = 2; //DU
+ infoArray[16].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[17].regNum = 6;
+ infoArray[17].refCount = 2; //DU
+ infoArray[17].physicalType = LowOpndRegType_scratch;
+ numTmps = 18;
+#endif
+ infoArray[10].regNum = 14;
+ infoArray[10].refCount = 2; //DU
+ infoArray[10].physicalType = LowOpndRegType_gp;
+ infoArray[11].regNum = 4;
+ infoArray[11].refCount = 2; //DU
+ infoArray[11].physicalType = LowOpndRegType_scratch;
+#ifdef DEBUG_CALL_STACK
+ infoArray[numTmps].regNum = 5;
+ infoArray[numTmps].refCount = 2;
+ infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+ numTmps++;
+#endif
+ infoArray[numTmps].regNum = PhysicalReg_EBX;
+ /* used to hold chaining cell
+ updated to be returnAddr
+ then conditionally updated to zero
+ used to update inJitCodeCache
+ compare against zero to determine whether to jump to native code
+ jump to native code (%ebx)
+ */
+ infoArray[numTmps].refCount = 3+1+1;
+ infoArray[numTmps].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ numTmps++;
+ infoArray[numTmps].regNum = 17;
+ infoArray[numTmps].refCount = 2; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ infoArray[numTmps].regNum = 7;
+ infoArray[numTmps].refCount = 4; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+ numTmps++;
+ return numTmps;
+}
+
+/* update temporaries used by predicted INVOKE_VIRTUAL & INVOKE_INTERFACE */
+int updateGenPrediction(TempRegInfo* infoArray, bool isInterface) {
+ infoArray[0].regNum = 40;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 41;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 32;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+
+ if(isInterface) {
+ infoArray[0].refCount = 2+2;
+ infoArray[1].refCount = 3+2-1; //for temp41, -1 for gingerbread
+ infoArray[3].regNum = 33;
+ infoArray[3].refCount = 4+1;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = PhysicalReg_EAX;
+ infoArray[4].refCount = 5;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[5].regNum = PhysicalReg_ECX;
+ infoArray[5].refCount = 1+1+2; //used in ArgsDone (twice)
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = 10;
+ infoArray[6].refCount = 2;
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ infoArray[7].regNum = 9;
+ infoArray[7].refCount = 2;
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ infoArray[8].regNum = 8;
+ infoArray[8].refCount = 2;
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[9].regNum = PhysicalReg_EDX; //space holder
+ infoArray[9].refCount = 1;
+ infoArray[9].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[10].regNum = 43;
+ infoArray[10].refCount = 3;
+ infoArray[10].physicalType = LowOpndRegType_gp;
+ infoArray[11].regNum = 44;
+ infoArray[11].refCount = 3;
+ infoArray[11].physicalType = LowOpndRegType_gp;
+ infoArray[12].regNum = 45;
+ infoArray[12].refCount = 2;
+ infoArray[12].physicalType = LowOpndRegType_gp;
+ infoArray[13].regNum = 7;
+ infoArray[13].refCount = 4;
+ infoArray[13].physicalType = LowOpndRegType_scratch;
+ return 14;
+ } else { //virtual or virtual_quick
+ infoArray[0].refCount = 2+2;
+ infoArray[1].refCount = 3+2-2; //for temp41, -2 for gingerbread
+ infoArray[2].refCount++; //for temp32 gingerbread
+ infoArray[3].regNum = 33;
+ infoArray[3].refCount = 4+1;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 34;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = PhysicalReg_EAX;
+ infoArray[5].refCount = 2;
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = PhysicalReg_ECX;
+ infoArray[6].refCount = 1+3+2;
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[7].regNum = 10;
+ infoArray[7].refCount = 2;
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ infoArray[8].regNum = PhysicalReg_EDX; //space holder
+ infoArray[8].refCount = 1;
+ infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[9].regNum = 43;
+ infoArray[9].refCount = 3;
+ infoArray[9].physicalType = LowOpndRegType_gp;
+ infoArray[10].regNum = 44;
+ infoArray[10].refCount = 3;
+ infoArray[10].physicalType = LowOpndRegType_gp;
+ infoArray[11].regNum = 7;
+ infoArray[11].refCount = 4;
+ infoArray[11].physicalType = LowOpndRegType_scratch;
+ return 12;
+ }
+}
+
+int updateMarkCard(TempRegInfo* infoArray, int j1/*valReg*/,
+ int j2/*tgtAddrReg*/, int j3/*scratchReg*/) {
+ infoArray[j3].regNum = 11;
+ infoArray[j3].physicalType = LowOpndRegType_gp;
+ infoArray[j3].refCount = 3;
+ infoArray[j3].is8Bit = true;
+ infoArray[j1].refCount++;
+ infoArray[j2].refCount += 2;
+ infoArray[j3+1].regNum = 6;
+ infoArray[j3+1].physicalType = LowOpndRegType_scratch;
+ infoArray[j3+1].refCount = 2;
+ return j3+2;
+}
+
+int updateMarkCard_notNull(TempRegInfo* infoArray,
+ int j2/*tgtAddrReg*/, int j3/*scratchReg*/) {
+ infoArray[j3].regNum = 11;
+ infoArray[j3].physicalType = LowOpndRegType_gp;
+ infoArray[j3].refCount = 3;
+ infoArray[j3].is8Bit = true;
+ infoArray[j2].refCount += 2;
+ infoArray[j3+1].regNum = 2;
+ infoArray[j3+1].refCount = 2; //DU
+ infoArray[j3+1].physicalType = LowOpndRegType_scratch;
+ return j3+2;
+}
+
+int iget_obj_inst = -1;
+//! This function updates infoArray with temporaries accessed when lowering the bytecode
+
+//! returns the number of temporaries
+int getTempRegInfo(TempRegInfo* infoArray) { //returns an array of TempRegInfo
+ int k;
+ int numTmps;
+ for(k = 0; k < MAX_TEMP_REG_PER_BYTECODE; k++) {
+ infoArray[k].linkageToVR = -1;
+ infoArray[k].versionNum = 0;
+ infoArray[k].shareWithVR = true;
+ infoArray[k].is8Bit = false;
+ }
+ u2 vA, v1, length, num, tmp;
+ u2 inst_op = INST_INST(inst);
+ s2 tmp_s2;
+ s4 tmp_s4;
+ switch(inst_op) {
+ case OP_APUT_BYTE:
+ for(k = 0; k < MAX_TEMP_REG_PER_BYTECODE; k++)
+ infoArray[k].shareWithVR = true; //false;
+ break;
+ }
+ switch (INST_INST(inst)) {
+ case OP_NOP:
+ return 0;
+ case OP_MOVE:
+ case OP_MOVE_OBJECT:
+ case OP_MOVE_FROM16:
+ case OP_MOVE_OBJECT_FROM16:
+ case OP_MOVE_16:
+ case OP_MOVE_OBJECT_16:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ return 1;
+ case OP_MOVE_WIDE:
+ case OP_MOVE_WIDE_FROM16:
+ case OP_MOVE_WIDE_16:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ return 1;
+ case OP_MOVE_RESULT:
+ case OP_MOVE_RESULT_OBJECT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+ return 2;
+ case OP_MOVE_RESULT_WIDE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+ return 2;
+ case OP_MOVE_EXCEPTION:
+ infoArray[0].regNum = 2;
+ infoArray[0].refCount = 3; //DUU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 3;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ return 3;
+
+ case OP_CONST_4:
+ case OP_CONST_16:
+ case OP_CONST:
+ case OP_CONST_HIGH16:
+ case OP_CONST_WIDE_16:
+ case OP_CONST_WIDE_32:
+ case OP_CONST_WIDE:
+ case OP_CONST_WIDE_HIGH16:
+ return 0;
+ case OP_CONST_STRING: //hardcode %eax
+ case OP_CONST_STRING_JUMBO:
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+ infoArray[2].regNum = 2;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 4;
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 4;
+ case OP_CONST_CLASS:
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+ infoArray[2].regNum = 2;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 4;
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 4;
+
+ case OP_MONITOR_ENTER:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 3;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = 2;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+ case OP_MONITOR_EXIT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EAX;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = PhysicalReg_EDX;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = 2;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ infoArray[5].regNum = 3;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ return 6;
+ case OP_CHECK_CAST:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 4;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 6;
+ infoArray[2].refCount = 3; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ infoArray[4].regNum = 2;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+
+ infoArray[5].regNum = PhysicalReg_EAX;
+ /* %eax has 3 live ranges
+ 1> 5 accesses: to resolve the class object
+ 2> call dvmInstanceofNonTrivial to define %eax, then use it once
+ 3> move exception object to %eax, then jump to throw_exception
+ if WITH_JIT is true, the first live range has 6 accesses
+ */
+ infoArray[5].refCount = 6;
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = PhysicalReg_EDX;
+ infoArray[6].refCount = 2; //export_pc
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[7].regNum = PhysicalReg_ECX;
+ infoArray[7].refCount = 1;
+ infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[8].regNum = 3;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ return 9;
+ case OP_INSTANCE_OF:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 3;
+ infoArray[1].refCount = 4; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 4;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 6;
+ infoArray[3].refCount = 3; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+
+ infoArray[4].regNum = 1;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ infoArray[5].regNum = 2;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+
+ infoArray[6].regNum = PhysicalReg_EAX;
+ infoArray[6].refCount = 6;
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[7].regNum = 3;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ infoArray[8].regNum = PhysicalReg_EDX;
+ infoArray[8].refCount = 2; //export_pc for class_resolve
+ infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 9;
+
+ case OP_ARRAY_LENGTH:
+ vA = INST_A(inst);
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[1].linkageToVR = vA;
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 3;
+ case OP_NEW_INSTANCE:
+ infoArray[0].regNum = PhysicalReg_EAX;
+ //6: class object
+ //3: defined by C function, used twice
+ infoArray[0].refCount = 6; //next version has 3 references
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].regNum = PhysicalReg_ECX; //before common_throw_message
+ infoArray[1].refCount = 1;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[3].is8Bit = true;
+ infoArray[4].regNum = 6;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = 2;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ infoArray[7].regNum = 3;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+
+ infoArray[8].regNum = PhysicalReg_EDX; //before common_throw_message
+ infoArray[8].refCount = 2;
+ infoArray[8].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[9].regNum = 4;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_scratch;
+ return 10;
+
+ case OP_NEW_ARRAY:
+ infoArray[0].regNum = PhysicalReg_EAX;
+ //4: class object
+ //3: defined by C function, used twice
+ infoArray[0].refCount = 4; //next version has 3 references
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 3; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+
+ infoArray[4].regNum = 1;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ infoArray[5].regNum = 2;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = 3;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ infoArray[7].regNum = 4;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ return 8;
+
+ case OP_FILLED_NEW_ARRAY:
+ length = INST_B(inst);
+ infoArray[0].regNum = PhysicalReg_EAX;
+ //4: class object
+ //3: defined by C function, used twice (array object)
+ //length: access array object to update the content
+ infoArray[0].refCount = 4; //next version has 5+length references
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 6;
+ infoArray[4].refCount = 8; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[4].is8Bit = true;
+
+ if(length >= 1) {
+ infoArray[5].regNum = 7;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 2) {
+ infoArray[6].regNum = 8;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 3) {
+ infoArray[7].regNum = 9;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 4) {
+ infoArray[8].regNum = 10;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_gp;
+ }
+ if(length >= 5) {
+ infoArray[9].regNum = 11;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[5+length].regNum = 1;
+ infoArray[5+length].refCount = 2; //DU
+ infoArray[5+length].physicalType = LowOpndRegType_scratch;
+ infoArray[6+length].regNum = 2;
+ infoArray[6+length].refCount = 4; //DU
+ infoArray[6+length].physicalType = LowOpndRegType_scratch;
+ infoArray[7+length].regNum = 3;
+ infoArray[7+length].refCount = 2; //DU
+ infoArray[7+length].physicalType = LowOpndRegType_scratch;
+ infoArray[8+length].regNum = 4;
+ infoArray[8+length].refCount = 5; //DU
+ infoArray[8+length].physicalType = LowOpndRegType_scratch;
+ return 9+length;
+
+ case OP_FILLED_NEW_ARRAY_RANGE:
+ length = INST_AA(inst);
+ infoArray[0].regNum = PhysicalReg_EAX;
+ //4: class object
+ //3: defined by C function, used twice (array object)
+ //if length is 0, no access to array object
+ //else, used inside a loop
+ infoArray[0].refCount = 4; //next version: 5+(length >= 1 ? LOOP_COUNT : 0)
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 6;
+ infoArray[4].refCount = 8; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[4].is8Bit = true;
+
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = 2;
+ infoArray[6].refCount = 4; //DU
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ infoArray[7].regNum = 3;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+
+ infoArray[8].regNum = 7;
+ infoArray[8].refCount = 3*(length >= 1 ? LOOP_COUNT : 0);
+ infoArray[8].physicalType = LowOpndRegType_gp;
+ infoArray[9].regNum = 8;
+ infoArray[9].refCount = 3*(length >= 1 ? LOOP_COUNT : 0);
+ infoArray[9].physicalType = LowOpndRegType_gp;
+ infoArray[10].regNum = 9;
+ infoArray[10].refCount = 2*(length >= 1 ? LOOP_COUNT : 0);
+ infoArray[10].physicalType = LowOpndRegType_gp;
+ infoArray[11].regNum = 10;
+ infoArray[11].refCount = 2*(length >= 1 ? LOOP_COUNT : 0);
+ infoArray[11].physicalType = LowOpndRegType_gp;
+ infoArray[12].regNum = 4;
+ infoArray[12].refCount = 5; //DU
+ infoArray[12].physicalType = LowOpndRegType_scratch;
+ return 13;
+
+ case OP_FILL_ARRAY_DATA:
+ infoArray[0].regNum = PhysicalReg_EAX;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+#if 0//def HARDREG_OPT
+ infoArray[1].refCount = 3; //next version has refCount of 2
+#else
+ infoArray[1].refCount = 5;
+#endif
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum =1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ infoArray[4].regNum = 2;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ return 5;
+
+ case OP_THROW:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EDX; //before common_throw_message
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = 2;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ return 4;
+ case OP_THROW_VERIFICATION_ERROR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EDX; //export_pc
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ infoArray[3].regNum = 2;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ return 4;
+
+ case OP_GOTO: //called function common_periodicChecks4
+#if defined(ENABLE_TRACING)
+ tt = INST_AA(inst);
+ tmp_s2 = (s2)((s2)tt << 8) >> 8;
+ if(tmp_s2 < 0) {
+ infoArray[0].regNum = PhysicalReg_EDX;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 1;
+ }
+#endif
+ return 0;
+ case OP_GOTO_16:
+#if defined(ENABLE_TRACING)
+ tmp_s2 = (s2)FETCH(1);
+ if(tmp_s2 < 0) {
+ infoArray[0].regNum = PhysicalReg_EDX;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 1;
+ }
+#endif
+ return 0;
+ case OP_GOTO_32:
+#if defined(ENABLE_TRACING)
+ tmp_u4 = (u4)FETCH(1);
+ tmp_u4 |= (u4)FETCH(2) << 16;
+ if(((s4)tmp_u4) < 0) {
+ infoArray[0].regNum = PhysicalReg_EDX;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 1;
+ }
+#endif
+ return 0;
+ case OP_IF_EQ:
+ case OP_IF_NE:
+ case OP_IF_LT:
+ case OP_IF_GE:
+ case OP_IF_GT:
+ case OP_IF_LE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+#if defined(ENABLE_TRACING)
+ tmp_s2 = (s2)FETCH(1);
+ if(tmp_s2 < 0) {
+ infoArray[1].regNum = PhysicalReg_EDX;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 2;
+ }
+#endif
+ return 1;
+ case OP_IF_EQZ: //called function common_periodicChecks4
+ case OP_IF_NEZ:
+ case OP_IF_LTZ:
+ case OP_IF_GEZ:
+ case OP_IF_GTZ:
+ case OP_IF_LEZ:
+#if defined(ENABLE_TRACING)
+ tmp_s2 = (s2)FETCH(1);
+ if(tmp_s2 < 0) {
+ infoArray[0].regNum = PhysicalReg_EDX;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 1;
+ }
+#endif
+ return 0;
+ case OP_PACKED_SWITCH: //jump common_backwardBranch, which calls common_periodicChecks_entry, then jump_reg %eax
+ case OP_SPARSE_SWITCH: //%edx, %eax
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EDX;
+ infoArray[1].refCount = 6;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[2].regNum = PhysicalReg_EAX; //return by dvm helper
+ infoArray[2].refCount = 2+1; //2 uses
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2;
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ infoArray[4].regNum = 2;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ return 5;
+
+ case OP_AGET:
+ case OP_AGET_OBJECT:
+ case OP_AGET_BOOLEAN:
+ case OP_AGET_BYTE:
+ case OP_AGET_CHAR:
+ case OP_AGET_SHORT:
+ vA = INST_AA(inst);
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[3].linkageToVR = vA;
+ if(inst_op == OP_AGET_BYTE || inst_op == OP_AGET_BOOLEAN)
+ infoArray[3].is8Bit = true;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+ case OP_AGET_WIDE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+
+ case OP_APUT:
+ case OP_APUT_BOOLEAN:
+ case OP_APUT_BYTE:
+ case OP_APUT_CHAR:
+ case OP_APUT_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ if(inst_op == OP_APUT_BYTE || inst_op == OP_APUT_BOOLEAN)
+ infoArray[3].is8Bit = true;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+ case OP_APUT_WIDE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+ case OP_APUT_OBJECT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 5+1; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2; //live through function call dvmCanPut
+ infoArray[1].refCount = 3+1; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 4+1; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 6;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp;
+
+ infoArray[6].regNum = PhysicalReg_EDX;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[7].regNum = PhysicalReg_EAX;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[8].regNum = 1;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[0].shareWithVR = false;
+ return updateMarkCard_notNull(infoArray,
+ 0/*index for tgtAddrReg*/, 9);
+
+ case OP_IGET:
+ case OP_IGET_OBJECT:
+ case OP_IGET_VOLATILE:
+ case OP_IGET_OBJECT_VOLATILE:
+ case OP_IGET_BOOLEAN:
+ case OP_IGET_BYTE:
+ case OP_IGET_CHAR:
+ case OP_IGET_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 3; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[4].regNum = 3;
+ infoArray[4].refCount = 3; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 7;
+#ifdef DEBUG_IGET_OBJ
+ //add hack for a specific instance (iget_obj_inst) of IGET_OBJECT within a method
+ if(inst_op == OP_IGET_OBJECT && !strncmp(currentMethod->clazz->descriptor, "Lspec/benchmarks/_228_jack/Parse", 32) &&
+ !strncmp(currentMethod->name, "buildPhase3", 11))
+ {
+#if 0
+ if(iget_obj_inst == 12) {
+ LOGD("increase count for instance %d of %s %s", iget_obj_inst, currentMethod->clazz->descriptor, currentMethod->name);
+ infoArray[5].refCount = 4; //DU
+ }
+ else
+#endif
+ infoArray[5].refCount = 3;
+ iget_obj_inst++;
+ }
+ else
+ infoArray[5].refCount = 3;
+#else
+ infoArray[5].refCount = 3; //DU
+#endif
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ infoArray[6].regNum = 8;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ infoArray[7].regNum = 9;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp;
+ return 8;
+ case OP_IPUT:
+ case OP_IPUT_OBJECT:
+ case OP_IPUT_VOLATILE:
+ case OP_IPUT_OBJECT_VOLATILE:
+ case OP_IPUT_BOOLEAN:
+ case OP_IPUT_BYTE:
+ case OP_IPUT_CHAR:
+ case OP_IPUT_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 3; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[4].regNum = 3;
+ infoArray[4].refCount = 3; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 7;
+ infoArray[5].refCount = 3; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ infoArray[6].regNum = 8;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ infoArray[7].regNum = 9;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp;
+ if(inst_op == OP_IPUT_OBJECT || inst_op == OP_IPUT_OBJECT_VOLATILE) {
+ infoArray[5].shareWithVR = false;
+ return updateMarkCard(infoArray, 7/*index for valReg*/,
+ 5/*index for tgtAddrReg*/, 8);
+ }
+ return 8;
+ case OP_IGET_WIDE:
+ case OP_IGET_WIDE_VOLATILE:
+ case OP_IPUT_WIDE:
+ case OP_IPUT_WIDE_VOLATILE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 3; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[4].regNum = 3;
+ infoArray[4].refCount = 3; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 7;
+ infoArray[5].refCount = 3; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ infoArray[6].regNum = 8;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ infoArray[7].regNum = 1;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_xmm;
+
+ if(inst_op == OP_IPUT_WIDE_VOLATILE || inst_op == OP_IGET_WIDE_VOLATILE) {
+ infoArray[8].regNum = 3;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[9].regNum = 9;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_gp;
+ return 10;
+ }
+ return 8;
+
+ case OP_SGET:
+ case OP_SGET_OBJECT:
+ case OP_SGET_VOLATILE:
+ case OP_SGET_OBJECT_VOLATILE:
+ case OP_SGET_BOOLEAN:
+ case OP_SGET_BYTE:
+ case OP_SGET_CHAR:
+ case OP_SGET_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EAX;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 7;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = PhysicalReg_EDX;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 6;
+ case OP_SPUT:
+ case OP_SPUT_OBJECT:
+ case OP_SPUT_VOLATILE:
+ case OP_SPUT_OBJECT_VOLATILE:
+ case OP_SPUT_BOOLEAN:
+ case OP_SPUT_BYTE:
+ case OP_SPUT_CHAR:
+ case OP_SPUT_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EAX;
+ infoArray[2].refCount = 2+1; //access clazz of the field
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 7;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = PhysicalReg_EDX;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ if(inst_op == OP_SPUT_OBJECT || inst_op == OP_SPUT_OBJECT_VOLATILE) {
+ infoArray[2].shareWithVR = false;
+ infoArray[6].regNum = 12;
+ infoArray[6].refCount = 1; //1 def, 2 uses in updateMarkCard
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ return updateMarkCard(infoArray, 4/*index for valReg*/,
+ 6/*index for tgtAddrReg */, 7);
+ }
+ return 6;
+ case OP_SGET_WIDE:
+ case OP_SGET_WIDE_VOLATILE:
+ case OP_SPUT_WIDE:
+ case OP_SPUT_WIDE_VOLATILE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_scratch;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_scratch;
+
+ infoArray[2].regNum = PhysicalReg_EAX;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 1;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_xmm;
+ infoArray[5].regNum = PhysicalReg_EDX;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ if(inst_op == OP_SPUT_WIDE_VOLATILE || inst_op == OP_SGET_WIDE_VOLATILE) {
+ infoArray[6].regNum = 3;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ infoArray[7].regNum = 9;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp;
+ return 8;
+ }
+ return 6;
+
+ case OP_IGET_QUICK:
+ case OP_IGET_OBJECT_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 3;
+ case OP_IPUT_QUICK:
+ case OP_IPUT_OBJECT_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ if(inst_op == OP_IPUT_OBJECT_QUICK) {
+ infoArray[0].shareWithVR = false;
+ return updateMarkCard(infoArray, 1/*index for valReg*/,
+ 0/*index for tgtAddrReg*/, 3);
+ }
+ return 3;
+ case OP_IGET_WIDE_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 3;
+ case OP_IPUT_WIDE_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 3;
+
+ case OP_RETURN_VOID:
+ case OP_RETURN_VOID_BARRIER:
+ return updateReturnCommon(infoArray);
+ case OP_RETURN:
+ case OP_RETURN_OBJECT:
+ numTmps = updateReturnCommon(infoArray);
+
+ infoArray[numTmps].regNum = 21;
+ infoArray[numTmps].refCount = 2; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ infoArray[numTmps].regNum = 22;
+ infoArray[numTmps].refCount = 2; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ return numTmps;
+ case OP_RETURN_WIDE:
+ numTmps = updateReturnCommon(infoArray);
+
+ infoArray[numTmps].regNum = 10;
+ infoArray[numTmps].refCount = 2; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_scratch;
+ numTmps++;
+ infoArray[numTmps].regNum = 1;
+ infoArray[numTmps].refCount = 2; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_xmm;
+ numTmps++;
+ return numTmps;
+
+ case OP_INVOKE_VIRTUAL:
+ case OP_INVOKE_VIRTUAL_RANGE:
+#ifdef PREDICTED_CHAINING
+ numTmps = updateGenPrediction(infoArray, false /*not interface*/);
+ infoArray[numTmps].regNum = 5;
+ infoArray[numTmps].refCount = 3; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ if(inst_op == OP_INVOKE_VIRTUAL)
+ k = updateInvokeNoRange(infoArray, numTmps);
+ else
+ k = updateInvokeRange(infoArray, numTmps);
+ return k;
+#else
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 7;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 8;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 6;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 3; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = PhysicalReg_EDX;
+ infoArray[5].refCount = 2; //2 versions, first version DU is for exception, 2nd version: eip right before jumping to invokeArgsDone
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = PhysicalReg_ECX; //ecx is ued in invokeArgsDone
+ infoArray[6].refCount = 1+1; //used in .invokeArgsDone
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ //when WITH_JIT is true and PREDICTED_CHAINING is false
+ // temp 8 and EAX are not used; but it is okay to keep it here
+ infoArray[7].regNum = PhysicalReg_EAX;
+ infoArray[7].refCount = 4; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[8].regNum = 1;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[9].regNum = 2;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_VIRTUAL)
+ k = updateInvokeNoRange(infoArray, 10);
+ else
+ k = updateInvokeRange(infoArray, 10);
+ return k;
+#endif
+ case OP_INVOKE_SUPER:
+ case OP_INVOKE_SUPER_RANGE:
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 7;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 8;
+ infoArray[2].refCount = 3; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 6;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 9;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+
+ infoArray[5].regNum = PhysicalReg_EDX;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = PhysicalReg_ECX;
+ infoArray[6].refCount = 1+1; //DU
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[7].regNum = PhysicalReg_EAX;
+ infoArray[7].refCount = 4; //DU
+ infoArray[7].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[8].regNum = 1;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[9].regNum = 2;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_scratch;
+ infoArray[10].regNum = 3;
+ infoArray[10].refCount = 2; //DU
+ infoArray[10].physicalType = LowOpndRegType_scratch;
+ infoArray[11].regNum = 4;
+ infoArray[11].refCount = 2; //DU
+ infoArray[11].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_SUPER)
+ k = updateInvokeNoRange(infoArray, 12);
+ else
+ k = updateInvokeRange(infoArray, 12);
+ return k;
+ case OP_INVOKE_DIRECT:
+ case OP_INVOKE_DIRECT_RANGE:
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 5;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+
+ infoArray[2].regNum = PhysicalReg_EDX;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = PhysicalReg_ECX;
+ infoArray[3].refCount = 2;
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = PhysicalReg_EAX;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = 2;
+ infoArray[6].refCount = 2; //DU
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_DIRECT)
+ k = updateInvokeNoRange(infoArray, 7);
+ else
+ k = updateInvokeRange(infoArray, 7);
+ return k;
+ case OP_INVOKE_STATIC:
+ case OP_INVOKE_STATIC_RANGE:
+ infoArray[0].regNum = 3;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+
+ infoArray[1].regNum = PhysicalReg_EDX;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[2].regNum = PhysicalReg_ECX;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[4].regNum = 1;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ infoArray[5].regNum = 2;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_STATIC)
+ k = updateInvokeNoRange(infoArray, 6);
+ else
+ k = updateInvokeRange(infoArray, 6);
+ return k;
+ case OP_INVOKE_INTERFACE:
+ case OP_INVOKE_INTERFACE_RANGE:
+#ifdef PREDICTED_CHAINING
+ numTmps = updateGenPrediction(infoArray, true /*interface*/);
+ infoArray[numTmps].regNum = 1;
+ infoArray[numTmps].refCount = 3; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ if(inst_op == OP_INVOKE_INTERFACE)
+ k = updateInvokeNoRange(infoArray, numTmps);
+ else
+ k = updateInvokeRange(infoArray, numTmps);
+ return k;
+#else
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 3;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 4;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[5].regNum = PhysicalReg_ECX;
+ infoArray[5].refCount = 1+1; //DU
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[6].regNum = PhysicalReg_EAX;
+ infoArray[6].refCount = 2+1; //2 uses
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[7].regNum = 1;
+ infoArray[7].refCount = 2; //DU
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ infoArray[8].regNum = 2;
+ infoArray[8].refCount = 2; //DU
+ infoArray[8].physicalType = LowOpndRegType_scratch;
+ infoArray[9].regNum = 3;
+ infoArray[9].refCount = 2; //DU
+ infoArray[9].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_INTERFACE)
+ k = updateInvokeNoRange(infoArray, 10);
+ else
+ k = updateInvokeRange(infoArray, 10);
+ return k;
+#endif
+ ////////////////////////////////////////////// ALU
+ case OP_NEG_INT:
+ case OP_NOT_INT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].shareWithVR = false;
+ return 1;
+ case OP_NEG_LONG:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //define, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 4; //define, update, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_NOT_LONG:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_NEG_FLOAT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].shareWithVR = false;
+ return 1;
+ case OP_NEG_DOUBLE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //define, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //define, update, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_INT_TO_LONG: //hard-code eax & edx
+ infoArray[0].regNum = PhysicalReg_EAX;
+ infoArray[0].refCount = 2+1;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = PhysicalReg_EDX;
+ infoArray[1].refCount = 1+1; //cdq accesses edx & eax
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 2;
+ case OP_INT_TO_FLOAT:
+ case OP_INT_TO_DOUBLE:
+ case OP_LONG_TO_FLOAT:
+ case OP_LONG_TO_DOUBLE:
+ case OP_FLOAT_TO_DOUBLE:
+ case OP_DOUBLE_TO_FLOAT:
+ return 0; //fp stack
+ case OP_LONG_TO_INT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ return 1;
+ case OP_FLOAT_TO_INT:
+ case OP_DOUBLE_TO_INT: //fp stack
+ return 0;
+ case OP_FLOAT_TO_LONG:
+ case OP_DOUBLE_TO_LONG:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //define, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //define, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //define, use
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ return 3;
+ case OP_INT_TO_BYTE:
+ case OP_INT_TO_CHAR:
+ case OP_INT_TO_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //define, update, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].shareWithVR = false;
+ return 1;
+
+ case OP_ADD_INT:
+ case OP_SUB_INT:
+ case OP_MUL_INT:
+ case OP_AND_INT:
+ case OP_OR_INT:
+ case OP_XOR_INT:
+ case OP_ADD_INT_2ADDR:
+ case OP_SUB_INT_2ADDR:
+ case OP_MUL_INT_2ADDR:
+ case OP_AND_INT_2ADDR:
+ case OP_OR_INT_2ADDR:
+ case OP_XOR_INT_2ADDR:
+ if(inst_op == OP_ADD_INT || inst_op == OP_SUB_INT || inst_op == OP_MUL_INT ||
+ inst_op == OP_AND_INT || inst_op == OP_OR_INT || inst_op == OP_XOR_INT) {
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ } else {
+ vA = INST_A(inst);
+ v1 = vA;
+ }
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ if(vA != v1)
+ infoArray[0].shareWithVR = false;
+ return 1; //common_alu_int
+
+ case OP_SHL_INT:
+ case OP_SHR_INT:
+ case OP_USHR_INT:
+ case OP_SHL_INT_2ADDR:
+ case OP_SHR_INT_2ADDR:
+ case OP_USHR_INT_2ADDR: //use %cl or %ecx?
+ if(inst_op == OP_SHL_INT || inst_op == OP_SHR_INT || inst_op == OP_USHR_INT) {
+ vA = INST_AA(inst);
+ v1 = *((u1*)rPC + 2);
+ } else {
+ vA = INST_A(inst);
+ v1 = vA;
+ }
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ if(vA != v1)
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = PhysicalReg_ECX;
+ infoArray[1].refCount = 2; //define, use
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 2;//common_shift_int
+
+ case OP_DIV_INT:
+ case OP_REM_INT:
+ case OP_DIV_INT_2ADDR:
+ case OP_REM_INT_2ADDR: //hard-code %eax, %edx (dividend in edx:eax; quotient in eax; remainder in edx)
+ infoArray[0].regNum = 2;
+ infoArray[0].refCount = 4; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EAX; //dividend, quotient
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].shareWithVR = false;
+ infoArray[2].regNum = PhysicalReg_EDX; //export_pc, output for REM
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //define, use
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_DIV_INT || inst_op == OP_DIV_INT_2ADDR) {
+ infoArray[1].refCount = 5;
+ infoArray[2].refCount = 4;
+ } else {
+ infoArray[1].refCount = 4;
+ infoArray[2].refCount = 5;
+ }
+ return 4;
+
+ case OP_ADD_INT_LIT16:
+ case OP_MUL_INT_LIT16:
+ case OP_AND_INT_LIT16:
+ case OP_OR_INT_LIT16:
+ case OP_XOR_INT_LIT16:
+ case OP_ADD_INT_LIT8:
+ case OP_MUL_INT_LIT8:
+ case OP_AND_INT_LIT8:
+ case OP_OR_INT_LIT8:
+ case OP_XOR_INT_LIT8:
+ case OP_SHL_INT_LIT8:
+ case OP_SHR_INT_LIT8:
+ case OP_USHR_INT_LIT8:
+ if(inst_op == OP_ADD_INT_LIT16 || inst_op == OP_MUL_INT_LIT16 ||
+ inst_op == OP_AND_INT_LIT16 || inst_op == OP_OR_INT_LIT16 || inst_op == OP_XOR_INT_LIT16) {
+ vA = INST_A(inst);
+ v1 = INST_B(inst);
+ } else {
+ vA = INST_AA(inst);
+ v1 = (u2)FETCH(1) & 0xff;
+ }
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ if(vA != v1)
+ infoArray[0].shareWithVR = false;
+ return 1;
+
+ case OP_RSUB_INT_LIT8:
+ case OP_RSUB_INT:
+ vA = INST_AA(inst);
+ v1 = (inst_op == OP_RSUB_INT) ? INST_B(inst) : ((u2)FETCH(1) & 0xff);
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ if(vA != v1)
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ if(vA != v1)
+ infoArray[1].shareWithVR = false;
+ return 2;
+
+ case OP_DIV_INT_LIT16:
+ case OP_REM_INT_LIT16:
+ case OP_DIV_INT_LIT8:
+ case OP_REM_INT_LIT8:
+ if(inst_op == OP_DIV_INT_LIT8 || inst_op == OP_REM_INT_LIT8) {
+ tmp_s2 = (s2)FETCH(1) >> 8;
+ }
+ else {
+ tmp_s4 = (s2)FETCH(1);
+ tmp_s2 = tmp_s4;
+ }
+ if((inst_op == OP_DIV_INT_LIT8 || inst_op == OP_DIV_INT_LIT16)) {
+ int power = isPowerOfTwo(tmp_s2);
+ if(power >= 1) { /* divide by a power of 2 constant */
+ infoArray[0].regNum = 2;
+ infoArray[0].refCount = 3; //define, use, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ if(power == 1) infoArray[1].refCount = 5;
+ else infoArray[1].refCount = 6;
+ return 2;
+ }
+ }
+ if(tmp_s2 == 0) {
+ //export_pc
+ infoArray[0].regNum = PhysicalReg_EDX; //export_pc, output for REM
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 1;
+ }
+ if(inst_op == OP_DIV_INT_LIT16 || inst_op == OP_DIV_INT_LIT8) {
+ if(tmp_s2 == -1)
+ infoArray[1].refCount = 4+1;
+ else
+ infoArray[1].refCount = 4;
+ infoArray[2].refCount = 2; //edx
+ } else {
+ if(tmp_s2 == -1)
+ infoArray[1].refCount = 3+1;
+ else
+ infoArray[1].refCount = 3;
+ infoArray[2].refCount = 3; //edx
+ }
+ infoArray[0].regNum = 2;
+ infoArray[0].refCount = 2; //define, use
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EAX; //dividend, quotient
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[1].shareWithVR = false;
+ infoArray[2].regNum = PhysicalReg_EDX; //export_pc, output for REM
+ infoArray[2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 3;
+
+ case OP_ADD_LONG:
+ case OP_SUB_LONG:
+ case OP_AND_LONG:
+ case OP_OR_LONG:
+ case OP_XOR_LONG:
+ case OP_ADD_LONG_2ADDR:
+ case OP_SUB_LONG_2ADDR:
+ case OP_AND_LONG_2ADDR:
+ case OP_OR_LONG_2ADDR:
+ case OP_XOR_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //define, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+
+ case OP_SHL_LONG:
+ case OP_SHL_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //define, update, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[1].shareWithVR = false;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //define, use
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ return 3;
+
+ case OP_SHR_LONG:
+ case OP_SHR_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 4; //define, update, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[1].shareWithVR = false;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //define, use
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 3;
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 3;
+ infoArray[4].physicalType = LowOpndRegType_xmm;
+ return 5;
+
+ case OP_USHR_LONG:
+ case OP_USHR_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //define, update, use
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //define, update, use
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[1].shareWithVR = false;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //define, use
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ return 3;
+
+ case OP_MUL_LONG: //general purpose register
+ case OP_MUL_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 6;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 2+1; //for mul_opc
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2; //for mul_opc
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 5;
+
+ case OP_DIV_LONG:
+ case OP_REM_LONG:
+ case OP_DIV_LONG_2ADDR:
+ case OP_REM_LONG_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_xmm;
+ infoArray[3].regNum = PhysicalReg_EAX;
+ infoArray[3].refCount = 2; //defined by function call
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2; //next version has 2 references
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2;
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ return 6;
+
+ case OP_ADD_FLOAT:
+ case OP_SUB_FLOAT:
+ case OP_MUL_FLOAT:
+ case OP_ADD_FLOAT_2ADDR:
+ case OP_SUB_FLOAT_2ADDR:
+ case OP_MUL_FLOAT_2ADDR:
+ case OP_ADD_DOUBLE: //PhysicalReg_FP TODO
+ case OP_SUB_DOUBLE:
+ case OP_MUL_DOUBLE:
+ case OP_ADD_DOUBLE_2ADDR:
+ case OP_SUB_DOUBLE_2ADDR:
+ case OP_MUL_DOUBLE_2ADDR:
+ case OP_DIV_FLOAT:
+ case OP_DIV_FLOAT_2ADDR:
+ case OP_DIV_DOUBLE:
+ case OP_DIV_DOUBLE_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ //for ALU ops with 2ADDR, the temp variable can share the same physical
+ //reg as the virtual register, since the content of VR is updated by
+ //the content of the temp variable
+ if(inst_op == OP_ADD_FLOAT || inst_op == OP_SUB_FLOAT ||
+ inst_op == OP_MUL_FLOAT || inst_op == OP_ADD_DOUBLE ||
+ inst_op == OP_SUB_DOUBLE || inst_op == OP_MUL_DOUBLE ||
+ inst_op == OP_DIV_FLOAT || inst_op == OP_DIV_DOUBLE)
+ infoArray[0].shareWithVR = false;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_REM_FLOAT:
+ case OP_REM_FLOAT_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ return 3;
+
+ case OP_REM_DOUBLE:
+ case OP_REM_DOUBLE_2ADDR:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ return 3;
+
+ case OP_CMPL_FLOAT:
+ case OP_CMPL_DOUBLE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 2;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 2;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 4; //return
+ infoArray[4].refCount = 5;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ return 5;
+
+ case OP_CMPG_FLOAT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 2;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 5;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ return 4;
+ break;
+ case OP_CMPG_DOUBLE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_xmm;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 2;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 3;
+ infoArray[3].refCount = 5;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ return 4;
+
+ case OP_CMP_LONG:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 3;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 6;
+ infoArray[5].refCount = 7;
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ return 6;
+
+ case OP_EXECUTE_INLINE:
+ case OP_EXECUTE_INLINE_RANGE:
+ if(inst_op == OP_EXECUTE_INLINE)
+ num = INST_B(inst);
+ else
+ num = INST_AA(inst);
+ tmp = FETCH(1);
+ switch (tmp) {
+ case INLINE_STRING_LENGTH:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2;
+ infoArray[3].physicalType = LowOpndRegType_scratch;
+ return 4;
+ case INLINE_STRING_IS_EMPTY:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 4;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 1;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_scratch;
+ return 3;
+ case INLINE_STRING_FASTINDEXOF_II:
+#if defined(USE_GLOBAL_STRING_DEFS)
+ break;
+#else
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 14 * LOOP_COUNT;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3 * LOOP_COUNT;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 11 * LOOP_COUNT;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 3 * LOOP_COUNT;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 9 * LOOP_COUNT;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 6;
+ infoArray[5].refCount = 4 * LOOP_COUNT;
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ infoArray[6].regNum = 7;
+ infoArray[6].refCount = 2;
+ infoArray[6].physicalType = LowOpndRegType_gp;
+ infoArray[7].regNum = 1;
+ infoArray[7].refCount = 2;
+ infoArray[7].physicalType = LowOpndRegType_scratch;
+ return 8;
+#endif
+ case INLINE_MATH_ABS_LONG:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 7;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 3;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 6;
+ infoArray[5].refCount = 5;
+ infoArray[5].physicalType = LowOpndRegType_gp;
+ return 6;
+ case INLINE_MATH_ABS_INT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 5;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 4;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ return 3;
+ case INLINE_MATH_MAX_INT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ return 3;
+ case INLINE_MATH_ABS_FLOAT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ return 2;
+ case INLINE_MATH_ABS_DOUBLE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ return 3;
+ case INLINE_FLOAT_TO_RAW_INT_BITS:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ return 2;
+ case INLINE_INT_BITS_TO_FLOAT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ return 2;
+ case INLINE_DOUBLE_TO_RAW_LONG_BITS:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ return 3;
+ case INLINE_LONG_BITS_TO_DOUBLE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 3;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ return 3;
+ default:
+ break;
+ }
+
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 4;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ if(num >= 1) {
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 2) {
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 3) {
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 2;
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ }
+ if(num >= 4) {
+ infoArray[4].regNum = 5;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ }
+ infoArray[num+1].regNum = 6;
+ infoArray[num+1].refCount = 2;
+ infoArray[num+1].physicalType = LowOpndRegType_gp;
+ infoArray[num+2].regNum = PhysicalReg_EAX;
+ infoArray[num+2].refCount = 2;
+ infoArray[num+2].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[num+3].regNum = PhysicalReg_EDX;
+ infoArray[num+3].refCount = 2;
+ infoArray[num+3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[num+4].regNum = 1;
+ infoArray[num+4].refCount = 4;
+ infoArray[num+4].physicalType = LowOpndRegType_scratch;
+ return num+5;
+#if FIXME
+ case OP_INVOKE_OBJECT_INIT_RANGE:
+ return 0;
+#endif
+ case OP_INVOKE_VIRTUAL_QUICK:
+ case OP_INVOKE_VIRTUAL_QUICK_RANGE:
+#ifdef PREDICTED_CHAINING
+ numTmps = updateGenPrediction(infoArray, false /*not interface*/);
+ infoArray[numTmps].regNum = 1;
+ infoArray[numTmps].refCount = 3; //DU
+ infoArray[numTmps].physicalType = LowOpndRegType_gp;
+ numTmps++;
+ if(inst_op == OP_INVOKE_VIRTUAL_QUICK)
+ k = updateInvokeNoRange(infoArray, numTmps);
+ else
+ k = updateInvokeRange(infoArray, numTmps);
+ return k;
+#else
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+
+ infoArray[3].regNum = PhysicalReg_ECX;
+ infoArray[3].refCount = 1+1;
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ if(inst_op == OP_INVOKE_VIRTUAL_QUICK_RANGE)
+ k = updateInvokeRange(infoArray, 5);
+ else
+ k = updateInvokeNoRange(infoArray, 5);
+ return k;
+#endif
+ case OP_INVOKE_SUPER_QUICK:
+ case OP_INVOKE_SUPER_QUICK_RANGE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2;
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 4;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 5;
+ infoArray[2].refCount = 2;
+ infoArray[2].physicalType = LowOpndRegType_gp;
+
+ infoArray[3].regNum = PhysicalReg_ECX;
+ infoArray[3].refCount = 1+1;
+ infoArray[3].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ infoArray[4].regNum = PhysicalReg_EDX;
+ infoArray[4].refCount = 2;
+ infoArray[4].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2;
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = 2;
+ infoArray[6].refCount = 2;
+ infoArray[6].physicalType = LowOpndRegType_scratch;
+ if(inst_op == OP_INVOKE_SUPER_QUICK_RANGE)
+ k = updateInvokeRange(infoArray, 7);
+ else
+ k = updateInvokeNoRange(infoArray, 7);
+ return k;
+#ifdef SUPPORT_HLO
+ case kExtInstruction:
+ switch(inst) {
+ case OP_X_AGET_QUICK:
+ case OP_X_AGET_OBJECT_QUICK:
+ case OP_X_AGET_BOOLEAN_QUICK:
+ case OP_X_AGET_BYTE_QUICK:
+ case OP_X_AGET_CHAR_QUICK:
+ case OP_X_AGET_SHORT_QUICK:
+ vA = FETCH(1) & 0xff;
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[3].linkageToVR = vA;
+ if(inst == OP_X_AGET_BYTE_QUICK || inst == OP_X_AGET_BOOLEAN_QUICK)
+ infoArray[3].is8Bit = true;
+ return 4;
+ case OP_X_AGET_WIDE_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ return 4;
+ case OP_X_APUT_QUICK:
+ case OP_X_APUT_OBJECT_QUICK:
+ case OP_X_APUT_BOOLEAN_QUICK:
+ case OP_X_APUT_BYTE_QUICK:
+ case OP_X_APUT_CHAR_QUICK:
+ case OP_X_APUT_SHORT_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 4;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ if(inst == OP_X_APUT_BYTE_QUICK || inst == OP_X_APUT_BOOLEAN_QUICK)
+ infoArray[3].is8Bit = true;
+ return 4;
+ case OP_X_APUT_WIDE_QUICK:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 1;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_xmm;
+ return 4;
+ case OP_X_DEREF_GET:
+ case OP_X_DEREF_GET_OBJECT:
+ case OP_X_DEREF_GET_BOOLEAN:
+ case OP_X_DEREF_GET_BYTE:
+ case OP_X_DEREF_GET_CHAR:
+ case OP_X_DEREF_GET_SHORT:
+ vA = FETCH(1) & 0xff;
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[1].linkageToVR = vA;
+ if(inst == OP_X_DEREF_GET_BYTE || inst == OP_X_DEREF_GET_BOOLEAN)
+ infoArray[1].is8Bit = true;
+ return 2;
+ case OP_X_DEREF_GET_WIDE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_X_DEREF_PUT:
+ case OP_X_DEREF_PUT_OBJECT:
+ case OP_X_DEREF_PUT_BOOLEAN:
+ case OP_X_DEREF_PUT_BYTE:
+ case OP_X_DEREF_PUT_CHAR:
+ case OP_X_DEREF_PUT_SHORT:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ if(inst == OP_X_DEREF_PUT_BYTE || inst == OP_X_DEREF_PUT_BOOLEAN)
+ infoArray[1].is8Bit = true;
+ return 2;
+ case OP_X_DEREF_PUT_WIDE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 1;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_xmm;
+ return 2;
+ case OP_X_ARRAY_CHECKS:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ return 2;
+ case OP_X_CHECK_BOUNDS:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 2; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ return 2;
+ case OP_X_CHECK_NULL:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 2; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = PhysicalReg_EDX;
+ infoArray[1].refCount = 2;
+ infoArray[1].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 2;
+ case OP_X_CHECK_TYPE:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 3; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 5;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 6;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 1;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_scratch;
+ infoArray[5].regNum = PhysicalReg_EAX;
+ infoArray[5].refCount = 2;
+ infoArray[5].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 6;
+ case OP_X_ARRAY_OBJECT_CHECKS:
+ infoArray[0].regNum = 1;
+ infoArray[0].refCount = 3; //DU
+ infoArray[0].physicalType = LowOpndRegType_gp;
+ infoArray[1].regNum = 2;
+ infoArray[1].refCount = 4; //DU
+ infoArray[1].physicalType = LowOpndRegType_gp;
+ infoArray[2].regNum = 3;
+ infoArray[2].refCount = 2; //DU
+ infoArray[2].physicalType = LowOpndRegType_gp;
+ infoArray[3].regNum = 5;
+ infoArray[3].refCount = 2; //DU
+ infoArray[3].physicalType = LowOpndRegType_gp;
+ infoArray[4].regNum = 6;
+ infoArray[4].refCount = 2; //DU
+ infoArray[4].physicalType = LowOpndRegType_gp;
+ infoArray[5].regNum = 1;
+ infoArray[5].refCount = 2; //DU
+ infoArray[5].physicalType = LowOpndRegType_scratch;
+ infoArray[6].regNum = PhysicalReg_EAX;
+ infoArray[6].refCount = 2;
+ infoArray[6].physicalType = LowOpndRegType_gp | LowOpndRegType_hard;
+ return 7;
+ }
+#endif
+ }
+ return -1;
+}