blob: 28d53ad77b2f8e9af29e5032d3962fa6e8444bc9 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
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 "dex/compiler_internals.h"
18#include "dex/dataflow_iterator-inl.h"
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -080019#include "dex/quick/dex_file_method_inliner.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070020#include "mir_to_lir-inl.h"
21#include "object_utils.h"
Ian Rogers02ed4c02013-09-06 13:10:04 -070022#include "thread-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070023
24namespace art {
25
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -080026void Mir2Lir::LockArg(int in_position, bool wide) {
27 int reg_arg_low = GetArgMappingToPhysicalReg(in_position);
28 int reg_arg_high = wide ? GetArgMappingToPhysicalReg(in_position + 1) : INVALID_REG;
29
30 if (reg_arg_low != INVALID_REG) {
31 LockTemp(reg_arg_low);
32 }
33 if (reg_arg_high != INVALID_REG && reg_arg_low != reg_arg_high) {
34 LockTemp(reg_arg_high);
35 }
36}
37
38int Mir2Lir::LoadArg(int in_position, bool wide) {
39 int reg_arg_low = GetArgMappingToPhysicalReg(in_position);
40 int reg_arg_high = wide ? GetArgMappingToPhysicalReg(in_position + 1) : INVALID_REG;
41
42 int offset = StackVisitor::GetOutVROffset(in_position);
43 if (cu_->instruction_set == kX86) {
44 /*
45 * When doing a call for x86, it moves the stack pointer in order to push return.
46 * Thus, we add another 4 bytes to figure out the out of caller (in of callee).
47 * TODO: This needs revisited for 64-bit.
48 */
49 offset += sizeof(uint32_t);
50 }
51
52 // If the VR is wide and there is no register for high part, we need to load it.
53 if (wide && reg_arg_high == INVALID_REG) {
54 // If the low part is not in a reg, we allocate a pair. Otherwise, we just load to high reg.
55 if (reg_arg_low == INVALID_REG) {
Bill Buzbee86ec5202014-02-26 19:03:09 +000056 int new_regs = AllocTypedTempPair(false, kAnyReg);
57 DECODE_REG_PAIR(new_regs, reg_arg_low, reg_arg_high);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -080058 LoadBaseDispWide(TargetReg(kSp), offset, reg_arg_low, reg_arg_high, INVALID_SREG);
59 } else {
60 reg_arg_high = AllocTemp();
61 int offset_high = offset + sizeof(uint32_t);
62 LoadWordDisp(TargetReg(kSp), offset_high, reg_arg_high);
63 }
64 }
65
66 // If the low part is not in a register yet, we need to load it.
67 if (reg_arg_low == INVALID_REG) {
68 reg_arg_low = AllocTemp();
69 LoadWordDisp(TargetReg(kSp), offset, reg_arg_low);
70 }
71
72 if (wide) {
73 return ENCODE_REG_PAIR(reg_arg_low, reg_arg_high);
74 } else {
75 return reg_arg_low;
76 }
77}
78
79void Mir2Lir::LoadArgDirect(int in_position, RegLocation rl_dest) {
80 int offset = StackVisitor::GetOutVROffset(in_position);
81 if (cu_->instruction_set == kX86) {
82 /*
83 * When doing a call for x86, it moves the stack pointer in order to push return.
84 * Thus, we add another 4 bytes to figure out the out of caller (in of callee).
85 * TODO: This needs revisited for 64-bit.
86 */
87 offset += sizeof(uint32_t);
88 }
89
90 if (!rl_dest.wide) {
91 int reg = GetArgMappingToPhysicalReg(in_position);
92 if (reg != INVALID_REG) {
Bill Buzbee86ec5202014-02-26 19:03:09 +000093 OpRegCopy(rl_dest.low_reg, reg);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -080094 } else {
Bill Buzbee86ec5202014-02-26 19:03:09 +000095 LoadWordDisp(TargetReg(kSp), offset, rl_dest.low_reg);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -080096 }
97 } else {
98 int reg_arg_low = GetArgMappingToPhysicalReg(in_position);
99 int reg_arg_high = GetArgMappingToPhysicalReg(in_position + 1);
100
101 if (reg_arg_low != INVALID_REG && reg_arg_high != INVALID_REG) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000102 OpRegCopyWide(rl_dest.low_reg, rl_dest.high_reg, reg_arg_low, reg_arg_high);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800103 } else if (reg_arg_low != INVALID_REG && reg_arg_high == INVALID_REG) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000104 OpRegCopy(rl_dest.low_reg, reg_arg_low);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800105 int offset_high = offset + sizeof(uint32_t);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000106 LoadWordDisp(TargetReg(kSp), offset_high, rl_dest.high_reg);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800107 } else if (reg_arg_low == INVALID_REG && reg_arg_high != INVALID_REG) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000108 OpRegCopy(rl_dest.high_reg, reg_arg_high);
109 LoadWordDisp(TargetReg(kSp), offset, rl_dest.low_reg);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800110 } else {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000111 LoadBaseDispWide(TargetReg(kSp), offset, rl_dest.low_reg, rl_dest.high_reg, INVALID_SREG);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800112 }
113 }
114}
115
116bool Mir2Lir::GenSpecialIGet(MIR* mir, const InlineMethod& special) {
117 // FastInstance() already checked by DexFileMethodInliner.
118 const InlineIGetIPutData& data = special.d.ifield_data;
119 if (data.method_is_static || data.object_arg != 0) {
120 // The object is not "this" and has to be null-checked.
121 return false;
122 }
123
124 DCHECK_NE(data.op_size, kDouble); // The inliner doesn't distinguish kDouble, uses kLong.
125 bool wide = (data.op_size == kLong);
126 bool double_or_float = cu_->shorty[0] == 'F' || cu_->shorty[0] == 'D';
127
128 // Point of no return - no aborts after this
129 GenPrintLabel(mir);
130 LockArg(data.object_arg);
131 RegLocation rl_dest = wide ? GetReturnWide(double_or_float) : GetReturn(double_or_float);
132 int reg_obj = LoadArg(data.object_arg);
133 if (wide) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000134 LoadBaseDispWide(reg_obj, data.field_offset, rl_dest.low_reg, rl_dest.high_reg, INVALID_SREG);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800135 } else {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000136 LoadBaseDisp(reg_obj, data.field_offset, rl_dest.low_reg, kWord, INVALID_SREG);
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800137 }
138 if (data.is_volatile) {
139 GenMemBarrier(kLoadLoad);
140 }
141 return true;
142}
143
144bool Mir2Lir::GenSpecialIPut(MIR* mir, const InlineMethod& special) {
145 // FastInstance() already checked by DexFileMethodInliner.
146 const InlineIGetIPutData& data = special.d.ifield_data;
147 if (data.method_is_static || data.object_arg != 0) {
148 // The object is not "this" and has to be null-checked.
149 return false;
150 }
151
152 DCHECK_NE(data.op_size, kDouble); // The inliner doesn't distinguish kDouble, uses kLong.
153 bool wide = (data.op_size == kLong);
154
155 // Point of no return - no aborts after this
156 GenPrintLabel(mir);
157 LockArg(data.object_arg);
158 LockArg(data.src_arg, wide);
159 int reg_obj = LoadArg(data.object_arg);
160 int reg_src = LoadArg(data.src_arg, wide);
161 if (data.is_volatile) {
162 GenMemBarrier(kStoreStore);
163 }
164 if (wide) {
165 int low_reg, high_reg;
166 DECODE_REG_PAIR(reg_src, low_reg, high_reg);
167 StoreBaseDispWide(reg_obj, data.field_offset, low_reg, high_reg);
168 } else {
169 StoreBaseDisp(reg_obj, data.field_offset, reg_src, kWord);
170 }
171 if (data.is_volatile) {
172 GenMemBarrier(kLoadLoad);
173 }
174 if (data.is_object) {
175 MarkGCCard(reg_src, reg_obj);
176 }
177 return true;
178}
179
180bool Mir2Lir::GenSpecialIdentity(MIR* mir, const InlineMethod& special) {
181 const InlineReturnArgData& data = special.d.return_data;
182 DCHECK_NE(data.op_size, kDouble); // The inliner doesn't distinguish kDouble, uses kLong.
183 bool wide = (data.op_size == kLong);
184 bool double_or_float = cu_->shorty[0] == 'F' || cu_->shorty[0] == 'D';
185
186 // Point of no return - no aborts after this
187 GenPrintLabel(mir);
188 LockArg(data.arg, wide);
189 RegLocation rl_dest = wide ? GetReturnWide(double_or_float) : GetReturn(double_or_float);
190 LoadArgDirect(data.arg, rl_dest);
191 return true;
192}
193
194/*
195 * Special-case code generation for simple non-throwing leaf methods.
196 */
197bool Mir2Lir::GenSpecialCase(BasicBlock* bb, MIR* mir, const InlineMethod& special) {
198 DCHECK(special.flags & kInlineSpecial);
199 current_dalvik_offset_ = mir->offset;
200 MIR* return_mir = nullptr;
201 bool successful = false;
202
203 switch (special.opcode) {
204 case kInlineOpNop:
205 successful = true;
206 DCHECK_EQ(mir->dalvikInsn.opcode, Instruction::RETURN_VOID);
207 return_mir = mir;
208 break;
209 case kInlineOpNonWideConst: {
210 successful = true;
211 RegLocation rl_dest = GetReturn(cu_->shorty[0] == 'F');
212 GenPrintLabel(mir);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000213 LoadConstant(rl_dest.low_reg, static_cast<int>(special.d.data));
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800214 return_mir = mir_graph_->GetNextUnconditionalMir(bb, mir);
215 break;
216 }
217 case kInlineOpReturnArg:
218 successful = GenSpecialIdentity(mir, special);
219 return_mir = mir;
220 break;
221 case kInlineOpIGet:
222 successful = GenSpecialIGet(mir, special);
223 return_mir = mir_graph_->GetNextUnconditionalMir(bb, mir);
224 break;
225 case kInlineOpIPut:
226 successful = GenSpecialIPut(mir, special);
227 return_mir = mir_graph_->GetNextUnconditionalMir(bb, mir);
228 break;
229 default:
230 break;
231 }
232
233 if (successful) {
Vladimir Marko39d95e62014-02-28 12:51:24 +0000234 if (kIsDebugBuild) {
235 // Clear unreachable catch entries.
236 mir_graph_->catches_.clear();
237 }
238
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800239 // Handle verbosity for return MIR.
240 if (return_mir != nullptr) {
241 current_dalvik_offset_ = return_mir->offset;
242 // Not handling special identity case because it already generated code as part
243 // of the return. The label should have been added before any code was generated.
244 if (special.opcode != kInlineOpReturnArg) {
245 GenPrintLabel(return_mir);
246 }
247 }
248 GenSpecialExitSequence();
249
250 core_spill_mask_ = 0;
251 num_core_spills_ = 0;
252 fp_spill_mask_ = 0;
253 num_fp_spills_ = 0;
254 frame_size_ = 0;
255 core_vmap_table_.clear();
256 fp_vmap_table_.clear();
257 }
258
259 return successful;
260}
261
Brian Carlstrom7940e442013-07-12 13:46:57 -0700262/*
263 * Target-independent code generation. Use only high-level
264 * load/store utilities here, or target-dependent genXX() handlers
265 * when necessary.
266 */
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700267void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700268 RegLocation rl_src[3];
269 RegLocation rl_dest = mir_graph_->GetBadLoc();
270 RegLocation rl_result = mir_graph_->GetBadLoc();
271 Instruction::Code opcode = mir->dalvikInsn.opcode;
272 int opt_flags = mir->optimization_flags;
273 uint32_t vB = mir->dalvikInsn.vB;
274 uint32_t vC = mir->dalvikInsn.vC;
275
276 // Prep Src and Dest locations.
277 int next_sreg = 0;
278 int next_loc = 0;
buzbee1da1e2f2013-11-15 13:37:01 -0800279 uint64_t attrs = mir_graph_->oat_data_flow_attributes_[opcode];
Brian Carlstrom7940e442013-07-12 13:46:57 -0700280 rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc();
281 if (attrs & DF_UA) {
282 if (attrs & DF_A_WIDE) {
283 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
284 next_sreg+= 2;
285 } else {
286 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
287 next_sreg++;
288 }
289 }
290 if (attrs & DF_UB) {
291 if (attrs & DF_B_WIDE) {
292 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
293 next_sreg+= 2;
294 } else {
295 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
296 next_sreg++;
297 }
298 }
299 if (attrs & DF_UC) {
300 if (attrs & DF_C_WIDE) {
301 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg);
302 } else {
303 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg);
304 }
305 }
306 if (attrs & DF_DA) {
307 if (attrs & DF_A_WIDE) {
308 rl_dest = mir_graph_->GetDestWide(mir);
309 } else {
310 rl_dest = mir_graph_->GetDest(mir);
311 }
312 }
313 switch (opcode) {
314 case Instruction::NOP:
315 break;
316
317 case Instruction::MOVE_EXCEPTION:
318 GenMoveException(rl_dest);
319 break;
320
321 case Instruction::RETURN_VOID:
322 if (((cu_->access_flags & kAccConstructor) != 0) &&
323 cu_->compiler_driver->RequiresConstructorBarrier(Thread::Current(), cu_->dex_file,
324 cu_->class_def_idx)) {
325 GenMemBarrier(kStoreStore);
326 }
327 if (!mir_graph_->MethodIsLeaf()) {
328 GenSuspendTest(opt_flags);
329 }
330 break;
331
332 case Instruction::RETURN:
333 case Instruction::RETURN_OBJECT:
334 if (!mir_graph_->MethodIsLeaf()) {
335 GenSuspendTest(opt_flags);
336 }
337 StoreValue(GetReturn(cu_->shorty[0] == 'F'), rl_src[0]);
338 break;
339
340 case Instruction::RETURN_WIDE:
341 if (!mir_graph_->MethodIsLeaf()) {
342 GenSuspendTest(opt_flags);
343 }
344 StoreValueWide(GetReturnWide(cu_->shorty[0] == 'D'), rl_src[0]);
345 break;
346
347 case Instruction::MOVE_RESULT_WIDE:
348 if (opt_flags & MIR_INLINED)
349 break; // Nop - combined w/ previous invoke.
350 StoreValueWide(rl_dest, GetReturnWide(rl_dest.fp));
351 break;
352
353 case Instruction::MOVE_RESULT:
354 case Instruction::MOVE_RESULT_OBJECT:
355 if (opt_flags & MIR_INLINED)
356 break; // Nop - combined w/ previous invoke.
357 StoreValue(rl_dest, GetReturn(rl_dest.fp));
358 break;
359
360 case Instruction::MOVE:
361 case Instruction::MOVE_OBJECT:
362 case Instruction::MOVE_16:
363 case Instruction::MOVE_OBJECT_16:
364 case Instruction::MOVE_FROM16:
365 case Instruction::MOVE_OBJECT_FROM16:
366 StoreValue(rl_dest, rl_src[0]);
367 break;
368
369 case Instruction::MOVE_WIDE:
370 case Instruction::MOVE_WIDE_16:
371 case Instruction::MOVE_WIDE_FROM16:
372 StoreValueWide(rl_dest, rl_src[0]);
373 break;
374
375 case Instruction::CONST:
376 case Instruction::CONST_4:
377 case Instruction::CONST_16:
378 rl_result = EvalLoc(rl_dest, kAnyReg, true);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000379 LoadConstantNoClobber(rl_result.low_reg, vB);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700380 StoreValue(rl_dest, rl_result);
381 if (vB == 0) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000382 Workaround7250540(rl_dest, rl_result.low_reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700383 }
384 break;
385
386 case Instruction::CONST_HIGH16:
387 rl_result = EvalLoc(rl_dest, kAnyReg, true);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000388 LoadConstantNoClobber(rl_result.low_reg, vB << 16);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700389 StoreValue(rl_dest, rl_result);
390 if (vB == 0) {
Bill Buzbee86ec5202014-02-26 19:03:09 +0000391 Workaround7250540(rl_dest, rl_result.low_reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700392 }
393 break;
394
395 case Instruction::CONST_WIDE_16:
396 case Instruction::CONST_WIDE_32:
Bill Buzbeed61ba4b2014-01-13 21:44:01 +0000397 GenConstWide(rl_dest, static_cast<int64_t>(static_cast<int32_t>(vB)));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700398 break;
399
400 case Instruction::CONST_WIDE:
Bill Buzbeed61ba4b2014-01-13 21:44:01 +0000401 GenConstWide(rl_dest, mir->dalvikInsn.vB_wide);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700402 break;
403
404 case Instruction::CONST_WIDE_HIGH16:
405 rl_result = EvalLoc(rl_dest, kAnyReg, true);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000406 LoadConstantWide(rl_result.low_reg, rl_result.high_reg,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700407 static_cast<int64_t>(vB) << 48);
408 StoreValueWide(rl_dest, rl_result);
409 break;
410
411 case Instruction::MONITOR_ENTER:
412 GenMonitorEnter(opt_flags, rl_src[0]);
413 break;
414
415 case Instruction::MONITOR_EXIT:
416 GenMonitorExit(opt_flags, rl_src[0]);
417 break;
418
419 case Instruction::CHECK_CAST: {
420 GenCheckCast(mir->offset, vB, rl_src[0]);
421 break;
422 }
423 case Instruction::INSTANCE_OF:
424 GenInstanceof(vC, rl_dest, rl_src[0]);
425 break;
426
427 case Instruction::NEW_INSTANCE:
428 GenNewInstance(vB, rl_dest);
429 break;
430
431 case Instruction::THROW:
432 GenThrow(rl_src[0]);
433 break;
434
435 case Instruction::ARRAY_LENGTH:
436 int len_offset;
437 len_offset = mirror::Array::LengthOffset().Int32Value();
438 rl_src[0] = LoadValue(rl_src[0], kCoreReg);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000439 GenNullCheck(rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700440 rl_result = EvalLoc(rl_dest, kCoreReg, true);
Bill Buzbee86ec5202014-02-26 19:03:09 +0000441 LoadWordDisp(rl_src[0].low_reg, len_offset, rl_result.low_reg);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700442 StoreValue(rl_dest, rl_result);
443 break;
444
445 case Instruction::CONST_STRING:
446 case Instruction::CONST_STRING_JUMBO:
447 GenConstString(vB, rl_dest);
448 break;
449
450 case Instruction::CONST_CLASS:
451 GenConstClass(vB, rl_dest);
452 break;
453
454 case Instruction::FILL_ARRAY_DATA:
455 GenFillArrayData(vB, rl_src[0]);
456 break;
457
458 case Instruction::FILLED_NEW_ARRAY:
459 GenFilledNewArray(mir_graph_->NewMemCallInfo(bb, mir, kStatic,
460 false /* not range */));
461 break;
462
463 case Instruction::FILLED_NEW_ARRAY_RANGE:
464 GenFilledNewArray(mir_graph_->NewMemCallInfo(bb, mir, kStatic,
465 true /* range */));
466 break;
467
468 case Instruction::NEW_ARRAY:
469 GenNewArray(vC, rl_dest, rl_src[0]);
470 break;
471
472 case Instruction::GOTO:
473 case Instruction::GOTO_16:
474 case Instruction::GOTO_32:
buzbee9329e6d2013-08-19 12:55:10 -0700475 if (mir_graph_->IsBackedge(bb, bb->taken)) {
buzbee0d829482013-10-11 15:24:55 -0700476 GenSuspendTestAndBranch(opt_flags, &label_list[bb->taken]);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700477 } else {
buzbee0d829482013-10-11 15:24:55 -0700478 OpUnconditionalBranch(&label_list[bb->taken]);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700479 }
480 break;
481
482 case Instruction::PACKED_SWITCH:
483 GenPackedSwitch(mir, vB, rl_src[0]);
484 break;
485
486 case Instruction::SPARSE_SWITCH:
487 GenSparseSwitch(mir, vB, rl_src[0]);
488 break;
489
490 case Instruction::CMPL_FLOAT:
491 case Instruction::CMPG_FLOAT:
492 case Instruction::CMPL_DOUBLE:
493 case Instruction::CMPG_DOUBLE:
494 GenCmpFP(opcode, rl_dest, rl_src[0], rl_src[1]);
495 break;
496
497 case Instruction::CMP_LONG:
498 GenCmpLong(rl_dest, rl_src[0], rl_src[1]);
499 break;
500
501 case Instruction::IF_EQ:
502 case Instruction::IF_NE:
503 case Instruction::IF_LT:
504 case Instruction::IF_GE:
505 case Instruction::IF_GT:
506 case Instruction::IF_LE: {
buzbee0d829482013-10-11 15:24:55 -0700507 LIR* taken = &label_list[bb->taken];
508 LIR* fall_through = &label_list[bb->fall_through];
Brian Carlstrom7940e442013-07-12 13:46:57 -0700509 // Result known at compile time?
510 if (rl_src[0].is_const && rl_src[1].is_const) {
511 bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg),
512 mir_graph_->ConstantValue(rl_src[1].orig_sreg));
buzbee0d829482013-10-11 15:24:55 -0700513 BasicBlockId target_id = is_taken ? bb->taken : bb->fall_through;
514 if (mir_graph_->IsBackedge(bb, target_id)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700515 GenSuspendTest(opt_flags);
516 }
buzbee0d829482013-10-11 15:24:55 -0700517 OpUnconditionalBranch(&label_list[target_id]);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700518 } else {
buzbee9329e6d2013-08-19 12:55:10 -0700519 if (mir_graph_->IsBackwardsBranch(bb)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700520 GenSuspendTest(opt_flags);
521 }
buzbee0d829482013-10-11 15:24:55 -0700522 GenCompareAndBranch(opcode, rl_src[0], rl_src[1], taken, fall_through);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700523 }
524 break;
525 }
526
527 case Instruction::IF_EQZ:
528 case Instruction::IF_NEZ:
529 case Instruction::IF_LTZ:
530 case Instruction::IF_GEZ:
531 case Instruction::IF_GTZ:
532 case Instruction::IF_LEZ: {
buzbee0d829482013-10-11 15:24:55 -0700533 LIR* taken = &label_list[bb->taken];
534 LIR* fall_through = &label_list[bb->fall_through];
Brian Carlstrom7940e442013-07-12 13:46:57 -0700535 // Result known at compile time?
536 if (rl_src[0].is_const) {
537 bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg), 0);
buzbee0d829482013-10-11 15:24:55 -0700538 BasicBlockId target_id = is_taken ? bb->taken : bb->fall_through;
539 if (mir_graph_->IsBackedge(bb, target_id)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700540 GenSuspendTest(opt_flags);
541 }
buzbee0d829482013-10-11 15:24:55 -0700542 OpUnconditionalBranch(&label_list[target_id]);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700543 } else {
buzbee9329e6d2013-08-19 12:55:10 -0700544 if (mir_graph_->IsBackwardsBranch(bb)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700545 GenSuspendTest(opt_flags);
546 }
547 GenCompareZeroAndBranch(opcode, rl_src[0], taken, fall_through);
548 }
549 break;
550 }
551
552 case Instruction::AGET_WIDE:
553 GenArrayGet(opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
554 break;
555 case Instruction::AGET:
556 case Instruction::AGET_OBJECT:
557 GenArrayGet(opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
558 break;
559 case Instruction::AGET_BOOLEAN:
560 GenArrayGet(opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
561 break;
562 case Instruction::AGET_BYTE:
563 GenArrayGet(opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
564 break;
565 case Instruction::AGET_CHAR:
566 GenArrayGet(opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
567 break;
568 case Instruction::AGET_SHORT:
569 GenArrayGet(opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
570 break;
571 case Instruction::APUT_WIDE:
Ian Rogersa9a82542013-10-04 11:17:26 -0700572 GenArrayPut(opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700573 break;
574 case Instruction::APUT:
Ian Rogersa9a82542013-10-04 11:17:26 -0700575 GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700576 break;
Ian Rogersa9a82542013-10-04 11:17:26 -0700577 case Instruction::APUT_OBJECT: {
578 bool is_null = mir_graph_->IsConstantNullRef(rl_src[0]);
579 bool is_safe = is_null; // Always safe to store null.
580 if (!is_safe) {
581 // Check safety from verifier type information.
Vladimir Marko2730db02014-01-27 11:15:17 +0000582 const DexCompilationUnit* unit = mir_graph_->GetCurrentDexCompilationUnit();
583 is_safe = cu_->compiler_driver->IsSafeCast(unit, mir->offset);
Ian Rogersa9a82542013-10-04 11:17:26 -0700584 }
585 if (is_null || is_safe) {
586 // Store of constant null doesn't require an assignability test and can be generated inline
587 // without fixed register usage or a card mark.
588 GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2, !is_null);
589 } else {
590 GenArrayObjPut(opt_flags, rl_src[1], rl_src[2], rl_src[0]);
591 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700592 break;
Ian Rogersa9a82542013-10-04 11:17:26 -0700593 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700594 case Instruction::APUT_SHORT:
595 case Instruction::APUT_CHAR:
Ian Rogersa9a82542013-10-04 11:17:26 -0700596 GenArrayPut(opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700597 break;
598 case Instruction::APUT_BYTE:
599 case Instruction::APUT_BOOLEAN:
Ian Rogersa9a82542013-10-04 11:17:26 -0700600 GenArrayPut(opt_flags, kUnsignedByte, rl_src[1], rl_src[2], rl_src[0], 0, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700601 break;
602
603 case Instruction::IGET_OBJECT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000604 GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700605 break;
606
607 case Instruction::IGET_WIDE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000608 GenIGet(vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700609 break;
610
611 case Instruction::IGET:
Ian Rogers9c86a022014-02-21 16:40:21 +0000612 GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700613 break;
614
615 case Instruction::IGET_CHAR:
Ian Rogers9c86a022014-02-21 16:40:21 +0000616 GenIGet(vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700617 break;
618
619 case Instruction::IGET_SHORT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000620 GenIGet(vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700621 break;
622
623 case Instruction::IGET_BOOLEAN:
624 case Instruction::IGET_BYTE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000625 GenIGet(vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700626 break;
627
628 case Instruction::IPUT_WIDE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000629 GenIPut(vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700630 break;
631
632 case Instruction::IPUT_OBJECT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000633 GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700634 break;
635
636 case Instruction::IPUT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000637 GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700638 break;
639
640 case Instruction::IPUT_BOOLEAN:
641 case Instruction::IPUT_BYTE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000642 GenIPut(vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700643 break;
644
645 case Instruction::IPUT_CHAR:
Ian Rogers9c86a022014-02-21 16:40:21 +0000646 GenIPut(vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700647 break;
648
649 case Instruction::IPUT_SHORT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000650 GenIPut(vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700651 break;
652
653 case Instruction::SGET_OBJECT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000654 GenSget(vB, rl_dest, false, true);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700655 break;
656 case Instruction::SGET:
657 case Instruction::SGET_BOOLEAN:
658 case Instruction::SGET_BYTE:
659 case Instruction::SGET_CHAR:
660 case Instruction::SGET_SHORT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000661 GenSget(vB, rl_dest, false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700662 break;
663
664 case Instruction::SGET_WIDE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000665 GenSget(vB, rl_dest, true, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700666 break;
667
668 case Instruction::SPUT_OBJECT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000669 GenSput(vB, rl_src[0], false, true);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700670 break;
671
672 case Instruction::SPUT:
673 case Instruction::SPUT_BOOLEAN:
674 case Instruction::SPUT_BYTE:
675 case Instruction::SPUT_CHAR:
676 case Instruction::SPUT_SHORT:
Ian Rogers9c86a022014-02-21 16:40:21 +0000677 GenSput(vB, rl_src[0], false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700678 break;
679
680 case Instruction::SPUT_WIDE:
Ian Rogers9c86a022014-02-21 16:40:21 +0000681 GenSput(vB, rl_src[0], true, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700682 break;
683
684 case Instruction::INVOKE_STATIC_RANGE:
685 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, true));
686 break;
687 case Instruction::INVOKE_STATIC:
688 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, false));
689 break;
690
691 case Instruction::INVOKE_DIRECT:
692 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, false));
693 break;
694 case Instruction::INVOKE_DIRECT_RANGE:
695 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, true));
696 break;
697
698 case Instruction::INVOKE_VIRTUAL:
699 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, false));
700 break;
701 case Instruction::INVOKE_VIRTUAL_RANGE:
702 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, true));
703 break;
704
705 case Instruction::INVOKE_SUPER:
706 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, false));
707 break;
708 case Instruction::INVOKE_SUPER_RANGE:
709 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, true));
710 break;
711
712 case Instruction::INVOKE_INTERFACE:
713 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, false));
714 break;
715 case Instruction::INVOKE_INTERFACE_RANGE:
716 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, true));
717 break;
718
719 case Instruction::NEG_INT:
720 case Instruction::NOT_INT:
721 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0]);
722 break;
723
724 case Instruction::NEG_LONG:
725 case Instruction::NOT_LONG:
726 GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0]);
727 break;
728
729 case Instruction::NEG_FLOAT:
730 GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[0]);
731 break;
732
733 case Instruction::NEG_DOUBLE:
734 GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[0]);
735 break;
736
737 case Instruction::INT_TO_LONG:
738 GenIntToLong(rl_dest, rl_src[0]);
739 break;
740
741 case Instruction::LONG_TO_INT:
742 rl_src[0] = UpdateLocWide(rl_src[0]);
743 rl_src[0] = WideToNarrow(rl_src[0]);
744 StoreValue(rl_dest, rl_src[0]);
745 break;
746
747 case Instruction::INT_TO_BYTE:
748 case Instruction::INT_TO_SHORT:
749 case Instruction::INT_TO_CHAR:
750 GenIntNarrowing(opcode, rl_dest, rl_src[0]);
751 break;
752
753 case Instruction::INT_TO_FLOAT:
754 case Instruction::INT_TO_DOUBLE:
755 case Instruction::LONG_TO_FLOAT:
756 case Instruction::LONG_TO_DOUBLE:
757 case Instruction::FLOAT_TO_INT:
758 case Instruction::FLOAT_TO_LONG:
759 case Instruction::FLOAT_TO_DOUBLE:
760 case Instruction::DOUBLE_TO_INT:
761 case Instruction::DOUBLE_TO_LONG:
762 case Instruction::DOUBLE_TO_FLOAT:
763 GenConversion(opcode, rl_dest, rl_src[0]);
764 break;
765
766
767 case Instruction::ADD_INT:
768 case Instruction::ADD_INT_2ADDR:
769 case Instruction::MUL_INT:
770 case Instruction::MUL_INT_2ADDR:
771 case Instruction::AND_INT:
772 case Instruction::AND_INT_2ADDR:
773 case Instruction::OR_INT:
774 case Instruction::OR_INT_2ADDR:
775 case Instruction::XOR_INT:
776 case Instruction::XOR_INT_2ADDR:
777 if (rl_src[0].is_const &&
778 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[0]))) {
779 GenArithOpIntLit(opcode, rl_dest, rl_src[1],
780 mir_graph_->ConstantValue(rl_src[0].orig_sreg));
781 } else if (rl_src[1].is_const &&
782 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) {
783 GenArithOpIntLit(opcode, rl_dest, rl_src[0],
784 mir_graph_->ConstantValue(rl_src[1].orig_sreg));
785 } else {
786 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
787 }
788 break;
789
790 case Instruction::SUB_INT:
791 case Instruction::SUB_INT_2ADDR:
792 case Instruction::DIV_INT:
793 case Instruction::DIV_INT_2ADDR:
794 case Instruction::REM_INT:
795 case Instruction::REM_INT_2ADDR:
796 case Instruction::SHL_INT:
797 case Instruction::SHL_INT_2ADDR:
798 case Instruction::SHR_INT:
799 case Instruction::SHR_INT_2ADDR:
800 case Instruction::USHR_INT:
801 case Instruction::USHR_INT_2ADDR:
802 if (rl_src[1].is_const &&
803 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) {
804 GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1]));
805 } else {
806 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
807 }
808 break;
809
810 case Instruction::ADD_LONG:
811 case Instruction::SUB_LONG:
812 case Instruction::AND_LONG:
813 case Instruction::OR_LONG:
814 case Instruction::XOR_LONG:
815 case Instruction::ADD_LONG_2ADDR:
816 case Instruction::SUB_LONG_2ADDR:
817 case Instruction::AND_LONG_2ADDR:
818 case Instruction::OR_LONG_2ADDR:
819 case Instruction::XOR_LONG_2ADDR:
820 if (rl_src[0].is_const || rl_src[1].is_const) {
821 GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
822 break;
823 }
824 // Note: intentional fallthrough.
825
826 case Instruction::MUL_LONG:
827 case Instruction::DIV_LONG:
828 case Instruction::REM_LONG:
829 case Instruction::MUL_LONG_2ADDR:
830 case Instruction::DIV_LONG_2ADDR:
831 case Instruction::REM_LONG_2ADDR:
832 GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
833 break;
834
835 case Instruction::SHL_LONG:
836 case Instruction::SHR_LONG:
837 case Instruction::USHR_LONG:
838 case Instruction::SHL_LONG_2ADDR:
839 case Instruction::SHR_LONG_2ADDR:
840 case Instruction::USHR_LONG_2ADDR:
841 if (rl_src[1].is_const) {
842 GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
843 } else {
844 GenShiftOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
845 }
846 break;
847
848 case Instruction::ADD_FLOAT:
849 case Instruction::SUB_FLOAT:
850 case Instruction::MUL_FLOAT:
851 case Instruction::DIV_FLOAT:
852 case Instruction::REM_FLOAT:
853 case Instruction::ADD_FLOAT_2ADDR:
854 case Instruction::SUB_FLOAT_2ADDR:
855 case Instruction::MUL_FLOAT_2ADDR:
856 case Instruction::DIV_FLOAT_2ADDR:
857 case Instruction::REM_FLOAT_2ADDR:
858 GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[1]);
859 break;
860
861 case Instruction::ADD_DOUBLE:
862 case Instruction::SUB_DOUBLE:
863 case Instruction::MUL_DOUBLE:
864 case Instruction::DIV_DOUBLE:
865 case Instruction::REM_DOUBLE:
866 case Instruction::ADD_DOUBLE_2ADDR:
867 case Instruction::SUB_DOUBLE_2ADDR:
868 case Instruction::MUL_DOUBLE_2ADDR:
869 case Instruction::DIV_DOUBLE_2ADDR:
870 case Instruction::REM_DOUBLE_2ADDR:
871 GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[1]);
872 break;
873
874 case Instruction::RSUB_INT:
875 case Instruction::ADD_INT_LIT16:
876 case Instruction::MUL_INT_LIT16:
877 case Instruction::DIV_INT_LIT16:
878 case Instruction::REM_INT_LIT16:
879 case Instruction::AND_INT_LIT16:
880 case Instruction::OR_INT_LIT16:
881 case Instruction::XOR_INT_LIT16:
882 case Instruction::ADD_INT_LIT8:
883 case Instruction::RSUB_INT_LIT8:
884 case Instruction::MUL_INT_LIT8:
885 case Instruction::DIV_INT_LIT8:
886 case Instruction::REM_INT_LIT8:
887 case Instruction::AND_INT_LIT8:
888 case Instruction::OR_INT_LIT8:
889 case Instruction::XOR_INT_LIT8:
890 case Instruction::SHL_INT_LIT8:
891 case Instruction::SHR_INT_LIT8:
892 case Instruction::USHR_INT_LIT8:
893 GenArithOpIntLit(opcode, rl_dest, rl_src[0], vC);
894 break;
895
896 default:
897 LOG(FATAL) << "Unexpected opcode: " << opcode;
898 }
Brian Carlstrom1895ea32013-07-18 13:28:37 -0700899} // NOLINT(readability/fn_size)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700900
901// Process extended MIR instructions
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700902void Mir2Lir::HandleExtendedMethodMIR(BasicBlock* bb, MIR* mir) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700903 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
904 case kMirOpCopy: {
905 RegLocation rl_src = mir_graph_->GetSrc(mir, 0);
906 RegLocation rl_dest = mir_graph_->GetDest(mir);
907 StoreValue(rl_dest, rl_src);
908 break;
909 }
910 case kMirOpFusedCmplFloat:
911 GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, false /*double*/);
912 break;
913 case kMirOpFusedCmpgFloat:
914 GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, false /*double*/);
915 break;
916 case kMirOpFusedCmplDouble:
917 GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, true /*double*/);
918 break;
919 case kMirOpFusedCmpgDouble:
920 GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, true /*double*/);
921 break;
922 case kMirOpFusedCmpLong:
923 GenFusedLongCmpBranch(bb, mir);
924 break;
925 case kMirOpSelect:
926 GenSelect(bb, mir);
927 break;
928 default:
929 break;
930 }
931}
932
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800933void Mir2Lir::GenPrintLabel(MIR* mir) {
934 // Mark the beginning of a Dalvik instruction for line tracking.
935 if (cu_->verbose) {
936 char* inst_str = mir_graph_->GetDalvikDisassembly(mir);
937 MarkBoundary(mir->offset, inst_str);
938 }
939}
940
Brian Carlstrom7940e442013-07-12 13:46:57 -0700941// Handle the content in each basic block.
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700942bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700943 if (bb->block_type == kDead) return false;
944 current_dalvik_offset_ = bb->start_offset;
945 MIR* mir;
946 int block_id = bb->id;
947
948 block_label_list_[block_id].operands[0] = bb->start_offset;
949
950 // Insert the block label.
951 block_label_list_[block_id].opcode = kPseudoNormalBlockLabel;
buzbeeb48819d2013-09-14 16:15:25 -0700952 block_label_list_[block_id].flags.fixup = kFixupLabel;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700953 AppendLIR(&block_label_list_[block_id]);
954
955 LIR* head_lir = NULL;
956
957 // If this is a catch block, export the start address.
958 if (bb->catch_entry) {
959 head_lir = NewLIR0(kPseudoExportedPC);
960 }
961
962 // Free temp registers and reset redundant store tracking.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700963 ClobberAllRegs();
964
965 if (bb->block_type == kEntryBlock) {
buzbee56c71782013-09-05 17:13:19 -0700966 ResetRegPool();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700967 int start_vreg = cu_->num_dalvik_registers - cu_->num_ins;
968 GenEntrySequence(&mir_graph_->reg_location_[start_vreg],
969 mir_graph_->reg_location_[mir_graph_->GetMethodSReg()]);
970 } else if (bb->block_type == kExitBlock) {
buzbee56c71782013-09-05 17:13:19 -0700971 ResetRegPool();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700972 GenExitSequence();
973 }
974
975 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
976 ResetRegPool();
977 if (cu_->disable_opt & (1 << kTrackLiveTemps)) {
978 ClobberAllRegs();
979 }
980
981 if (cu_->disable_opt & (1 << kSuppressLoads)) {
982 ResetDefTracking();
983 }
984
985 // Reset temp tracking sanity check.
986 if (kIsDebugBuild) {
987 live_sreg_ = INVALID_SREG;
988 }
989
990 current_dalvik_offset_ = mir->offset;
991 int opcode = mir->dalvikInsn.opcode;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700992
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -0800993 GenPrintLabel(mir);
994
Brian Carlstrom7940e442013-07-12 13:46:57 -0700995 // Remember the first LIR for this block.
996 if (head_lir == NULL) {
buzbee252254b2013-09-08 16:20:53 -0700997 head_lir = &block_label_list_[bb->id];
998 // Set the first label as a scheduling barrier.
buzbeeb48819d2013-09-14 16:15:25 -0700999 DCHECK(!head_lir->flags.use_def_invalid);
1000 head_lir->u.m.def_mask = ENCODE_ALL;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001001 }
1002
1003 if (opcode == kMirOpCheck) {
1004 // Combine check and work halves of throwing instruction.
1005 MIR* work_half = mir->meta.throw_insn;
1006 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
Vladimir Marko4376c872014-01-23 12:39:29 +00001007 mir->meta = work_half->meta; // Whatever the work_half had, we need to copy it.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001008 opcode = work_half->dalvikInsn.opcode;
1009 SSARepresentation* ssa_rep = work_half->ssa_rep;
1010 work_half->ssa_rep = mir->ssa_rep;
1011 mir->ssa_rep = ssa_rep;
1012 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
Vladimir Marko4376c872014-01-23 12:39:29 +00001013 work_half->meta.throw_insn = mir;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001014 }
1015
1016 if (opcode >= kMirOpFirst) {
1017 HandleExtendedMethodMIR(bb, mir);
1018 continue;
1019 }
1020
1021 CompileDalvikInstruction(mir, bb, block_label_list_);
1022 }
1023
1024 if (head_lir) {
1025 // Eliminate redundant loads/stores and delay stores into later slots.
1026 ApplyLocalOptimizations(head_lir, last_lir_insn_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001027 }
1028 return false;
1029}
1030
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -08001031bool Mir2Lir::SpecialMIR2LIR(const InlineMethod& special) {
Vladimir Marko5816ed42013-11-27 17:04:20 +00001032 cu_->NewTimingSplit("SpecialMIR2LIR");
Brian Carlstrom7940e442013-07-12 13:46:57 -07001033 // Find the first DalvikByteCode block.
1034 int num_reachable_blocks = mir_graph_->GetNumReachableBlocks();
1035 BasicBlock*bb = NULL;
1036 for (int idx = 0; idx < num_reachable_blocks; idx++) {
1037 // TODO: no direct access of growable lists.
1038 int dfs_index = mir_graph_->GetDfsOrder()->Get(idx);
1039 bb = mir_graph_->GetBasicBlock(dfs_index);
1040 if (bb->block_type == kDalvikByteCode) {
1041 break;
1042 }
1043 }
1044 if (bb == NULL) {
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -08001045 return false;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001046 }
1047 DCHECK_EQ(bb->start_offset, 0);
1048 DCHECK(bb->first_mir_insn != NULL);
1049
1050 // Get the first instruction.
1051 MIR* mir = bb->first_mir_insn;
1052
1053 // Free temp registers and reset redundant store tracking.
1054 ResetRegPool();
1055 ResetDefTracking();
1056 ClobberAllRegs();
1057
Razvan A Lupusoru3bc01742014-02-06 13:18:43 -08001058 return GenSpecialCase(bb, mir, special);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001059}
1060
Brian Carlstrom2ce745c2013-07-17 17:44:30 -07001061void Mir2Lir::MethodMIR2LIR() {
buzbeea61f4952013-08-23 14:27:06 -07001062 cu_->NewTimingSplit("MIR2LIR");
1063
Brian Carlstrom7940e442013-07-12 13:46:57 -07001064 // Hold the labels of each block.
1065 block_label_list_ =
Mathieu Chartierf6c4b3b2013-08-24 16:11:37 -07001066 static_cast<LIR*>(arena_->Alloc(sizeof(LIR) * mir_graph_->GetNumBlocks(),
1067 ArenaAllocator::kAllocLIR));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001068
buzbee56c71782013-09-05 17:13:19 -07001069 PreOrderDfsIterator iter(mir_graph_);
buzbee252254b2013-09-08 16:20:53 -07001070 BasicBlock* curr_bb = iter.Next();
1071 BasicBlock* next_bb = iter.Next();
1072 while (curr_bb != NULL) {
1073 MethodBlockCodeGen(curr_bb);
1074 // If the fall_through block is no longer laid out consecutively, drop in a branch.
buzbee0d829482013-10-11 15:24:55 -07001075 BasicBlock* curr_bb_fall_through = mir_graph_->GetBasicBlock(curr_bb->fall_through);
1076 if ((curr_bb_fall_through != NULL) && (curr_bb_fall_through != next_bb)) {
1077 OpUnconditionalBranch(&block_label_list_[curr_bb->fall_through]);
buzbee252254b2013-09-08 16:20:53 -07001078 }
1079 curr_bb = next_bb;
1080 do {
1081 next_bb = iter.Next();
1082 } while ((next_bb != NULL) && (next_bb->block_type == kDead));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001083 }
Dave Allisonbcec6fb2014-01-17 12:52:22 -08001084 HandleSlowPaths();
1085
buzbeea61f4952013-08-23 14:27:06 -07001086 cu_->NewTimingSplit("Launchpads");
Brian Carlstrom7940e442013-07-12 13:46:57 -07001087 HandleSuspendLaunchPads();
1088
1089 HandleThrowLaunchPads();
1090
1091 HandleIntrinsicLaunchPads();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001092}
1093
Dave Allisonbcec6fb2014-01-17 12:52:22 -08001094//
1095// LIR Slow Path
1096//
1097
1098LIR* Mir2Lir::LIRSlowPath::GenerateTargetLabel() {
1099 LIR* target = m2l_->RawLIR(current_dex_pc_, kPseudoTargetLabel);
1100 m2l_->AppendLIR(target);
1101 fromfast_->target = target;
1102 m2l_->SetCurrentDexPc(current_dex_pc_);
1103 return target;
1104}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001105} // namespace art