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