Home | History | Annotate | Download | only in x86
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 /*! \file LowerMove.cpp
     19     \brief This file lowers the following bytecodes: MOVE_XXX
     20 */
     21 #include "libdex/DexOpcodes.h"
     22 #include "libdex/DexFile.h"
     23 #include "Lower.h"
     24 #include "enc_wrapper.h"
     25 
     26 #define P_GPR_1 PhysicalReg_EBX
     27 //! lower bytecode MOVE
     28 
     29 //!
     30 int op_move() {
     31     u2 vA, vB;
     32     vA = INST_A(inst);
     33     vB = INST_B(inst);
     34     get_virtual_reg(vB, OpndSize_32, 1, false/*isPhysical*/);
     35     set_virtual_reg(vA, OpndSize_32, 1, false);
     36     rPC += 1;
     37     return 2;
     38 }
     39 //! lower bytecode MOVE_FROM16
     40 
     41 //!
     42 int op_move_from16() {
     43     u2 vA, vB;
     44     vA = INST_AA(inst);
     45     vB = FETCH(1);
     46     get_virtual_reg(vB, OpndSize_32, 1, false);
     47     set_virtual_reg(vA, OpndSize_32, 1, false);
     48     rPC += 2;
     49     return 2;
     50 }
     51 //! lower bytecode MOVE_16
     52 
     53 //!
     54 int op_move_16() {
     55     u2 vA, vB;
     56     vA = FETCH(1);
     57     vB = FETCH(2);
     58     get_virtual_reg(vB, OpndSize_32, 1, false);
     59     set_virtual_reg(vA, OpndSize_32, 1, false);
     60     rPC += 3;
     61     return 2;
     62 }
     63 #undef P_GPR_1
     64 //! lower bytecode MOVE_WIDE
     65 
     66 //!
     67 int op_move_wide() {
     68     u2 vA = INST_A(inst);
     69     u2 vB = INST_B(inst);
     70     get_virtual_reg(vB, OpndSize_64, 1, false);
     71     set_virtual_reg(vA, OpndSize_64, 1, false);
     72     rPC += 1;
     73     return 2;
     74 }
     75 //! lower bytecode MOVE_WIDE_FROM16
     76 
     77 //!
     78 int op_move_wide_from16() {
     79     u2 vA = INST_AA(inst);
     80     u2 vB = FETCH(1);
     81     get_virtual_reg(vB, OpndSize_64, 1, false);
     82     set_virtual_reg(vA, OpndSize_64, 1, false);
     83     rPC += 2;
     84     return 2;
     85 }
     86 //! lower bytecode MOVE_WIDE_16
     87 
     88 //!
     89 int op_move_wide_16() {
     90     u2 vA = FETCH(1);
     91     u2 vB = FETCH(2);
     92     get_virtual_reg(vB, OpndSize_64, 1, false);
     93     set_virtual_reg(vA, OpndSize_64, 1, false);
     94     rPC += 3;
     95     return 2;
     96 }
     97 //! lower bytecode MOVE_RESULT.
     98 
     99 //! the return value from bytecode INVOKE is stored in the glue structure
    100 int op_move_result() {
    101 #ifdef WITH_JIT_INLINING
    102     /* An inlined move result is effectively no-op */
    103     if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
    104         return 0;
    105 #endif
    106     u2 vA = INST_AA(inst);
    107     scratchRegs[0] = PhysicalReg_SCRATCH_1;
    108     get_return_value(OpndSize_32, 1, false);
    109     set_virtual_reg(vA, OpndSize_32, 1, false);
    110     rPC += 1;
    111     return 0;
    112 }
    113 //! lower bytecode MOVE_RESULT_WIDE.
    114 
    115 //! the return value from bytecode INVOKE is stored in the glue structure
    116 int op_move_result_wide() {
    117 #ifdef WITH_JIT_INLINING
    118     /* An inlined move result is effectively no-op */
    119     if (traceCurrentMIR->OptimizationFlags & MIR_INLINED)
    120         return 0;
    121 #endif
    122     u2 vA = INST_AA(inst);
    123     scratchRegs[0] = PhysicalReg_SCRATCH_1;
    124     get_return_value(OpndSize_64, 1, false);
    125     set_virtual_reg(vA, OpndSize_64, 1, false);
    126     rPC += 1;
    127     return 0;
    128 }
    129 
    130 #define P_GPR_1 PhysicalReg_EBX
    131 #define P_GPR_2 PhysicalReg_ECX
    132 //!lower bytecode MOVE_RESULT_EXCEPTION
    133 
    134 //!update a virtual register with exception from glue structure;
    135 //!clear the exception from glue structure
    136 int op_move_exception() {
    137     u2 vA = INST_AA(inst);
    138     scratchRegs[2] = PhysicalReg_Null; scratchRegs[3] = PhysicalReg_Null;
    139     scratchRegs[0] = PhysicalReg_SCRATCH_1; scratchRegs[1] = PhysicalReg_Null;
    140     get_self_pointer(2, false);
    141     move_mem_to_reg(OpndSize_32, offThread_exception, 2, false, 3, false);
    142     move_imm_to_mem(OpndSize_32, 0, offThread_exception, 2, false);
    143     set_virtual_reg(vA, OpndSize_32, 3, false);
    144     rPC += 1;
    145     return 0;
    146 }
    147 #undef P_GPR_1
    148 #undef P_GPR_2
    149 
    150