mir_to_lir.cc revision 2ce745c06271d5223d57dbf08117b20d5b60694a
1/* 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" 19#include "mir_to_lir-inl.h" 20#include "object_utils.h" 21 22namespace art { 23 24/* 25 * Target-independent code generation. Use only high-level 26 * load/store utilities here, or target-dependent genXX() handlers 27 * when necessary. 28 */ 29void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list) { 30 RegLocation rl_src[3]; 31 RegLocation rl_dest = mir_graph_->GetBadLoc(); 32 RegLocation rl_result = mir_graph_->GetBadLoc(); 33 Instruction::Code opcode = mir->dalvikInsn.opcode; 34 int opt_flags = mir->optimization_flags; 35 uint32_t vB = mir->dalvikInsn.vB; 36 uint32_t vC = mir->dalvikInsn.vC; 37 38 // Prep Src and Dest locations. 39 int next_sreg = 0; 40 int next_loc = 0; 41 int attrs = mir_graph_->oat_data_flow_attributes_[opcode]; 42 rl_src[0] = rl_src[1] = rl_src[2] = mir_graph_->GetBadLoc(); 43 if (attrs & DF_UA) { 44 if (attrs & DF_A_WIDE) { 45 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); 46 next_sreg+= 2; 47 } else { 48 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); 49 next_sreg++; 50 } 51 } 52 if (attrs & DF_UB) { 53 if (attrs & DF_B_WIDE) { 54 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); 55 next_sreg+= 2; 56 } else { 57 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); 58 next_sreg++; 59 } 60 } 61 if (attrs & DF_UC) { 62 if (attrs & DF_C_WIDE) { 63 rl_src[next_loc++] = mir_graph_->GetSrcWide(mir, next_sreg); 64 } else { 65 rl_src[next_loc++] = mir_graph_->GetSrc(mir, next_sreg); 66 } 67 } 68 if (attrs & DF_DA) { 69 if (attrs & DF_A_WIDE) { 70 rl_dest = mir_graph_->GetDestWide(mir); 71 } else { 72 rl_dest = mir_graph_->GetDest(mir); 73 } 74 } 75 switch (opcode) { 76 case Instruction::NOP: 77 break; 78 79 case Instruction::MOVE_EXCEPTION: 80 GenMoveException(rl_dest); 81 break; 82 83 case Instruction::RETURN_VOID: 84 if (((cu_->access_flags & kAccConstructor) != 0) && 85 cu_->compiler_driver->RequiresConstructorBarrier(Thread::Current(), cu_->dex_file, 86 cu_->class_def_idx)) { 87 GenMemBarrier(kStoreStore); 88 } 89 if (!mir_graph_->MethodIsLeaf()) { 90 GenSuspendTest(opt_flags); 91 } 92 break; 93 94 case Instruction::RETURN: 95 case Instruction::RETURN_OBJECT: 96 if (!mir_graph_->MethodIsLeaf()) { 97 GenSuspendTest(opt_flags); 98 } 99 StoreValue(GetReturn(cu_->shorty[0] == 'F'), rl_src[0]); 100 break; 101 102 case Instruction::RETURN_WIDE: 103 if (!mir_graph_->MethodIsLeaf()) { 104 GenSuspendTest(opt_flags); 105 } 106 StoreValueWide(GetReturnWide(cu_->shorty[0] == 'D'), rl_src[0]); 107 break; 108 109 case Instruction::MOVE_RESULT_WIDE: 110 if (opt_flags & MIR_INLINED) 111 break; // Nop - combined w/ previous invoke. 112 StoreValueWide(rl_dest, GetReturnWide(rl_dest.fp)); 113 break; 114 115 case Instruction::MOVE_RESULT: 116 case Instruction::MOVE_RESULT_OBJECT: 117 if (opt_flags & MIR_INLINED) 118 break; // Nop - combined w/ previous invoke. 119 StoreValue(rl_dest, GetReturn(rl_dest.fp)); 120 break; 121 122 case Instruction::MOVE: 123 case Instruction::MOVE_OBJECT: 124 case Instruction::MOVE_16: 125 case Instruction::MOVE_OBJECT_16: 126 case Instruction::MOVE_FROM16: 127 case Instruction::MOVE_OBJECT_FROM16: 128 StoreValue(rl_dest, rl_src[0]); 129 break; 130 131 case Instruction::MOVE_WIDE: 132 case Instruction::MOVE_WIDE_16: 133 case Instruction::MOVE_WIDE_FROM16: 134 StoreValueWide(rl_dest, rl_src[0]); 135 break; 136 137 case Instruction::CONST: 138 case Instruction::CONST_4: 139 case Instruction::CONST_16: 140 rl_result = EvalLoc(rl_dest, kAnyReg, true); 141 LoadConstantNoClobber(rl_result.low_reg, vB); 142 StoreValue(rl_dest, rl_result); 143 if (vB == 0) { 144 Workaround7250540(rl_dest, rl_result.low_reg); 145 } 146 break; 147 148 case Instruction::CONST_HIGH16: 149 rl_result = EvalLoc(rl_dest, kAnyReg, true); 150 LoadConstantNoClobber(rl_result.low_reg, vB << 16); 151 StoreValue(rl_dest, rl_result); 152 if (vB == 0) { 153 Workaround7250540(rl_dest, rl_result.low_reg); 154 } 155 break; 156 157 case Instruction::CONST_WIDE_16: 158 case Instruction::CONST_WIDE_32: 159 rl_result = EvalLoc(rl_dest, kAnyReg, true); 160 LoadConstantWide(rl_result.low_reg, rl_result.high_reg, 161 static_cast<int64_t>(static_cast<int32_t>(vB))); 162 StoreValueWide(rl_dest, rl_result); 163 break; 164 165 case Instruction::CONST_WIDE: 166 rl_result = EvalLoc(rl_dest, kAnyReg, true); 167 LoadConstantWide(rl_result.low_reg, rl_result.high_reg, mir->dalvikInsn.vB_wide); 168 StoreValueWide(rl_dest, rl_result); 169 break; 170 171 case Instruction::CONST_WIDE_HIGH16: 172 rl_result = EvalLoc(rl_dest, kAnyReg, true); 173 LoadConstantWide(rl_result.low_reg, rl_result.high_reg, 174 static_cast<int64_t>(vB) << 48); 175 StoreValueWide(rl_dest, rl_result); 176 break; 177 178 case Instruction::MONITOR_ENTER: 179 GenMonitorEnter(opt_flags, rl_src[0]); 180 break; 181 182 case Instruction::MONITOR_EXIT: 183 GenMonitorExit(opt_flags, rl_src[0]); 184 break; 185 186 case Instruction::CHECK_CAST: { 187 GenCheckCast(mir->offset, vB, rl_src[0]); 188 break; 189 } 190 case Instruction::INSTANCE_OF: 191 GenInstanceof(vC, rl_dest, rl_src[0]); 192 break; 193 194 case Instruction::NEW_INSTANCE: 195 GenNewInstance(vB, rl_dest); 196 break; 197 198 case Instruction::THROW: 199 GenThrow(rl_src[0]); 200 break; 201 202 case Instruction::ARRAY_LENGTH: 203 int len_offset; 204 len_offset = mirror::Array::LengthOffset().Int32Value(); 205 rl_src[0] = LoadValue(rl_src[0], kCoreReg); 206 GenNullCheck(rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags); 207 rl_result = EvalLoc(rl_dest, kCoreReg, true); 208 LoadWordDisp(rl_src[0].low_reg, len_offset, rl_result.low_reg); 209 StoreValue(rl_dest, rl_result); 210 break; 211 212 case Instruction::CONST_STRING: 213 case Instruction::CONST_STRING_JUMBO: 214 GenConstString(vB, rl_dest); 215 break; 216 217 case Instruction::CONST_CLASS: 218 GenConstClass(vB, rl_dest); 219 break; 220 221 case Instruction::FILL_ARRAY_DATA: 222 GenFillArrayData(vB, rl_src[0]); 223 break; 224 225 case Instruction::FILLED_NEW_ARRAY: 226 GenFilledNewArray(mir_graph_->NewMemCallInfo(bb, mir, kStatic, 227 false /* not range */)); 228 break; 229 230 case Instruction::FILLED_NEW_ARRAY_RANGE: 231 GenFilledNewArray(mir_graph_->NewMemCallInfo(bb, mir, kStatic, 232 true /* range */)); 233 break; 234 235 case Instruction::NEW_ARRAY: 236 GenNewArray(vC, rl_dest, rl_src[0]); 237 break; 238 239 case Instruction::GOTO: 240 case Instruction::GOTO_16: 241 case Instruction::GOTO_32: 242 if (bb->taken->start_offset <= mir->offset) { 243 GenSuspendTestAndBranch(opt_flags, &label_list[bb->taken->id]); 244 } else { 245 OpUnconditionalBranch(&label_list[bb->taken->id]); 246 } 247 break; 248 249 case Instruction::PACKED_SWITCH: 250 GenPackedSwitch(mir, vB, rl_src[0]); 251 break; 252 253 case Instruction::SPARSE_SWITCH: 254 GenSparseSwitch(mir, vB, rl_src[0]); 255 break; 256 257 case Instruction::CMPL_FLOAT: 258 case Instruction::CMPG_FLOAT: 259 case Instruction::CMPL_DOUBLE: 260 case Instruction::CMPG_DOUBLE: 261 GenCmpFP(opcode, rl_dest, rl_src[0], rl_src[1]); 262 break; 263 264 case Instruction::CMP_LONG: 265 GenCmpLong(rl_dest, rl_src[0], rl_src[1]); 266 break; 267 268 case Instruction::IF_EQ: 269 case Instruction::IF_NE: 270 case Instruction::IF_LT: 271 case Instruction::IF_GE: 272 case Instruction::IF_GT: 273 case Instruction::IF_LE: { 274 LIR* taken = &label_list[bb->taken->id]; 275 LIR* fall_through = &label_list[bb->fall_through->id]; 276 bool backward_branch; 277 backward_branch = (bb->taken->start_offset <= mir->offset); 278 // Result known at compile time? 279 if (rl_src[0].is_const && rl_src[1].is_const) { 280 bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg), 281 mir_graph_->ConstantValue(rl_src[1].orig_sreg)); 282 if (is_taken && backward_branch) { 283 GenSuspendTest(opt_flags); 284 } 285 int id = is_taken ? bb->taken->id : bb->fall_through->id; 286 OpUnconditionalBranch(&label_list[id]); 287 } else { 288 if (backward_branch) { 289 GenSuspendTest(opt_flags); 290 } 291 GenCompareAndBranch(opcode, rl_src[0], rl_src[1], taken, 292 fall_through); 293 } 294 break; 295 } 296 297 case Instruction::IF_EQZ: 298 case Instruction::IF_NEZ: 299 case Instruction::IF_LTZ: 300 case Instruction::IF_GEZ: 301 case Instruction::IF_GTZ: 302 case Instruction::IF_LEZ: { 303 LIR* taken = &label_list[bb->taken->id]; 304 LIR* fall_through = &label_list[bb->fall_through->id]; 305 bool backward_branch; 306 backward_branch = (bb->taken->start_offset <= mir->offset); 307 // Result known at compile time? 308 if (rl_src[0].is_const) { 309 bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg), 0); 310 if (is_taken && backward_branch) { 311 GenSuspendTest(opt_flags); 312 } 313 int id = is_taken ? bb->taken->id : bb->fall_through->id; 314 OpUnconditionalBranch(&label_list[id]); 315 } else { 316 if (backward_branch) { 317 GenSuspendTest(opt_flags); 318 } 319 GenCompareZeroAndBranch(opcode, rl_src[0], taken, fall_through); 320 } 321 break; 322 } 323 324 case Instruction::AGET_WIDE: 325 GenArrayGet(opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3); 326 break; 327 case Instruction::AGET: 328 case Instruction::AGET_OBJECT: 329 GenArrayGet(opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2); 330 break; 331 case Instruction::AGET_BOOLEAN: 332 GenArrayGet(opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0); 333 break; 334 case Instruction::AGET_BYTE: 335 GenArrayGet(opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0); 336 break; 337 case Instruction::AGET_CHAR: 338 GenArrayGet(opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1); 339 break; 340 case Instruction::AGET_SHORT: 341 GenArrayGet(opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1); 342 break; 343 case Instruction::APUT_WIDE: 344 GenArrayPut(opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3); 345 break; 346 case Instruction::APUT: 347 GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2); 348 break; 349 case Instruction::APUT_OBJECT: 350 GenArrayObjPut(opt_flags, rl_src[1], rl_src[2], rl_src[0], 2); 351 break; 352 case Instruction::APUT_SHORT: 353 case Instruction::APUT_CHAR: 354 GenArrayPut(opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1); 355 break; 356 case Instruction::APUT_BYTE: 357 case Instruction::APUT_BOOLEAN: 358 GenArrayPut(opt_flags, kUnsignedByte, rl_src[1], rl_src[2], 359 rl_src[0], 0); 360 break; 361 362 case Instruction::IGET_OBJECT: 363 GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, true); 364 break; 365 366 case Instruction::IGET_WIDE: 367 GenIGet(vC, opt_flags, kLong, rl_dest, rl_src[0], true, false); 368 break; 369 370 case Instruction::IGET: 371 GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, false); 372 break; 373 374 case Instruction::IGET_CHAR: 375 GenIGet(vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false); 376 break; 377 378 case Instruction::IGET_SHORT: 379 GenIGet(vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false); 380 break; 381 382 case Instruction::IGET_BOOLEAN: 383 case Instruction::IGET_BYTE: 384 GenIGet(vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false); 385 break; 386 387 case Instruction::IPUT_WIDE: 388 GenIPut(vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false); 389 break; 390 391 case Instruction::IPUT_OBJECT: 392 GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true); 393 break; 394 395 case Instruction::IPUT: 396 GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false); 397 break; 398 399 case Instruction::IPUT_BOOLEAN: 400 case Instruction::IPUT_BYTE: 401 GenIPut(vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false); 402 break; 403 404 case Instruction::IPUT_CHAR: 405 GenIPut(vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false); 406 break; 407 408 case Instruction::IPUT_SHORT: 409 GenIPut(vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false); 410 break; 411 412 case Instruction::SGET_OBJECT: 413 GenSget(vB, rl_dest, false, true); 414 break; 415 case Instruction::SGET: 416 case Instruction::SGET_BOOLEAN: 417 case Instruction::SGET_BYTE: 418 case Instruction::SGET_CHAR: 419 case Instruction::SGET_SHORT: 420 GenSget(vB, rl_dest, false, false); 421 break; 422 423 case Instruction::SGET_WIDE: 424 GenSget(vB, rl_dest, true, false); 425 break; 426 427 case Instruction::SPUT_OBJECT: 428 GenSput(vB, rl_src[0], false, true); 429 break; 430 431 case Instruction::SPUT: 432 case Instruction::SPUT_BOOLEAN: 433 case Instruction::SPUT_BYTE: 434 case Instruction::SPUT_CHAR: 435 case Instruction::SPUT_SHORT: 436 GenSput(vB, rl_src[0], false, false); 437 break; 438 439 case Instruction::SPUT_WIDE: 440 GenSput(vB, rl_src[0], true, false); 441 break; 442 443 case Instruction::INVOKE_STATIC_RANGE: 444 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, true)); 445 break; 446 case Instruction::INVOKE_STATIC: 447 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, false)); 448 break; 449 450 case Instruction::INVOKE_DIRECT: 451 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, false)); 452 break; 453 case Instruction::INVOKE_DIRECT_RANGE: 454 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, true)); 455 break; 456 457 case Instruction::INVOKE_VIRTUAL: 458 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, false)); 459 break; 460 case Instruction::INVOKE_VIRTUAL_RANGE: 461 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, true)); 462 break; 463 464 case Instruction::INVOKE_SUPER: 465 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, false)); 466 break; 467 case Instruction::INVOKE_SUPER_RANGE: 468 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, true)); 469 break; 470 471 case Instruction::INVOKE_INTERFACE: 472 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, false)); 473 break; 474 case Instruction::INVOKE_INTERFACE_RANGE: 475 GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, true)); 476 break; 477 478 case Instruction::NEG_INT: 479 case Instruction::NOT_INT: 480 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0]); 481 break; 482 483 case Instruction::NEG_LONG: 484 case Instruction::NOT_LONG: 485 GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0]); 486 break; 487 488 case Instruction::NEG_FLOAT: 489 GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[0]); 490 break; 491 492 case Instruction::NEG_DOUBLE: 493 GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[0]); 494 break; 495 496 case Instruction::INT_TO_LONG: 497 GenIntToLong(rl_dest, rl_src[0]); 498 break; 499 500 case Instruction::LONG_TO_INT: 501 rl_src[0] = UpdateLocWide(rl_src[0]); 502 rl_src[0] = WideToNarrow(rl_src[0]); 503 StoreValue(rl_dest, rl_src[0]); 504 break; 505 506 case Instruction::INT_TO_BYTE: 507 case Instruction::INT_TO_SHORT: 508 case Instruction::INT_TO_CHAR: 509 GenIntNarrowing(opcode, rl_dest, rl_src[0]); 510 break; 511 512 case Instruction::INT_TO_FLOAT: 513 case Instruction::INT_TO_DOUBLE: 514 case Instruction::LONG_TO_FLOAT: 515 case Instruction::LONG_TO_DOUBLE: 516 case Instruction::FLOAT_TO_INT: 517 case Instruction::FLOAT_TO_LONG: 518 case Instruction::FLOAT_TO_DOUBLE: 519 case Instruction::DOUBLE_TO_INT: 520 case Instruction::DOUBLE_TO_LONG: 521 case Instruction::DOUBLE_TO_FLOAT: 522 GenConversion(opcode, rl_dest, rl_src[0]); 523 break; 524 525 526 case Instruction::ADD_INT: 527 case Instruction::ADD_INT_2ADDR: 528 case Instruction::MUL_INT: 529 case Instruction::MUL_INT_2ADDR: 530 case Instruction::AND_INT: 531 case Instruction::AND_INT_2ADDR: 532 case Instruction::OR_INT: 533 case Instruction::OR_INT_2ADDR: 534 case Instruction::XOR_INT: 535 case Instruction::XOR_INT_2ADDR: 536 if (rl_src[0].is_const && 537 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[0]))) { 538 GenArithOpIntLit(opcode, rl_dest, rl_src[1], 539 mir_graph_->ConstantValue(rl_src[0].orig_sreg)); 540 } else if (rl_src[1].is_const && 541 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) { 542 GenArithOpIntLit(opcode, rl_dest, rl_src[0], 543 mir_graph_->ConstantValue(rl_src[1].orig_sreg)); 544 } else { 545 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]); 546 } 547 break; 548 549 case Instruction::SUB_INT: 550 case Instruction::SUB_INT_2ADDR: 551 case Instruction::DIV_INT: 552 case Instruction::DIV_INT_2ADDR: 553 case Instruction::REM_INT: 554 case Instruction::REM_INT_2ADDR: 555 case Instruction::SHL_INT: 556 case Instruction::SHL_INT_2ADDR: 557 case Instruction::SHR_INT: 558 case Instruction::SHR_INT_2ADDR: 559 case Instruction::USHR_INT: 560 case Instruction::USHR_INT_2ADDR: 561 if (rl_src[1].is_const && 562 InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) { 563 GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1])); 564 } else { 565 GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]); 566 } 567 break; 568 569 case Instruction::ADD_LONG: 570 case Instruction::SUB_LONG: 571 case Instruction::AND_LONG: 572 case Instruction::OR_LONG: 573 case Instruction::XOR_LONG: 574 case Instruction::ADD_LONG_2ADDR: 575 case Instruction::SUB_LONG_2ADDR: 576 case Instruction::AND_LONG_2ADDR: 577 case Instruction::OR_LONG_2ADDR: 578 case Instruction::XOR_LONG_2ADDR: 579 if (rl_src[0].is_const || rl_src[1].is_const) { 580 GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); 581 break; 582 } 583 // Note: intentional fallthrough. 584 585 case Instruction::MUL_LONG: 586 case Instruction::DIV_LONG: 587 case Instruction::REM_LONG: 588 case Instruction::MUL_LONG_2ADDR: 589 case Instruction::DIV_LONG_2ADDR: 590 case Instruction::REM_LONG_2ADDR: 591 GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); 592 break; 593 594 case Instruction::SHL_LONG: 595 case Instruction::SHR_LONG: 596 case Instruction::USHR_LONG: 597 case Instruction::SHL_LONG_2ADDR: 598 case Instruction::SHR_LONG_2ADDR: 599 case Instruction::USHR_LONG_2ADDR: 600 if (rl_src[1].is_const) { 601 GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); 602 } else { 603 GenShiftOpLong(opcode, rl_dest, rl_src[0], rl_src[1]); 604 } 605 break; 606 607 case Instruction::ADD_FLOAT: 608 case Instruction::SUB_FLOAT: 609 case Instruction::MUL_FLOAT: 610 case Instruction::DIV_FLOAT: 611 case Instruction::REM_FLOAT: 612 case Instruction::ADD_FLOAT_2ADDR: 613 case Instruction::SUB_FLOAT_2ADDR: 614 case Instruction::MUL_FLOAT_2ADDR: 615 case Instruction::DIV_FLOAT_2ADDR: 616 case Instruction::REM_FLOAT_2ADDR: 617 GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[1]); 618 break; 619 620 case Instruction::ADD_DOUBLE: 621 case Instruction::SUB_DOUBLE: 622 case Instruction::MUL_DOUBLE: 623 case Instruction::DIV_DOUBLE: 624 case Instruction::REM_DOUBLE: 625 case Instruction::ADD_DOUBLE_2ADDR: 626 case Instruction::SUB_DOUBLE_2ADDR: 627 case Instruction::MUL_DOUBLE_2ADDR: 628 case Instruction::DIV_DOUBLE_2ADDR: 629 case Instruction::REM_DOUBLE_2ADDR: 630 GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[1]); 631 break; 632 633 case Instruction::RSUB_INT: 634 case Instruction::ADD_INT_LIT16: 635 case Instruction::MUL_INT_LIT16: 636 case Instruction::DIV_INT_LIT16: 637 case Instruction::REM_INT_LIT16: 638 case Instruction::AND_INT_LIT16: 639 case Instruction::OR_INT_LIT16: 640 case Instruction::XOR_INT_LIT16: 641 case Instruction::ADD_INT_LIT8: 642 case Instruction::RSUB_INT_LIT8: 643 case Instruction::MUL_INT_LIT8: 644 case Instruction::DIV_INT_LIT8: 645 case Instruction::REM_INT_LIT8: 646 case Instruction::AND_INT_LIT8: 647 case Instruction::OR_INT_LIT8: 648 case Instruction::XOR_INT_LIT8: 649 case Instruction::SHL_INT_LIT8: 650 case Instruction::SHR_INT_LIT8: 651 case Instruction::USHR_INT_LIT8: 652 GenArithOpIntLit(opcode, rl_dest, rl_src[0], vC); 653 break; 654 655 default: 656 LOG(FATAL) << "Unexpected opcode: " << opcode; 657 } 658} 659 660// Process extended MIR instructions 661void Mir2Lir::HandleExtendedMethodMIR(BasicBlock* bb, MIR* mir) { 662 switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) { 663 case kMirOpCopy: { 664 RegLocation rl_src = mir_graph_->GetSrc(mir, 0); 665 RegLocation rl_dest = mir_graph_->GetDest(mir); 666 StoreValue(rl_dest, rl_src); 667 break; 668 } 669 case kMirOpFusedCmplFloat: 670 GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, false /*double*/); 671 break; 672 case kMirOpFusedCmpgFloat: 673 GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, false /*double*/); 674 break; 675 case kMirOpFusedCmplDouble: 676 GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, true /*double*/); 677 break; 678 case kMirOpFusedCmpgDouble: 679 GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, true /*double*/); 680 break; 681 case kMirOpFusedCmpLong: 682 GenFusedLongCmpBranch(bb, mir); 683 break; 684 case kMirOpSelect: 685 GenSelect(bb, mir); 686 break; 687 default: 688 break; 689 } 690} 691 692// Handle the content in each basic block. 693bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) { 694 if (bb->block_type == kDead) return false; 695 current_dalvik_offset_ = bb->start_offset; 696 MIR* mir; 697 int block_id = bb->id; 698 699 block_label_list_[block_id].operands[0] = bb->start_offset; 700 701 // Insert the block label. 702 block_label_list_[block_id].opcode = kPseudoNormalBlockLabel; 703 AppendLIR(&block_label_list_[block_id]); 704 705 LIR* head_lir = NULL; 706 707 // If this is a catch block, export the start address. 708 if (bb->catch_entry) { 709 head_lir = NewLIR0(kPseudoExportedPC); 710 } 711 712 // Free temp registers and reset redundant store tracking. 713 ResetRegPool(); 714 ResetDefTracking(); 715 716 ClobberAllRegs(); 717 718 if (bb->block_type == kEntryBlock) { 719 int start_vreg = cu_->num_dalvik_registers - cu_->num_ins; 720 GenEntrySequence(&mir_graph_->reg_location_[start_vreg], 721 mir_graph_->reg_location_[mir_graph_->GetMethodSReg()]); 722 } else if (bb->block_type == kExitBlock) { 723 GenExitSequence(); 724 } 725 726 for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { 727 ResetRegPool(); 728 if (cu_->disable_opt & (1 << kTrackLiveTemps)) { 729 ClobberAllRegs(); 730 } 731 732 if (cu_->disable_opt & (1 << kSuppressLoads)) { 733 ResetDefTracking(); 734 } 735 736 // Reset temp tracking sanity check. 737 if (kIsDebugBuild) { 738 live_sreg_ = INVALID_SREG; 739 } 740 741 current_dalvik_offset_ = mir->offset; 742 int opcode = mir->dalvikInsn.opcode; 743 LIR* boundary_lir; 744 745 // Mark the beginning of a Dalvik instruction for line tracking. 746 char* inst_str = cu_->verbose ? 747 mir_graph_->GetDalvikDisassembly(mir) : NULL; 748 boundary_lir = MarkBoundary(mir->offset, inst_str); 749 // Remember the first LIR for this block. 750 if (head_lir == NULL) { 751 head_lir = boundary_lir; 752 // Set the first boundary_lir as a scheduling barrier. 753 head_lir->def_mask = ENCODE_ALL; 754 } 755 756 if (opcode == kMirOpCheck) { 757 // Combine check and work halves of throwing instruction. 758 MIR* work_half = mir->meta.throw_insn; 759 mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode; 760 opcode = work_half->dalvikInsn.opcode; 761 SSARepresentation* ssa_rep = work_half->ssa_rep; 762 work_half->ssa_rep = mir->ssa_rep; 763 mir->ssa_rep = ssa_rep; 764 work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2); 765 } 766 767 if (opcode >= kMirOpFirst) { 768 HandleExtendedMethodMIR(bb, mir); 769 continue; 770 } 771 772 CompileDalvikInstruction(mir, bb, block_label_list_); 773 } 774 775 if (head_lir) { 776 // Eliminate redundant loads/stores and delay stores into later slots. 777 ApplyLocalOptimizations(head_lir, last_lir_insn_); 778 779 // Generate an unconditional branch to the fallthrough block. 780 if (bb->fall_through) { 781 OpUnconditionalBranch(&block_label_list_[bb->fall_through->id]); 782 } 783 } 784 return false; 785} 786 787void Mir2Lir::SpecialMIR2LIR(SpecialCaseHandler special_case) { 788 // Find the first DalvikByteCode block. 789 int num_reachable_blocks = mir_graph_->GetNumReachableBlocks(); 790 BasicBlock*bb = NULL; 791 for (int idx = 0; idx < num_reachable_blocks; idx++) { 792 // TODO: no direct access of growable lists. 793 int dfs_index = mir_graph_->GetDfsOrder()->Get(idx); 794 bb = mir_graph_->GetBasicBlock(dfs_index); 795 if (bb->block_type == kDalvikByteCode) { 796 break; 797 } 798 } 799 if (bb == NULL) { 800 return; 801 } 802 DCHECK_EQ(bb->start_offset, 0); 803 DCHECK(bb->first_mir_insn != NULL); 804 805 // Get the first instruction. 806 MIR* mir = bb->first_mir_insn; 807 808 // Free temp registers and reset redundant store tracking. 809 ResetRegPool(); 810 ResetDefTracking(); 811 ClobberAllRegs(); 812 813 GenSpecialCase(bb, mir, special_case); 814} 815 816void Mir2Lir::MethodMIR2LIR() { 817 // Hold the labels of each block. 818 block_label_list_ = 819 static_cast<LIR*>(arena_->NewMem(sizeof(LIR) * mir_graph_->GetNumBlocks(), true, 820 ArenaAllocator::kAllocLIR)); 821 822 PreOrderDfsIterator iter(mir_graph_, false /* not iterative */); 823 for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) { 824 MethodBlockCodeGen(bb); 825 } 826 827 HandleSuspendLaunchPads(); 828 829 HandleThrowLaunchPads(); 830 831 HandleIntrinsicLaunchPads(); 832 833 if (!(cu_->disable_opt & (1 << kSafeOptimizations))) { 834 RemoveRedundantBranches(); 835 } 836} 837 838} // namespace art 839