| /* |
| * 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 |
| |