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