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 LowerConst.cpp
     19     \brief This file lowers the following bytecodes: CONST_XXX
     20 
     21     Functions are called from the lowered native sequence:
     22     1> const_string_resolve
     23        INPUT: const pool index in %eax
     24        OUTPUT: resolved string in %eax
     25        The only register that is still live after this function is ebx
     26     2> class_resolve
     27        INPUT: const pool index in %eax
     28        OUTPUT: resolved class in %eax
     29        The only register that is still live after this function is ebx
     30 */
     31 #include "libdex/DexOpcodes.h"
     32 #include "libdex/DexFile.h"
     33 #include "Lower.h"
     34 #include "NcgAot.h"
     35 #include "enc_wrapper.h"
     36 
     37 #define P_GPR_1 PhysicalReg_EBX
     38 #define P_GPR_2 PhysicalReg_ECX
     39 
     40 //! LOWER bytecode CONST_STRING without usage of helper function
     41 
     42 //! It calls const_string_resolve (%ebx is live across the call)
     43 //! Since the register allocator does not handle control flow within the lowered native sequence,
     44 //!   we define an interface between the lowering module and register allocator:
     45 //!     rememberState, gotoState, transferToState
     46 //!   to make sure at the control flow merge point the state of registers is the same
     47 int const_string_common_nohelper(u4 tmp, u2 vA) {
     48     /* for trace-based JIT, the string is already resolved since this code has been executed */
     49     void *strPtr = (void*)
     50               (currentMethod->clazz->pDvmDex->pResStrings[tmp]);
     51     assert(strPtr != NULL);
     52     set_VR_to_imm(vA, OpndSize_32, (int) strPtr );
     53     return 0;
     54 }
     55 //! dispatcher to select either const_string_common_helper or const_string_common_nohelper
     56 
     57 //!
     58 int const_string_common(u4 tmp, u2 vA) {
     59     return const_string_common_nohelper(tmp, vA);
     60 }
     61 #undef P_GPR_1
     62 #undef P_GPR_2
     63 
     64 //! lower bytecode CONST_4
     65 
     66 //!
     67 int op_const_4() {
     68     u2 vA = INST_A(inst);
     69     s4 tmp = (s4) (INST_B(inst) << 28) >> 28;
     70     set_VR_to_imm(vA, OpndSize_32, tmp);
     71     rPC += 1;
     72     return 1;
     73 }
     74 //! lower bytecode CONST_16
     75 
     76 //!
     77 int op_const_16() {
     78     u2 BBBB = FETCH(1);
     79     u2 vA = INST_AA(inst);
     80     set_VR_to_imm(vA, OpndSize_32, (s2)BBBB);
     81     rPC += 2;
     82     return 1;
     83 }
     84 //! lower bytecode CONST
     85 
     86 //!
     87 int op_const() {
     88     u2 vA = INST_AA(inst);
     89     u4 tmp = FETCH(1);
     90     tmp |= (u4)FETCH(2) << 16;
     91     set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
     92     rPC += 3;
     93     return 1;
     94 }
     95 //! lower bytecode CONST_HIGH16
     96 
     97 //!
     98 int op_const_high16() {
     99     u2 vA = INST_AA(inst);
    100     u2 tmp = FETCH(1);
    101     set_VR_to_imm(vA, OpndSize_32, (s4)tmp<<16); //??
    102     rPC += 2;
    103     return 1;
    104 }
    105 //! lower bytecode CONST_WIDE_16
    106 
    107 //!
    108 int op_const_wide_16() {
    109     u2 vA = INST_AA(inst);
    110     u2 tmp = FETCH(1);
    111     set_VR_to_imm(vA, OpndSize_32, (s2)tmp);
    112     set_VR_to_imm(vA+1, OpndSize_32, (s2)tmp>>31);
    113     rPC += 2;
    114     return 2;
    115 }
    116 //! lower bytecode CONST_WIDE_32
    117 
    118 //!
    119 int op_const_wide_32() {
    120     u2 vA = INST_AA(inst);
    121     u4 tmp = FETCH(1);
    122     tmp |= (u4)FETCH(2) << 16;
    123     set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
    124     set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp>>31);
    125     rPC += 3;
    126     return 2;
    127 }
    128 //! lower bytecode CONST_WIDE
    129 
    130 //!
    131 int op_const_wide() {
    132     u2 vA = INST_AA(inst);
    133     u4 tmp = FETCH(1);
    134     tmp |= (u8)FETCH(2) << 16;
    135     set_VR_to_imm(vA, OpndSize_32, (s4)tmp);
    136     tmp = (u8)FETCH(3);
    137     tmp |= (u8)FETCH(4) << 16;
    138     set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp);
    139     rPC += 5;
    140     return 2;
    141 }
    142 //! lower bytecode CONST_WIDE_HIGH16
    143 
    144 //!
    145 int op_const_wide_high16() {
    146     u2 vA = INST_AA(inst);
    147     u2 tmp = FETCH(1);
    148     set_VR_to_imm(vA, OpndSize_32, 0);
    149     set_VR_to_imm(vA+1, OpndSize_32, (s4)tmp<<16);
    150     rPC += 2;
    151     return 2;
    152 }
    153 //! lower bytecode CONST_STRING
    154 
    155 //!
    156 int op_const_string() {
    157     u2 vB = FETCH(1);
    158     u2 vA = INST_AA(inst);
    159     u4 tmp = vB;
    160     int retval = const_string_common(tmp, vA);
    161     rPC += 2;
    162     return retval;
    163 }
    164 //! lower bytecode CONST_STRING_JUMBO
    165 
    166 //!
    167 int op_const_string_jumbo() {
    168     u2 vA = INST_AA(inst);
    169     u4 tmp = FETCH(1);
    170     tmp |= (u4)FETCH(2) << 16;
    171     int retval = const_string_common(tmp, vA);
    172     rPC += 3;
    173     return retval;
    174 }
    175 
    176 #define P_GPR_1 PhysicalReg_EBX
    177 //! LOWER bytecode CONST_CLASS
    178 
    179 //! It calls class_resolve (%ebx is live across the call)
    180 //! Since the register allocator does not handle control flow within the lowered native sequence,
    181 //!   we define an interface between the lowering module and register allocator:
    182 //!     rememberState, gotoState, transferToState
    183 //!   to make sure at the control flow merge point the state of registers is the same
    184 int op_const_class() {
    185     u2 vA = INST_AA(inst);
    186     u4 tmp = (u4)FETCH(1);
    187     /* for trace-based JIT, the class is already resolved since this code has been executed */
    188     void *classPtr = (void*)
    189        (currentMethod->clazz->pDvmDex->pResClasses[tmp]);
    190     assert(classPtr != NULL);
    191     set_VR_to_imm(vA, OpndSize_32, (int) classPtr );
    192     rPC += 2;
    193     return 0;
    194 }
    195 
    196 #undef P_GPR_1
    197 
    198