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