diff options
Diffstat (limited to 'vm/compiler/codegen/x86/BytecodeVisitor.cpp')
| -rw-r--r-- | vm/compiler/codegen/x86/BytecodeVisitor.cpp | 5468 |
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; +} |
