blob: 23c3fe7e2faab2578efa1f5d0f7460d91700098c [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2011 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#include "object_utils.h"
18
Brian Carlstrom641ce032013-01-31 15:21:37 -080019#include "compiler/compiler_internals.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080020#include "local_optimizations.h"
buzbee1bc37c62012-11-20 13:35:41 -080021#include "codegen_util.h"
22#include "ralloc_util.h"
buzbeeeaf09bc2012-11-15 14:51:41 -080023
buzbeee3acd072012-02-25 17:03:10 -080024namespace art {
25
buzbeee3acd072012-02-25 17:03:10 -080026/*
27 * Target-independent code generation. Use only high-level
28 * load/store utilities here, or target-dependent genXX() handlers
29 * when necessary.
30 */
buzbeea5954be2013-02-07 10:41:40 -080031static void CompileDalvikInstruction(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
buzbeefa57c472012-11-21 12:06:18 -080032 LIR* label_list)
buzbeee3acd072012-02-25 17:03:10 -080033{
buzbee02031b12012-11-23 09:41:35 -080034 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -080035 RegLocation rl_src[3];
buzbee02031b12012-11-23 09:41:35 -080036 RegLocation rl_dest = GetBadLoc();
37 RegLocation rl_result = GetBadLoc();
Bill Buzbeea114add2012-05-03 15:00:40 -070038 Instruction::Code opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -080039 int opt_flags = mir->optimization_flags;
buzbee408ad162012-06-06 16:45:18 -070040 uint32_t vB = mir->dalvikInsn.vB;
41 uint32_t vC = mir->dalvikInsn.vC;
buzbeee3acd072012-02-25 17:03:10 -080042
buzbee02031b12012-11-23 09:41:35 -080043 // Prep Src and Dest locations.
buzbeefa57c472012-11-21 12:06:18 -080044 int next_sreg = 0;
45 int next_loc = 0;
46 int attrs = oat_data_flow_attributes[opcode];
buzbee02031b12012-11-23 09:41:35 -080047 rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
Bill Buzbeea114add2012-05-03 15:00:40 -070048 if (attrs & DF_UA) {
buzbeebff24652012-05-06 16:22:05 -070049 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080050 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
51 next_sreg+= 2;
buzbeebff24652012-05-06 16:22:05 -070052 } else {
buzbeefa57c472012-11-21 12:06:18 -080053 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
54 next_sreg++;
buzbeebff24652012-05-06 16:22:05 -070055 }
Bill Buzbeea114add2012-05-03 15:00:40 -070056 }
57 if (attrs & DF_UB) {
buzbeebff24652012-05-06 16:22:05 -070058 if (attrs & DF_B_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080059 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
60 next_sreg+= 2;
buzbeebff24652012-05-06 16:22:05 -070061 } else {
buzbeefa57c472012-11-21 12:06:18 -080062 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
63 next_sreg++;
buzbeebff24652012-05-06 16:22:05 -070064 }
Bill Buzbeea114add2012-05-03 15:00:40 -070065 }
66 if (attrs & DF_UC) {
buzbeebff24652012-05-06 16:22:05 -070067 if (attrs & DF_C_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080068 rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
buzbeebff24652012-05-06 16:22:05 -070069 } else {
buzbeefa57c472012-11-21 12:06:18 -080070 rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
buzbeebff24652012-05-06 16:22:05 -070071 }
Bill Buzbeea114add2012-05-03 15:00:40 -070072 }
73 if (attrs & DF_DA) {
buzbeebff24652012-05-06 16:22:05 -070074 if (attrs & DF_A_WIDE) {
buzbeefa57c472012-11-21 12:06:18 -080075 rl_dest = GetDestWide(cu, mir);
buzbeebff24652012-05-06 16:22:05 -070076 } else {
buzbeefa57c472012-11-21 12:06:18 -080077 rl_dest = GetDest(cu, mir);
buzbeebff24652012-05-06 16:22:05 -070078 }
Bill Buzbeea114add2012-05-03 15:00:40 -070079 }
Bill Buzbeea114add2012-05-03 15:00:40 -070080 switch (opcode) {
81 case Instruction::NOP:
82 break;
buzbeee3acd072012-02-25 17:03:10 -080083
Ian Rogers474b6da2012-09-25 00:20:38 -070084 case Instruction::MOVE_EXCEPTION:
buzbee02031b12012-11-23 09:41:35 -080085 cg->GenMoveException(cu, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -070086 break;
jeffhao1eab9582013-01-22 13:33:52 -080087
Bill Buzbeea114add2012-05-03 15:00:40 -070088 case Instruction::RETURN_VOID:
Ian Rogersfffdb022013-01-04 15:14:08 -080089 if (((cu->access_flags & kAccConstructor) != 0) &&
90 cu->compiler->RequiresConstructorBarrier(Thread::Current(), cu->dex_file,
91 cu->class_def_idx)) {
92 cg->GenMemBarrier(cu, kStoreStore);
93 }
buzbeefa57c472012-11-21 12:06:18 -080094 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -080095 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -070096 }
97 break;
98
99 case Instruction::RETURN:
100 case Instruction::RETURN_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800101 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800102 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700103 }
buzbee02031b12012-11-23 09:41:35 -0800104 cg->StoreValue(cu, GetReturn(cu, cu->shorty[0] == 'F'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 break;
106
107 case Instruction::RETURN_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800108 if (!(cu->attrs & METHOD_IS_LEAF)) {
buzbee02031b12012-11-23 09:41:35 -0800109 cg->GenSuspendTest(cu, opt_flags);
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 }
buzbee02031b12012-11-23 09:41:35 -0800111 cg->StoreValueWide(cu, GetReturnWide(cu,
buzbeefa57c472012-11-21 12:06:18 -0800112 cu->shorty[0] == 'D'), rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700113 break;
114
115 case Instruction::MOVE_RESULT_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800116 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800117 break; // Nop - combined w/ previous invoke.
118 cg->StoreValueWide(cu, rl_dest, GetReturnWide(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700119 break;
120
121 case Instruction::MOVE_RESULT:
122 case Instruction::MOVE_RESULT_OBJECT:
buzbeefa57c472012-11-21 12:06:18 -0800123 if (opt_flags & MIR_INLINED)
buzbee02031b12012-11-23 09:41:35 -0800124 break; // Nop - combined w/ previous invoke.
125 cg->StoreValue(cu, rl_dest, GetReturn(cu, rl_dest.fp));
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 break;
127
128 case Instruction::MOVE:
129 case Instruction::MOVE_OBJECT:
130 case Instruction::MOVE_16:
131 case Instruction::MOVE_OBJECT_16:
132 case Instruction::MOVE_FROM16:
133 case Instruction::MOVE_OBJECT_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800134 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700135 break;
136
137 case Instruction::MOVE_WIDE:
138 case Instruction::MOVE_WIDE_16:
139 case Instruction::MOVE_WIDE_FROM16:
buzbee02031b12012-11-23 09:41:35 -0800140 cg->StoreValueWide(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700141 break;
142
143 case Instruction::CONST:
144 case Instruction::CONST_4:
145 case Instruction::CONST_16:
buzbeefa57c472012-11-21 12:06:18 -0800146 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800147 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB);
148 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800149 if (vB == 0) {
150 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
151 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700152 break;
153
154 case Instruction::CONST_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800155 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee02031b12012-11-23 09:41:35 -0800156 cg->LoadConstantNoClobber(cu, rl_result.low_reg, vB << 16);
157 cg->StoreValue(cu, rl_dest, rl_result);
buzbee7da142f2012-11-29 16:33:42 -0800158 if (vB == 0) {
159 cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
160 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700161 break;
162
163 case Instruction::CONST_WIDE_16:
164 case Instruction::CONST_WIDE_32:
buzbeefa57c472012-11-21 12:06:18 -0800165 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800166 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg,
167 static_cast<int64_t>(static_cast<int32_t>(vB)));
buzbee02031b12012-11-23 09:41:35 -0800168 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700169 break;
170
171 case Instruction::CONST_WIDE:
buzbeefa57c472012-11-21 12:06:18 -0800172 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800173 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg, mir->dalvikInsn.vB_wide);
buzbee02031b12012-11-23 09:41:35 -0800174 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700175 break;
176
177 case Instruction::CONST_WIDE_HIGH16:
buzbeefa57c472012-11-21 12:06:18 -0800178 rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
buzbee4ef3e452012-12-14 13:35:28 -0800179 cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg,
180 static_cast<int64_t>(vB) << 48);
buzbee02031b12012-11-23 09:41:35 -0800181 cg->StoreValueWide(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700182 break;
183
184 case Instruction::MONITOR_ENTER:
buzbee02031b12012-11-23 09:41:35 -0800185 cg->GenMonitorEnter(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700186 break;
187
188 case Instruction::MONITOR_EXIT:
buzbee02031b12012-11-23 09:41:35 -0800189 cg->GenMonitorExit(cu, opt_flags, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700190 break;
191
192 case Instruction::CHECK_CAST:
buzbee02031b12012-11-23 09:41:35 -0800193 cg->GenCheckCast(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700194 break;
195
196 case Instruction::INSTANCE_OF:
buzbee02031b12012-11-23 09:41:35 -0800197 cg->GenInstanceof(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700198 break;
199
200 case Instruction::NEW_INSTANCE:
buzbee02031b12012-11-23 09:41:35 -0800201 cg->GenNewInstance(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700202 break;
203
204 case Instruction::THROW:
buzbee02031b12012-11-23 09:41:35 -0800205 cg->GenThrow(cu, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700206 break;
207
Bill Buzbeea114add2012-05-03 15:00:40 -0700208 case Instruction::ARRAY_LENGTH:
buzbeefa57c472012-11-21 12:06:18 -0800209 int len_offset;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800210 len_offset = mirror::Array::LengthOffset().Int32Value();
buzbee02031b12012-11-23 09:41:35 -0800211 rl_src[0] = cg->LoadValue(cu, rl_src[0], kCoreReg);
212 cg->GenNullCheck(cu, rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
buzbeefa57c472012-11-21 12:06:18 -0800213 rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
buzbee02031b12012-11-23 09:41:35 -0800214 cg->LoadWordDisp(cu, rl_src[0].low_reg, len_offset, rl_result.low_reg);
215 cg->StoreValue(cu, rl_dest, rl_result);
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 break;
217
218 case Instruction::CONST_STRING:
219 case Instruction::CONST_STRING_JUMBO:
buzbee02031b12012-11-23 09:41:35 -0800220 cg->GenConstString(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700221 break;
222
223 case Instruction::CONST_CLASS:
buzbee02031b12012-11-23 09:41:35 -0800224 cg->GenConstClass(cu, vB, rl_dest);
Bill Buzbeea114add2012-05-03 15:00:40 -0700225 break;
226
227 case Instruction::FILL_ARRAY_DATA:
buzbee02031b12012-11-23 09:41:35 -0800228 cg->GenFillArrayData(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700229 break;
230
231 case Instruction::FILLED_NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800232 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700233 false /* not range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700234 break;
235
236 case Instruction::FILLED_NEW_ARRAY_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800237 cg->GenFilledNewArray(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic,
buzbee3b3dbdd2012-06-13 13:39:34 -0700238 true /* range */));
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 break;
240
241 case Instruction::NEW_ARRAY:
buzbee02031b12012-11-23 09:41:35 -0800242 cg->GenNewArray(cu, vC, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 break;
244
245 case Instruction::GOTO:
246 case Instruction::GOTO_16:
247 case Instruction::GOTO_32:
buzbeefa57c472012-11-21 12:06:18 -0800248 if (bb->taken->start_offset <= mir->offset) {
buzbee02031b12012-11-23 09:41:35 -0800249 cg->GenSuspendTestAndBranch(cu, opt_flags, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700250 } else {
buzbee02031b12012-11-23 09:41:35 -0800251 cg->OpUnconditionalBranch(cu, &label_list[bb->taken->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 }
253 break;
254
255 case Instruction::PACKED_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800256 cg->GenPackedSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700257 break;
258
259 case Instruction::SPARSE_SWITCH:
buzbee02031b12012-11-23 09:41:35 -0800260 cg->GenSparseSwitch(cu, vB, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 break;
262
263 case Instruction::CMPL_FLOAT:
264 case Instruction::CMPG_FLOAT:
265 case Instruction::CMPL_DOUBLE:
266 case Instruction::CMPG_DOUBLE:
buzbeea5954be2013-02-07 10:41:40 -0800267 cg->GenCmpFP(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 break;
269
270 case Instruction::CMP_LONG:
buzbee02031b12012-11-23 09:41:35 -0800271 cg->GenCmpLong(cu, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700272 break;
273
274 case Instruction::IF_EQ:
275 case Instruction::IF_NE:
276 case Instruction::IF_LT:
277 case Instruction::IF_GE:
278 case Instruction::IF_GT:
279 case Instruction::IF_LE: {
buzbeefa57c472012-11-21 12:06:18 -0800280 LIR* taken = &label_list[bb->taken->id];
281 LIR* fall_through = &label_list[bb->fall_through->id];
282 bool backward_branch;
283 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800284 // Result known at compile time?
285 if (rl_src[0].is_const && rl_src[1].is_const) {
286 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg],
287 cu->constant_values[rl_src[1].orig_sreg]);
288 if (is_taken && backward_branch) {
289 cg->GenSuspendTest(cu, opt_flags);
290 }
291 int id = is_taken ? bb->taken->id : bb->fall_through->id;
292 cg->OpUnconditionalBranch(cu, &label_list[id]);
293 } else {
294 if (backward_branch) {
295 cg->GenSuspendTest(cu, opt_flags);
296 }
297 cg->GenCompareAndBranch(cu, opcode, rl_src[0], rl_src[1], taken,
298 fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 break;
301 }
302
303 case Instruction::IF_EQZ:
304 case Instruction::IF_NEZ:
305 case Instruction::IF_LTZ:
306 case Instruction::IF_GEZ:
307 case Instruction::IF_GTZ:
308 case Instruction::IF_LEZ: {
buzbeefa57c472012-11-21 12:06:18 -0800309 LIR* taken = &label_list[bb->taken->id];
310 LIR* fall_through = &label_list[bb->fall_through->id];
311 bool backward_branch;
312 backward_branch = (bb->taken->start_offset <= mir->offset);
buzbeee6285f92012-12-06 15:57:46 -0800313 // Result known at compile time?
314 if (rl_src[0].is_const) {
315 bool is_taken = EvaluateBranch(opcode, cu->constant_values[rl_src[0].orig_sreg], 0);
316 if (is_taken && backward_branch) {
317 cg->GenSuspendTest(cu, opt_flags);
318 }
319 int id = is_taken ? bb->taken->id : bb->fall_through->id;
320 cg->OpUnconditionalBranch(cu, &label_list[id]);
321 } else {
322 if (backward_branch) {
323 cg->GenSuspendTest(cu, opt_flags);
324 }
325 cg->GenCompareZeroAndBranch(cu, opcode, rl_src[0], taken, fall_through);
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 break;
328 }
329
330 case Instruction::AGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800331 cg->GenArrayGet(cu, opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700332 break;
333 case Instruction::AGET:
334 case Instruction::AGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800335 cg->GenArrayGet(cu, opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700336 break;
337 case Instruction::AGET_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800338 cg->GenArrayGet(cu, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700339 break;
340 case Instruction::AGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800341 cg->GenArrayGet(cu, opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700342 break;
343 case Instruction::AGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800344 cg->GenArrayGet(cu, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700345 break;
346 case Instruction::AGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800347 cg->GenArrayGet(cu, opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 break;
349 case Instruction::APUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800350 cg->GenArrayPut(cu, opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
Bill Buzbeea114add2012-05-03 15:00:40 -0700351 break;
352 case Instruction::APUT:
buzbee02031b12012-11-23 09:41:35 -0800353 cg->GenArrayPut(cu, opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700354 break;
355 case Instruction::APUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800356 cg->GenArrayObjPut(cu, opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 break;
358 case Instruction::APUT_SHORT:
359 case Instruction::APUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800360 cg->GenArrayPut(cu, opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
Bill Buzbeea114add2012-05-03 15:00:40 -0700361 break;
362 case Instruction::APUT_BYTE:
363 case Instruction::APUT_BOOLEAN:
buzbee02031b12012-11-23 09:41:35 -0800364 cg->GenArrayPut(cu, opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
buzbeefa57c472012-11-21 12:06:18 -0800365 rl_src[0], 0);
Bill Buzbeea114add2012-05-03 15:00:40 -0700366 break;
367
368 case Instruction::IGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800369 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700370 break;
371
372 case Instruction::IGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800373 cg->GenIGet(cu, vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 break;
375
376 case Instruction::IGET:
buzbee02031b12012-11-23 09:41:35 -0800377 cg->GenIGet(cu, vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700378 break;
379
380 case Instruction::IGET_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800381 cg->GenIGet(cu, vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700382 break;
383
384 case Instruction::IGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800385 cg->GenIGet(cu, vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700386 break;
387
388 case Instruction::IGET_BOOLEAN:
389 case Instruction::IGET_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800390 cg->GenIGet(cu, vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 break;
392
393 case Instruction::IPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800394 cg->GenIPut(cu, vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700395 break;
396
397 case Instruction::IPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800398 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700399 break;
400
401 case Instruction::IPUT:
buzbee02031b12012-11-23 09:41:35 -0800402 cg->GenIPut(cu, vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 break;
404
405 case Instruction::IPUT_BOOLEAN:
406 case Instruction::IPUT_BYTE:
buzbee02031b12012-11-23 09:41:35 -0800407 cg->GenIPut(cu, vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 break;
409
410 case Instruction::IPUT_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800411 cg->GenIPut(cu, vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700412 break;
413
414 case Instruction::IPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800415 cg->GenIPut(cu, vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 break;
417
418 case Instruction::SGET_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800419 cg->GenSget(cu, vB, rl_dest, false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700420 break;
421 case Instruction::SGET:
422 case Instruction::SGET_BOOLEAN:
423 case Instruction::SGET_BYTE:
424 case Instruction::SGET_CHAR:
425 case Instruction::SGET_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800426 cg->GenSget(cu, vB, rl_dest, false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700427 break;
428
429 case Instruction::SGET_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800430 cg->GenSget(cu, vB, rl_dest, true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 break;
432
433 case Instruction::SPUT_OBJECT:
buzbee02031b12012-11-23 09:41:35 -0800434 cg->GenSput(cu, vB, rl_src[0], false, true);
Bill Buzbeea114add2012-05-03 15:00:40 -0700435 break;
436
437 case Instruction::SPUT:
438 case Instruction::SPUT_BOOLEAN:
439 case Instruction::SPUT_BYTE:
440 case Instruction::SPUT_CHAR:
441 case Instruction::SPUT_SHORT:
buzbee02031b12012-11-23 09:41:35 -0800442 cg->GenSput(cu, vB, rl_src[0], false, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 break;
444
445 case Instruction::SPUT_WIDE:
buzbee02031b12012-11-23 09:41:35 -0800446 cg->GenSput(cu, vB, rl_src[0], true, false);
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 break;
448
449 case Instruction::INVOKE_STATIC_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800450 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 break;
452 case Instruction::INVOKE_STATIC:
buzbee02031b12012-11-23 09:41:35 -0800453 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kStatic, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700454 break;
455
456 case Instruction::INVOKE_DIRECT:
buzbee02031b12012-11-23 09:41:35 -0800457 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700458 break;
459 case Instruction::INVOKE_DIRECT_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800460 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kDirect, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700461 break;
462
463 case Instruction::INVOKE_VIRTUAL:
buzbee02031b12012-11-23 09:41:35 -0800464 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 break;
466 case Instruction::INVOKE_VIRTUAL_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800467 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kVirtual, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 break;
469
470 case Instruction::INVOKE_SUPER:
buzbee02031b12012-11-23 09:41:35 -0800471 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 break;
473 case Instruction::INVOKE_SUPER_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800474 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kSuper, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 break;
476
477 case Instruction::INVOKE_INTERFACE:
buzbee02031b12012-11-23 09:41:35 -0800478 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, false));
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 break;
480 case Instruction::INVOKE_INTERFACE_RANGE:
buzbee02031b12012-11-23 09:41:35 -0800481 cg->GenInvoke(cu, cg->NewMemCallInfo(cu, bb, mir, kInterface, true));
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 break;
483
484 case Instruction::NEG_INT:
485 case Instruction::NOT_INT:
buzbeea5954be2013-02-07 10:41:40 -0800486 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700487 break;
488
489 case Instruction::NEG_LONG:
490 case Instruction::NOT_LONG:
buzbeea5954be2013-02-07 10:41:40 -0800491 cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 break;
493
494 case Instruction::NEG_FLOAT:
buzbeea5954be2013-02-07 10:41:40 -0800495 cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 break;
497
498 case Instruction::NEG_DOUBLE:
buzbeea5954be2013-02-07 10:41:40 -0800499 cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 break;
501
502 case Instruction::INT_TO_LONG:
buzbee02031b12012-11-23 09:41:35 -0800503 cg->GenIntToLong(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 break;
505
506 case Instruction::LONG_TO_INT:
buzbeefa57c472012-11-21 12:06:18 -0800507 rl_src[0] = UpdateLocWide(cu, rl_src[0]);
508 rl_src[0] = WideToNarrow(cu, rl_src[0]);
buzbee02031b12012-11-23 09:41:35 -0800509 cg->StoreValue(cu, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700510 break;
511
512 case Instruction::INT_TO_BYTE:
513 case Instruction::INT_TO_SHORT:
514 case Instruction::INT_TO_CHAR:
buzbee02031b12012-11-23 09:41:35 -0800515 cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700516 break;
517
518 case Instruction::INT_TO_FLOAT:
519 case Instruction::INT_TO_DOUBLE:
520 case Instruction::LONG_TO_FLOAT:
521 case Instruction::LONG_TO_DOUBLE:
522 case Instruction::FLOAT_TO_INT:
523 case Instruction::FLOAT_TO_LONG:
524 case Instruction::FLOAT_TO_DOUBLE:
525 case Instruction::DOUBLE_TO_INT:
526 case Instruction::DOUBLE_TO_LONG:
527 case Instruction::DOUBLE_TO_FLOAT:
buzbee02031b12012-11-23 09:41:35 -0800528 cg->GenConversion(cu, opcode, rl_dest, rl_src[0]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700529 break;
530
buzbeee6285f92012-12-06 15:57:46 -0800531
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 case Instruction::ADD_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700533 case Instruction::ADD_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800534 case Instruction::MUL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700535 case Instruction::MUL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800536 case Instruction::AND_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 case Instruction::AND_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800538 case Instruction::OR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 case Instruction::OR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800540 case Instruction::XOR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 case Instruction::XOR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800542 if (rl_src[0].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800543 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[0]))) {
buzbeee6285f92012-12-06 15:57:46 -0800544 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[1],
545 cu->constant_values[rl_src[0].orig_sreg]);
546 } else if (rl_src[1].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800547 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[1]))) {
buzbeee6285f92012-12-06 15:57:46 -0800548 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0],
549 cu->constant_values[rl_src[1].orig_sreg]);
550 } else {
551 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
552 }
553 break;
554
555 case Instruction::SUB_INT:
556 case Instruction::SUB_INT_2ADDR:
557 case Instruction::DIV_INT:
558 case Instruction::DIV_INT_2ADDR:
559 case Instruction::REM_INT:
560 case Instruction::REM_INT_2ADDR:
561 case Instruction::SHL_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 case Instruction::SHL_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800563 case Instruction::SHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 case Instruction::SHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800565 case Instruction::USHR_INT:
Bill Buzbeea114add2012-05-03 15:00:40 -0700566 case Instruction::USHR_INT_2ADDR:
buzbeee6285f92012-12-06 15:57:46 -0800567 if (rl_src[1].is_const &&
buzbee4ef3e452012-12-14 13:35:28 -0800568 cu->cg->InexpensiveConstantInt(ConstantValue(cu, rl_src[1]))) {
569 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], ConstantValue(cu, rl_src[1]));
buzbeee6285f92012-12-06 15:57:46 -0800570 } else {
571 cg->GenArithOpInt(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
572 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700573 break;
574
575 case Instruction::ADD_LONG:
576 case Instruction::SUB_LONG:
Bill Buzbeea114add2012-05-03 15:00:40 -0700577 case Instruction::AND_LONG:
578 case Instruction::OR_LONG:
579 case Instruction::XOR_LONG:
580 case Instruction::ADD_LONG_2ADDR:
581 case Instruction::SUB_LONG_2ADDR:
Bill Buzbeea114add2012-05-03 15:00:40 -0700582 case Instruction::AND_LONG_2ADDR:
583 case Instruction::OR_LONG_2ADDR:
584 case Instruction::XOR_LONG_2ADDR:
buzbee4ef3e452012-12-14 13:35:28 -0800585 if (rl_src[0].is_const || rl_src[1].is_const) {
586 cg->GenArithImmOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
587 break;
588 }
589 // Note: intentional fallthrough.
590
591 case Instruction::MUL_LONG:
592 case Instruction::DIV_LONG:
593 case Instruction::REM_LONG:
594 case Instruction::MUL_LONG_2ADDR:
595 case Instruction::DIV_LONG_2ADDR:
596 case Instruction::REM_LONG_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800597 cg->GenArithOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700598 break;
599
600 case Instruction::SHL_LONG:
601 case Instruction::SHR_LONG:
602 case Instruction::USHR_LONG:
603 case Instruction::SHL_LONG_2ADDR:
604 case Instruction::SHR_LONG_2ADDR:
605 case Instruction::USHR_LONG_2ADDR:
buzbee4ef3e452012-12-14 13:35:28 -0800606 if (rl_src[1].is_const) {
607 cg->GenShiftImmOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
608 } else {
609 cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
610 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700611 break;
612
613 case Instruction::ADD_FLOAT:
614 case Instruction::SUB_FLOAT:
615 case Instruction::MUL_FLOAT:
616 case Instruction::DIV_FLOAT:
617 case Instruction::REM_FLOAT:
618 case Instruction::ADD_FLOAT_2ADDR:
619 case Instruction::SUB_FLOAT_2ADDR:
620 case Instruction::MUL_FLOAT_2ADDR:
621 case Instruction::DIV_FLOAT_2ADDR:
622 case Instruction::REM_FLOAT_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800623 cg->GenArithOpFloat(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700624 break;
625
626 case Instruction::ADD_DOUBLE:
627 case Instruction::SUB_DOUBLE:
628 case Instruction::MUL_DOUBLE:
629 case Instruction::DIV_DOUBLE:
630 case Instruction::REM_DOUBLE:
631 case Instruction::ADD_DOUBLE_2ADDR:
632 case Instruction::SUB_DOUBLE_2ADDR:
633 case Instruction::MUL_DOUBLE_2ADDR:
634 case Instruction::DIV_DOUBLE_2ADDR:
635 case Instruction::REM_DOUBLE_2ADDR:
buzbee02031b12012-11-23 09:41:35 -0800636 cg->GenArithOpDouble(cu, opcode, rl_dest, rl_src[0], rl_src[1]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 break;
638
639 case Instruction::RSUB_INT:
640 case Instruction::ADD_INT_LIT16:
641 case Instruction::MUL_INT_LIT16:
642 case Instruction::DIV_INT_LIT16:
643 case Instruction::REM_INT_LIT16:
644 case Instruction::AND_INT_LIT16:
645 case Instruction::OR_INT_LIT16:
646 case Instruction::XOR_INT_LIT16:
647 case Instruction::ADD_INT_LIT8:
648 case Instruction::RSUB_INT_LIT8:
649 case Instruction::MUL_INT_LIT8:
650 case Instruction::DIV_INT_LIT8:
651 case Instruction::REM_INT_LIT8:
652 case Instruction::AND_INT_LIT8:
653 case Instruction::OR_INT_LIT8:
654 case Instruction::XOR_INT_LIT8:
655 case Instruction::SHL_INT_LIT8:
656 case Instruction::SHR_INT_LIT8:
657 case Instruction::USHR_INT_LIT8:
buzbee02031b12012-11-23 09:41:35 -0800658 cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src[0], vC);
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 break;
660
661 default:
buzbeea5954be2013-02-07 10:41:40 -0800662 LOG(FATAL) << "Unexpected opcode: " << opcode;
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 }
buzbeee3acd072012-02-25 17:03:10 -0800664}
665
buzbeea169e1d2012-12-05 14:26:44 -0800666// Process extended MIR instructions
buzbeefa57c472012-11-21 12:06:18 -0800667static void HandleExtendedMethodMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir)
buzbeee3acd072012-02-25 17:03:10 -0800668{
buzbee02031b12012-11-23 09:41:35 -0800669 Codegen* cg = cu->cg.get();
buzbeecbd6d442012-11-17 14:11:25 -0800670 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 case kMirOpCopy: {
buzbeefa57c472012-11-21 12:06:18 -0800672 RegLocation rl_src = GetSrc(cu, mir, 0);
673 RegLocation rl_dest = GetDest(cu, mir);
buzbee02031b12012-11-23 09:41:35 -0800674 cg->StoreValue(cu, rl_dest, rl_src);
Bill Buzbeea114add2012-05-03 15:00:40 -0700675 break;
676 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 case kMirOpFusedCmplFloat:
buzbee02031b12012-11-23 09:41:35 -0800678 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 break;
680 case kMirOpFusedCmpgFloat:
buzbee02031b12012-11-23 09:41:35 -0800681 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, false /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700682 break;
683 case kMirOpFusedCmplDouble:
buzbee02031b12012-11-23 09:41:35 -0800684 cg->GenFusedFPCmpBranch(cu, bb, mir, false /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700685 break;
686 case kMirOpFusedCmpgDouble:
buzbee02031b12012-11-23 09:41:35 -0800687 cg->GenFusedFPCmpBranch(cu, bb, mir, true /*gt bias*/, true /*double*/);
Bill Buzbeea114add2012-05-03 15:00:40 -0700688 break;
689 case kMirOpFusedCmpLong:
buzbee02031b12012-11-23 09:41:35 -0800690 cg->GenFusedLongCmpBranch(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700691 break;
Bill Buzbeea114add2012-05-03 15:00:40 -0700692 default:
693 break;
694 }
buzbeee3acd072012-02-25 17:03:10 -0800695}
696
buzbee02031b12012-11-23 09:41:35 -0800697// Handle the content in each basic block.
buzbeefa57c472012-11-21 12:06:18 -0800698static bool MethodBlockCodeGen(CompilationUnit* cu, BasicBlock* bb)
buzbeee3acd072012-02-25 17:03:10 -0800699{
buzbeefa57c472012-11-21 12:06:18 -0800700 if (bb->block_type == kDead) return false;
buzbee02031b12012-11-23 09:41:35 -0800701 Codegen* cg = cu->cg.get();
buzbeefa57c472012-11-21 12:06:18 -0800702 cu->current_dalvik_offset = bb->start_offset;
Bill Buzbeea114add2012-05-03 15:00:40 -0700703 MIR* mir;
buzbeefa57c472012-11-21 12:06:18 -0800704 LIR* label_list = cu->block_label_list;
705 int block_id = bb->id;
buzbeee3acd072012-02-25 17:03:10 -0800706
buzbeefa57c472012-11-21 12:06:18 -0800707 cu->cur_block = bb;
708 label_list[block_id].operands[0] = bb->start_offset;
buzbeee3acd072012-02-25 17:03:10 -0800709
buzbee02031b12012-11-23 09:41:35 -0800710 // Insert the block label.
buzbeefa57c472012-11-21 12:06:18 -0800711 label_list[block_id].opcode = kPseudoNormalBlockLabel;
712 AppendLIR(cu, &label_list[block_id]);
buzbeee3acd072012-02-25 17:03:10 -0800713
buzbeefa57c472012-11-21 12:06:18 -0800714 LIR* head_lir = NULL;
buzbee8320f382012-09-11 16:29:42 -0700715
buzbee02031b12012-11-23 09:41:35 -0800716 // If this is a catch block, export the start address.
buzbeefa57c472012-11-21 12:06:18 -0800717 if (bb->catch_entry) {
718 head_lir = NewLIR0(cu, kPseudoExportedPC);
buzbee8320f382012-09-11 16:29:42 -0700719 }
720
buzbee02031b12012-11-23 09:41:35 -0800721 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800722 ResetRegPool(cu);
723 ResetDefTracking(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700724
buzbeefa57c472012-11-21 12:06:18 -0800725 ClobberAllRegs(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700726
buzbeefa57c472012-11-21 12:06:18 -0800727 if (bb->block_type == kEntryBlock) {
728 int start_vreg = cu->num_dalvik_registers - cu->num_ins;
buzbee02031b12012-11-23 09:41:35 -0800729 cg->GenEntrySequence(cu, &cu->reg_location[start_vreg],
730 cu->reg_location[cu->method_sreg]);
buzbeefa57c472012-11-21 12:06:18 -0800731 } else if (bb->block_type == kExitBlock) {
buzbee02031b12012-11-23 09:41:35 -0800732 cg->GenExitSequence(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700733 }
734
buzbee28c9a832012-11-21 15:39:13 -0800735 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
buzbeefa57c472012-11-21 12:06:18 -0800736 ResetRegPool(cu);
737 if (cu->disable_opt & (1 << kTrackLiveTemps)) {
738 ClobberAllRegs(cu);
buzbeee1965672012-03-11 18:39:19 -0700739 }
740
buzbeefa57c472012-11-21 12:06:18 -0800741 if (cu->disable_opt & (1 << kSuppressLoads)) {
742 ResetDefTracking(cu);
buzbeee3acd072012-02-25 17:03:10 -0800743 }
744
buzbee3d661942012-03-14 17:37:27 -0700745#ifndef NDEBUG
buzbee02031b12012-11-23 09:41:35 -0800746 // Reset temp tracking sanity check.
buzbeefa57c472012-11-21 12:06:18 -0800747 cu->live_sreg = INVALID_SREG;
buzbee3d661942012-03-14 17:37:27 -0700748#endif
749
buzbeefa57c472012-11-21 12:06:18 -0800750 cu->current_dalvik_offset = mir->offset;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700751 int opcode = mir->dalvikInsn.opcode;
buzbeefa57c472012-11-21 12:06:18 -0800752 LIR* boundary_lir;
buzbeee3acd072012-02-25 17:03:10 -0800753
buzbee02031b12012-11-23 09:41:35 -0800754 // Mark the beginning of a Dalvik instruction for line tracking.
buzbeefa57c472012-11-21 12:06:18 -0800755 char* inst_str = cu->verbose ?
buzbeea169e1d2012-12-05 14:26:44 -0800756 GetDalvikDisassembly(cu, mir) : NULL;
buzbeefa57c472012-11-21 12:06:18 -0800757 boundary_lir = MarkBoundary(cu, mir->offset, inst_str);
buzbee02031b12012-11-23 09:41:35 -0800758 // Remember the first LIR for this block.
buzbeefa57c472012-11-21 12:06:18 -0800759 if (head_lir == NULL) {
760 head_lir = boundary_lir;
buzbee02031b12012-11-23 09:41:35 -0800761 // Set the first boundary_lir as a scheduling barrier.
buzbeefa57c472012-11-21 12:06:18 -0800762 head_lir->def_mask = ENCODE_ALL;
buzbeee3acd072012-02-25 17:03:10 -0800763 }
764
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700765 if (opcode == kMirOpCheck) {
766 // Combine check and work halves of throwing instruction.
buzbeefa57c472012-11-21 12:06:18 -0800767 MIR* work_half = mir->meta.throw_insn;
768 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
769 opcode = work_half->dalvikInsn.opcode;
770 SSARepresentation* ssa_rep = work_half->ssa_rep;
771 work_half->ssa_rep = mir->ssa_rep;
772 mir->ssa_rep = ssa_rep;
buzbeea169e1d2012-12-05 14:26:44 -0800773 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700774 }
775
776 if (opcode >= kMirOpFirst) {
buzbeefa57c472012-11-21 12:06:18 -0800777 HandleExtendedMethodMIR(cu, bb, mir);
Bill Buzbeea114add2012-05-03 15:00:40 -0700778 continue;
779 }
780
buzbeea5954be2013-02-07 10:41:40 -0800781 CompileDalvikInstruction(cu, mir, bb, label_list);
Bill Buzbeea114add2012-05-03 15:00:40 -0700782 }
783
buzbeefa57c472012-11-21 12:06:18 -0800784 if (head_lir) {
buzbee02031b12012-11-23 09:41:35 -0800785 // Eliminate redundant loads/stores and delay stores into later slots.
buzbeefa57c472012-11-21 12:06:18 -0800786 ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
Bill Buzbeea114add2012-05-03 15:00:40 -0700787
buzbee02031b12012-11-23 09:41:35 -0800788 // Generate an unconditional branch to the fallthrough block.
buzbeefa57c472012-11-21 12:06:18 -0800789 if (bb->fall_through) {
buzbee02031b12012-11-23 09:41:35 -0800790 cg->OpUnconditionalBranch(cu, &label_list[bb->fall_through->id]);
Bill Buzbeea114add2012-05-03 15:00:40 -0700791 }
792 }
793 return false;
buzbeee3acd072012-02-25 17:03:10 -0800794}
795
buzbeefa57c472012-11-21 12:06:18 -0800796void SpecialMIR2LIR(CompilationUnit* cu, SpecialCaseHandler special_case)
buzbee16da88c2012-03-20 10:38:17 -0700797{
buzbee02031b12012-11-23 09:41:35 -0800798 Codegen* cg = cu->cg.get();
799 // Find the first DalvikByteCode block.
buzbeefa57c472012-11-21 12:06:18 -0800800 int num_reachable_blocks = cu->num_reachable_blocks;
801 const GrowableList *block_list = &cu->block_list;
Bill Buzbeea114add2012-05-03 15:00:40 -0700802 BasicBlock*bb = NULL;
buzbeefa57c472012-11-21 12:06:18 -0800803 for (int idx = 0; idx < num_reachable_blocks; idx++) {
804 int dfs_index = cu->dfs_order.elem_list[idx];
805 bb = reinterpret_cast<BasicBlock*>(GrowableListGetElement(block_list, dfs_index));
806 if (bb->block_type == kDalvikByteCode) {
Bill Buzbeea114add2012-05-03 15:00:40 -0700807 break;
buzbee16da88c2012-03-20 10:38:17 -0700808 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700809 }
810 if (bb == NULL) {
811 return;
812 }
buzbeefa57c472012-11-21 12:06:18 -0800813 DCHECK_EQ(bb->start_offset, 0);
814 DCHECK(bb->first_mir_insn != NULL);
buzbee16da88c2012-03-20 10:38:17 -0700815
buzbee02031b12012-11-23 09:41:35 -0800816 // Get the first instruction.
buzbeefa57c472012-11-21 12:06:18 -0800817 MIR* mir = bb->first_mir_insn;
buzbee16da88c2012-03-20 10:38:17 -0700818
buzbee02031b12012-11-23 09:41:35 -0800819 // Free temp registers and reset redundant store tracking.
buzbeefa57c472012-11-21 12:06:18 -0800820 ResetRegPool(cu);
821 ResetDefTracking(cu);
822 ClobberAllRegs(cu);
buzbee16da88c2012-03-20 10:38:17 -0700823
buzbee02031b12012-11-23 09:41:35 -0800824 cg->GenSpecialCase(cu, bb, mir, special_case);
buzbee16da88c2012-03-20 10:38:17 -0700825}
826
buzbeefa57c472012-11-21 12:06:18 -0800827void MethodMIR2LIR(CompilationUnit* cu)
buzbeee3acd072012-02-25 17:03:10 -0800828{
buzbee02031b12012-11-23 09:41:35 -0800829 Codegen* cg = cu->cg.get();
830 // Hold the labels of each block.
buzbeefa57c472012-11-21 12:06:18 -0800831 cu->block_label_list =
832 static_cast<LIR*>(NewMem(cu, sizeof(LIR) * cu->num_blocks, true, kAllocLIR));
buzbeee3acd072012-02-25 17:03:10 -0800833
buzbeefa57c472012-11-21 12:06:18 -0800834 DataFlowAnalysisDispatcher(cu, MethodBlockCodeGen,
Bill Buzbeea114add2012-05-03 15:00:40 -0700835 kPreOrderDFSTraversal, false /* Iterative */);
Ian Rogersab2b55d2012-03-18 00:06:11 -0700836
buzbee02031b12012-11-23 09:41:35 -0800837 cg->HandleSuspendLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800838
buzbee02031b12012-11-23 09:41:35 -0800839 cg->HandleThrowLaunchPads(cu);
buzbeee3acd072012-02-25 17:03:10 -0800840
buzbee02031b12012-11-23 09:41:35 -0800841 cg->HandleIntrinsicLaunchPads(cu);
buzbeefc9e6fa2012-03-23 15:14:29 -0700842
buzbeefa57c472012-11-21 12:06:18 -0800843 if (!(cu->disable_opt & (1 << kSafeOptimizations))) {
844 RemoveRedundantBranches(cu);
Bill Buzbeea114add2012-05-03 15:00:40 -0700845 }
buzbeee3acd072012-02-25 17:03:10 -0800846}
847
buzbeee3acd072012-02-25 17:03:10 -0800848} // namespace art