/* * 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 LowerMove.cpp \brief This file lowers the following bytecodes: MOVE_XXX */ #include "libdex/DexOpcodes.h" #include "libdex/DexFile.h" #include "Lower.h" #include "enc_wrapper.h" #define P_GPR_1 PhysicalReg_EBX //! lower bytecode MOVE //! int op_move() { u2 vA, vB; vA = INST_A(inst); vB = INST_B(inst); get_virtual_reg(vB, OpndSize_32, 1, false/*isPhysical*/); set_virtual_reg(vA, OpndSize_32, 1, false); rPC += 1; return 2; } //! lower bytecode MOVE_FROM16 //! int op_move_from16() { u2 vA, vB; vA = INST_AA(inst); vB = FETCH(1); get_virtual_reg(vB, OpndSize_32, 1, false); set_virtual_reg(vA, OpndSize_32, 1, false); rPC += 2; return 2; } //! lower bytecode MOVE_16 //! int op_move_16() { u2 vA, vB; vA = FETCH(1); vB = FETCH(2); get_virtual_reg(vB, OpndSize_32, 1, false); set_virtual_reg(vA, OpndSize_32, 1, false); rPC += 3; return 2; } #undef P_GPR_1 //! lower bytecode MOVE_WIDE //! int op_move_wide() { u2 vA = INST_A(inst); u2 vB = INST_B(inst); get_virtual_reg(vB, OpndSize_64, 1, false); set_virtual_reg(vA, OpndSize_64, 1, false); rPC += 1; return 2; } //! lower bytecode MOVE_WIDE_FROM16 //! int op_move_wide_from16() { u2 vA = INST_AA(inst); u2 vB = FETCH(1); get_virtual_reg(vB, OpndSize_64, 1, false); set_virtual_reg(vA, OpndSize_64, 1, false); rPC += 2; return 2; } //! lower bytecode MOVE_WIDE_16 //! int op_move_wide_16() { u2 vA = FETCH(1); u2 vB = FETCH(2); get_virtual_reg(vB, OpndSize_64, 1, false); set_virtual_reg(vA, OpndSize_64, 1, false); rPC += 3; return 2; } //! lower bytecode MOVE_RESULT. //! the return value from bytecode INVOKE is stored in the glue structure int op_move_result() { #ifdef WITH_JIT_INLINING /* An inlined move result is effectively no-op */ if (traceCurrentMIR->OptimizationFlags & MIR_INLINED) return 0; #endif u2 vA = INST_AA(inst); scratchRegs[0] = PhysicalReg_SCRATCH_1; get_return_value(OpndSize_32, 1, false); set_virtual_reg(vA, OpndSize_32, 1, false); rPC += 1; return 0; } //! lower bytecode MOVE_RESULT_WIDE. //! the return value from bytecode INVOKE is stored in the glue structure int op_move_result_wide() { #ifdef WITH_JIT_INLINING /* An inlined move result is effectively no-op */ if (traceCurrentMIR->OptimizationFlags & MIR_INLINED) return 0; #endif u2 vA = INST_AA(inst); scratchRegs[0] = PhysicalReg_SCRATCH_1; get_return_value(OpndSize_64, 1, false); set_virtual_reg(vA, OpndSize_64, 1, false); rPC += 1; return 0; } #define P_GPR_1 PhysicalReg_EBX #define P_GPR_2 PhysicalReg_ECX //!lower bytecode MOVE_RESULT_EXCEPTION //!update a virtual register with exception from glue structure; //!clear the exception from glue structure int op_move_exception() { u2 vA = INST_AA(inst); scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null; scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_Null; get_self_pointer(2, false); move_mem_to_reg(OpndSize_32, offThread_exception, 2, false, 3, false); move_imm_to_mem(OpndSize_32, 0, offThread_exception, 2, false); set_virtual_reg(vA, OpndSize_32, 3, false); rPC += 1; return 0; } #undef P_GPR_1 #undef P_GPR_2