• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
const_string_common_nohelper(u4 tmp,u2 vA)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 //!
const_string_common(u4 tmp,u2 vA)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 //!
op_const_4()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 //!
op_const_16()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 //!
op_const()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 //!
op_const_high16()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 //!
op_const_wide_16()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 //!
op_const_wide_32()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 //!
op_const_wide()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 //!
op_const_wide_high16()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 //!
op_const_string()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 //!
op_const_string_jumbo()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
op_const_class()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