Home | History | Annotate | Download | only in quick
      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 
     22 namespace 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  */
     29 void 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 (mir_graph_->IsBackedge(bb, bb->taken)) {
    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       // Result known at compile time?
    277       if (rl_src[0].is_const && rl_src[1].is_const) {
    278         bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg),
    279                                        mir_graph_->ConstantValue(rl_src[1].orig_sreg));
    280         BasicBlock* target = is_taken ? bb->taken : bb->fall_through;
    281         if (mir_graph_->IsBackedge(bb, target)) {
    282           GenSuspendTest(opt_flags);
    283         }
    284         OpUnconditionalBranch(&label_list[target->id]);
    285       } else {
    286         if (mir_graph_->IsBackwardsBranch(bb)) {
    287           GenSuspendTest(opt_flags);
    288         }
    289         GenCompareAndBranch(opcode, rl_src[0], rl_src[1], taken,
    290                                 fall_through);
    291       }
    292       break;
    293       }
    294 
    295     case Instruction::IF_EQZ:
    296     case Instruction::IF_NEZ:
    297     case Instruction::IF_LTZ:
    298     case Instruction::IF_GEZ:
    299     case Instruction::IF_GTZ:
    300     case Instruction::IF_LEZ: {
    301       LIR* taken = &label_list[bb->taken->id];
    302       LIR* fall_through = &label_list[bb->fall_through->id];
    303       // Result known at compile time?
    304       if (rl_src[0].is_const) {
    305         bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg), 0);
    306         BasicBlock* target = is_taken ? bb->taken : bb->fall_through;
    307         if (mir_graph_->IsBackedge(bb, target)) {
    308           GenSuspendTest(opt_flags);
    309         }
    310         OpUnconditionalBranch(&label_list[target->id]);
    311       } else {
    312         if (mir_graph_->IsBackwardsBranch(bb)) {
    313           GenSuspendTest(opt_flags);
    314         }
    315         GenCompareZeroAndBranch(opcode, rl_src[0], taken, fall_through);
    316       }
    317       break;
    318       }
    319 
    320     case Instruction::AGET_WIDE:
    321       GenArrayGet(opt_flags, kLong, rl_src[0], rl_src[1], rl_dest, 3);
    322       break;
    323     case Instruction::AGET:
    324     case Instruction::AGET_OBJECT:
    325       GenArrayGet(opt_flags, kWord, rl_src[0], rl_src[1], rl_dest, 2);
    326       break;
    327     case Instruction::AGET_BOOLEAN:
    328       GenArrayGet(opt_flags, kUnsignedByte, rl_src[0], rl_src[1], rl_dest, 0);
    329       break;
    330     case Instruction::AGET_BYTE:
    331       GenArrayGet(opt_flags, kSignedByte, rl_src[0], rl_src[1], rl_dest, 0);
    332       break;
    333     case Instruction::AGET_CHAR:
    334       GenArrayGet(opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
    335       break;
    336     case Instruction::AGET_SHORT:
    337       GenArrayGet(opt_flags, kSignedHalf, rl_src[0], rl_src[1], rl_dest, 1);
    338       break;
    339     case Instruction::APUT_WIDE:
    340       GenArrayPut(opt_flags, kLong, rl_src[1], rl_src[2], rl_src[0], 3);
    341       break;
    342     case Instruction::APUT:
    343       GenArrayPut(opt_flags, kWord, rl_src[1], rl_src[2], rl_src[0], 2);
    344       break;
    345     case Instruction::APUT_OBJECT:
    346       GenArrayObjPut(opt_flags, rl_src[1], rl_src[2], rl_src[0], 2);
    347       break;
    348     case Instruction::APUT_SHORT:
    349     case Instruction::APUT_CHAR:
    350       GenArrayPut(opt_flags, kUnsignedHalf, rl_src[1], rl_src[2], rl_src[0], 1);
    351       break;
    352     case Instruction::APUT_BYTE:
    353     case Instruction::APUT_BOOLEAN:
    354       GenArrayPut(opt_flags, kUnsignedByte, rl_src[1], rl_src[2],
    355             rl_src[0], 0);
    356       break;
    357 
    358     case Instruction::IGET_OBJECT:
    359       GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, true);
    360       break;
    361 
    362     case Instruction::IGET_WIDE:
    363       GenIGet(vC, opt_flags, kLong, rl_dest, rl_src[0], true, false);
    364       break;
    365 
    366     case Instruction::IGET:
    367       GenIGet(vC, opt_flags, kWord, rl_dest, rl_src[0], false, false);
    368       break;
    369 
    370     case Instruction::IGET_CHAR:
    371       GenIGet(vC, opt_flags, kUnsignedHalf, rl_dest, rl_src[0], false, false);
    372       break;
    373 
    374     case Instruction::IGET_SHORT:
    375       GenIGet(vC, opt_flags, kSignedHalf, rl_dest, rl_src[0], false, false);
    376       break;
    377 
    378     case Instruction::IGET_BOOLEAN:
    379     case Instruction::IGET_BYTE:
    380       GenIGet(vC, opt_flags, kUnsignedByte, rl_dest, rl_src[0], false, false);
    381       break;
    382 
    383     case Instruction::IPUT_WIDE:
    384       GenIPut(vC, opt_flags, kLong, rl_src[0], rl_src[1], true, false);
    385       break;
    386 
    387     case Instruction::IPUT_OBJECT:
    388       GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, true);
    389       break;
    390 
    391     case Instruction::IPUT:
    392       GenIPut(vC, opt_flags, kWord, rl_src[0], rl_src[1], false, false);
    393       break;
    394 
    395     case Instruction::IPUT_BOOLEAN:
    396     case Instruction::IPUT_BYTE:
    397       GenIPut(vC, opt_flags, kUnsignedByte, rl_src[0], rl_src[1], false, false);
    398       break;
    399 
    400     case Instruction::IPUT_CHAR:
    401       GenIPut(vC, opt_flags, kUnsignedHalf, rl_src[0], rl_src[1], false, false);
    402       break;
    403 
    404     case Instruction::IPUT_SHORT:
    405       GenIPut(vC, opt_flags, kSignedHalf, rl_src[0], rl_src[1], false, false);
    406       break;
    407 
    408     case Instruction::SGET_OBJECT:
    409       GenSget(vB, rl_dest, false, true);
    410       break;
    411     case Instruction::SGET:
    412     case Instruction::SGET_BOOLEAN:
    413     case Instruction::SGET_BYTE:
    414     case Instruction::SGET_CHAR:
    415     case Instruction::SGET_SHORT:
    416       GenSget(vB, rl_dest, false, false);
    417       break;
    418 
    419     case Instruction::SGET_WIDE:
    420       GenSget(vB, rl_dest, true, false);
    421       break;
    422 
    423     case Instruction::SPUT_OBJECT:
    424       GenSput(vB, rl_src[0], false, true);
    425       break;
    426 
    427     case Instruction::SPUT:
    428     case Instruction::SPUT_BOOLEAN:
    429     case Instruction::SPUT_BYTE:
    430     case Instruction::SPUT_CHAR:
    431     case Instruction::SPUT_SHORT:
    432       GenSput(vB, rl_src[0], false, false);
    433       break;
    434 
    435     case Instruction::SPUT_WIDE:
    436       GenSput(vB, rl_src[0], true, false);
    437       break;
    438 
    439     case Instruction::INVOKE_STATIC_RANGE:
    440       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, true));
    441       break;
    442     case Instruction::INVOKE_STATIC:
    443       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kStatic, false));
    444       break;
    445 
    446     case Instruction::INVOKE_DIRECT:
    447       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, false));
    448       break;
    449     case Instruction::INVOKE_DIRECT_RANGE:
    450       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kDirect, true));
    451       break;
    452 
    453     case Instruction::INVOKE_VIRTUAL:
    454       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, false));
    455       break;
    456     case Instruction::INVOKE_VIRTUAL_RANGE:
    457       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kVirtual, true));
    458       break;
    459 
    460     case Instruction::INVOKE_SUPER:
    461       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, false));
    462       break;
    463     case Instruction::INVOKE_SUPER_RANGE:
    464       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kSuper, true));
    465       break;
    466 
    467     case Instruction::INVOKE_INTERFACE:
    468       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, false));
    469       break;
    470     case Instruction::INVOKE_INTERFACE_RANGE:
    471       GenInvoke(mir_graph_->NewMemCallInfo(bb, mir, kInterface, true));
    472       break;
    473 
    474     case Instruction::NEG_INT:
    475     case Instruction::NOT_INT:
    476       GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[0]);
    477       break;
    478 
    479     case Instruction::NEG_LONG:
    480     case Instruction::NOT_LONG:
    481       GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[0]);
    482       break;
    483 
    484     case Instruction::NEG_FLOAT:
    485       GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[0]);
    486       break;
    487 
    488     case Instruction::NEG_DOUBLE:
    489       GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[0]);
    490       break;
    491 
    492     case Instruction::INT_TO_LONG:
    493       GenIntToLong(rl_dest, rl_src[0]);
    494       break;
    495 
    496     case Instruction::LONG_TO_INT:
    497       rl_src[0] = UpdateLocWide(rl_src[0]);
    498       rl_src[0] = WideToNarrow(rl_src[0]);
    499       StoreValue(rl_dest, rl_src[0]);
    500       break;
    501 
    502     case Instruction::INT_TO_BYTE:
    503     case Instruction::INT_TO_SHORT:
    504     case Instruction::INT_TO_CHAR:
    505       GenIntNarrowing(opcode, rl_dest, rl_src[0]);
    506       break;
    507 
    508     case Instruction::INT_TO_FLOAT:
    509     case Instruction::INT_TO_DOUBLE:
    510     case Instruction::LONG_TO_FLOAT:
    511     case Instruction::LONG_TO_DOUBLE:
    512     case Instruction::FLOAT_TO_INT:
    513     case Instruction::FLOAT_TO_LONG:
    514     case Instruction::FLOAT_TO_DOUBLE:
    515     case Instruction::DOUBLE_TO_INT:
    516     case Instruction::DOUBLE_TO_LONG:
    517     case Instruction::DOUBLE_TO_FLOAT:
    518       GenConversion(opcode, rl_dest, rl_src[0]);
    519       break;
    520 
    521 
    522     case Instruction::ADD_INT:
    523     case Instruction::ADD_INT_2ADDR:
    524     case Instruction::MUL_INT:
    525     case Instruction::MUL_INT_2ADDR:
    526     case Instruction::AND_INT:
    527     case Instruction::AND_INT_2ADDR:
    528     case Instruction::OR_INT:
    529     case Instruction::OR_INT_2ADDR:
    530     case Instruction::XOR_INT:
    531     case Instruction::XOR_INT_2ADDR:
    532       if (rl_src[0].is_const &&
    533           InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[0]))) {
    534         GenArithOpIntLit(opcode, rl_dest, rl_src[1],
    535                              mir_graph_->ConstantValue(rl_src[0].orig_sreg));
    536       } else if (rl_src[1].is_const &&
    537           InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) {
    538         GenArithOpIntLit(opcode, rl_dest, rl_src[0],
    539                              mir_graph_->ConstantValue(rl_src[1].orig_sreg));
    540       } else {
    541         GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
    542       }
    543       break;
    544 
    545     case Instruction::SUB_INT:
    546     case Instruction::SUB_INT_2ADDR:
    547     case Instruction::DIV_INT:
    548     case Instruction::DIV_INT_2ADDR:
    549     case Instruction::REM_INT:
    550     case Instruction::REM_INT_2ADDR:
    551     case Instruction::SHL_INT:
    552     case Instruction::SHL_INT_2ADDR:
    553     case Instruction::SHR_INT:
    554     case Instruction::SHR_INT_2ADDR:
    555     case Instruction::USHR_INT:
    556     case Instruction::USHR_INT_2ADDR:
    557       if (rl_src[1].is_const &&
    558           InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src[1]))) {
    559         GenArithOpIntLit(opcode, rl_dest, rl_src[0], mir_graph_->ConstantValue(rl_src[1]));
    560       } else {
    561         GenArithOpInt(opcode, rl_dest, rl_src[0], rl_src[1]);
    562       }
    563       break;
    564 
    565     case Instruction::ADD_LONG:
    566     case Instruction::SUB_LONG:
    567     case Instruction::AND_LONG:
    568     case Instruction::OR_LONG:
    569     case Instruction::XOR_LONG:
    570     case Instruction::ADD_LONG_2ADDR:
    571     case Instruction::SUB_LONG_2ADDR:
    572     case Instruction::AND_LONG_2ADDR:
    573     case Instruction::OR_LONG_2ADDR:
    574     case Instruction::XOR_LONG_2ADDR:
    575       if (rl_src[0].is_const || rl_src[1].is_const) {
    576         GenArithImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
    577         break;
    578       }
    579       // Note: intentional fallthrough.
    580 
    581     case Instruction::MUL_LONG:
    582     case Instruction::DIV_LONG:
    583     case Instruction::REM_LONG:
    584     case Instruction::MUL_LONG_2ADDR:
    585     case Instruction::DIV_LONG_2ADDR:
    586     case Instruction::REM_LONG_2ADDR:
    587       GenArithOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
    588       break;
    589 
    590     case Instruction::SHL_LONG:
    591     case Instruction::SHR_LONG:
    592     case Instruction::USHR_LONG:
    593     case Instruction::SHL_LONG_2ADDR:
    594     case Instruction::SHR_LONG_2ADDR:
    595     case Instruction::USHR_LONG_2ADDR:
    596       if (rl_src[1].is_const) {
    597         GenShiftImmOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
    598       } else {
    599         GenShiftOpLong(opcode, rl_dest, rl_src[0], rl_src[1]);
    600       }
    601       break;
    602 
    603     case Instruction::ADD_FLOAT:
    604     case Instruction::SUB_FLOAT:
    605     case Instruction::MUL_FLOAT:
    606     case Instruction::DIV_FLOAT:
    607     case Instruction::REM_FLOAT:
    608     case Instruction::ADD_FLOAT_2ADDR:
    609     case Instruction::SUB_FLOAT_2ADDR:
    610     case Instruction::MUL_FLOAT_2ADDR:
    611     case Instruction::DIV_FLOAT_2ADDR:
    612     case Instruction::REM_FLOAT_2ADDR:
    613       GenArithOpFloat(opcode, rl_dest, rl_src[0], rl_src[1]);
    614       break;
    615 
    616     case Instruction::ADD_DOUBLE:
    617     case Instruction::SUB_DOUBLE:
    618     case Instruction::MUL_DOUBLE:
    619     case Instruction::DIV_DOUBLE:
    620     case Instruction::REM_DOUBLE:
    621     case Instruction::ADD_DOUBLE_2ADDR:
    622     case Instruction::SUB_DOUBLE_2ADDR:
    623     case Instruction::MUL_DOUBLE_2ADDR:
    624     case Instruction::DIV_DOUBLE_2ADDR:
    625     case Instruction::REM_DOUBLE_2ADDR:
    626       GenArithOpDouble(opcode, rl_dest, rl_src[0], rl_src[1]);
    627       break;
    628 
    629     case Instruction::RSUB_INT:
    630     case Instruction::ADD_INT_LIT16:
    631     case Instruction::MUL_INT_LIT16:
    632     case Instruction::DIV_INT_LIT16:
    633     case Instruction::REM_INT_LIT16:
    634     case Instruction::AND_INT_LIT16:
    635     case Instruction::OR_INT_LIT16:
    636     case Instruction::XOR_INT_LIT16:
    637     case Instruction::ADD_INT_LIT8:
    638     case Instruction::RSUB_INT_LIT8:
    639     case Instruction::MUL_INT_LIT8:
    640     case Instruction::DIV_INT_LIT8:
    641     case Instruction::REM_INT_LIT8:
    642     case Instruction::AND_INT_LIT8:
    643     case Instruction::OR_INT_LIT8:
    644     case Instruction::XOR_INT_LIT8:
    645     case Instruction::SHL_INT_LIT8:
    646     case Instruction::SHR_INT_LIT8:
    647     case Instruction::USHR_INT_LIT8:
    648       GenArithOpIntLit(opcode, rl_dest, rl_src[0], vC);
    649       break;
    650 
    651     default:
    652       LOG(FATAL) << "Unexpected opcode: " << opcode;
    653   }
    654 }  // NOLINT(readability/fn_size)
    655 
    656 // Process extended MIR instructions
    657 void Mir2Lir::HandleExtendedMethodMIR(BasicBlock* bb, MIR* mir) {
    658   switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
    659     case kMirOpCopy: {
    660       RegLocation rl_src = mir_graph_->GetSrc(mir, 0);
    661       RegLocation rl_dest = mir_graph_->GetDest(mir);
    662       StoreValue(rl_dest, rl_src);
    663       break;
    664     }
    665     case kMirOpFusedCmplFloat:
    666       GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, false /*double*/);
    667       break;
    668     case kMirOpFusedCmpgFloat:
    669       GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, false /*double*/);
    670       break;
    671     case kMirOpFusedCmplDouble:
    672       GenFusedFPCmpBranch(bb, mir, false /*gt bias*/, true /*double*/);
    673       break;
    674     case kMirOpFusedCmpgDouble:
    675       GenFusedFPCmpBranch(bb, mir, true /*gt bias*/, true /*double*/);
    676       break;
    677     case kMirOpFusedCmpLong:
    678       GenFusedLongCmpBranch(bb, mir);
    679       break;
    680     case kMirOpSelect:
    681       GenSelect(bb, mir);
    682       break;
    683     default:
    684       break;
    685   }
    686 }
    687 
    688 // Handle the content in each basic block.
    689 bool Mir2Lir::MethodBlockCodeGen(BasicBlock* bb) {
    690   if (bb->block_type == kDead) return false;
    691   current_dalvik_offset_ = bb->start_offset;
    692   MIR* mir;
    693   int block_id = bb->id;
    694 
    695   block_label_list_[block_id].operands[0] = bb->start_offset;
    696 
    697   // Insert the block label.
    698   block_label_list_[block_id].opcode = kPseudoNormalBlockLabel;
    699   AppendLIR(&block_label_list_[block_id]);
    700 
    701   LIR* head_lir = NULL;
    702 
    703   // If this is a catch block, export the start address.
    704   if (bb->catch_entry) {
    705     head_lir = NewLIR0(kPseudoExportedPC);
    706   }
    707 
    708   // Free temp registers and reset redundant store tracking.
    709   ResetRegPool();
    710   ResetDefTracking();
    711 
    712   ClobberAllRegs();
    713 
    714   if (bb->block_type == kEntryBlock) {
    715     int start_vreg = cu_->num_dalvik_registers - cu_->num_ins;
    716     GenEntrySequence(&mir_graph_->reg_location_[start_vreg],
    717                          mir_graph_->reg_location_[mir_graph_->GetMethodSReg()]);
    718   } else if (bb->block_type == kExitBlock) {
    719     GenExitSequence();
    720   }
    721 
    722   for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
    723     ResetRegPool();
    724     if (cu_->disable_opt & (1 << kTrackLiveTemps)) {
    725       ClobberAllRegs();
    726     }
    727 
    728     if (cu_->disable_opt & (1 << kSuppressLoads)) {
    729       ResetDefTracking();
    730     }
    731 
    732     // Reset temp tracking sanity check.
    733     if (kIsDebugBuild) {
    734       live_sreg_ = INVALID_SREG;
    735     }
    736 
    737     current_dalvik_offset_ = mir->offset;
    738     int opcode = mir->dalvikInsn.opcode;
    739     LIR* boundary_lir;
    740 
    741     // Mark the beginning of a Dalvik instruction for line tracking.
    742     char* inst_str = cu_->verbose ?
    743        mir_graph_->GetDalvikDisassembly(mir) : NULL;
    744     boundary_lir = MarkBoundary(mir->offset, inst_str);
    745     // Remember the first LIR for this block.
    746     if (head_lir == NULL) {
    747       head_lir = boundary_lir;
    748       // Set the first boundary_lir as a scheduling barrier.
    749       head_lir->def_mask = ENCODE_ALL;
    750     }
    751 
    752     if (opcode == kMirOpCheck) {
    753       // Combine check and work halves of throwing instruction.
    754       MIR* work_half = mir->meta.throw_insn;
    755       mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
    756       opcode = work_half->dalvikInsn.opcode;
    757       SSARepresentation* ssa_rep = work_half->ssa_rep;
    758       work_half->ssa_rep = mir->ssa_rep;
    759       mir->ssa_rep = ssa_rep;
    760       work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
    761     }
    762 
    763     if (opcode >= kMirOpFirst) {
    764       HandleExtendedMethodMIR(bb, mir);
    765       continue;
    766     }
    767 
    768     CompileDalvikInstruction(mir, bb, block_label_list_);
    769   }
    770 
    771   if (head_lir) {
    772     // Eliminate redundant loads/stores and delay stores into later slots.
    773     ApplyLocalOptimizations(head_lir, last_lir_insn_);
    774 
    775     // Generate an unconditional branch to the fallthrough block.
    776     if (bb->fall_through) {
    777       OpUnconditionalBranch(&block_label_list_[bb->fall_through->id]);
    778     }
    779   }
    780   return false;
    781 }
    782 
    783 void Mir2Lir::SpecialMIR2LIR(SpecialCaseHandler special_case) {
    784   // Find the first DalvikByteCode block.
    785   int num_reachable_blocks = mir_graph_->GetNumReachableBlocks();
    786   BasicBlock*bb = NULL;
    787   for (int idx = 0; idx < num_reachable_blocks; idx++) {
    788     // TODO: no direct access of growable lists.
    789     int dfs_index = mir_graph_->GetDfsOrder()->Get(idx);
    790     bb = mir_graph_->GetBasicBlock(dfs_index);
    791     if (bb->block_type == kDalvikByteCode) {
    792       break;
    793     }
    794   }
    795   if (bb == NULL) {
    796     return;
    797   }
    798   DCHECK_EQ(bb->start_offset, 0);
    799   DCHECK(bb->first_mir_insn != NULL);
    800 
    801   // Get the first instruction.
    802   MIR* mir = bb->first_mir_insn;
    803 
    804   // Free temp registers and reset redundant store tracking.
    805   ResetRegPool();
    806   ResetDefTracking();
    807   ClobberAllRegs();
    808 
    809   GenSpecialCase(bb, mir, special_case);
    810 }
    811 
    812 void Mir2Lir::MethodMIR2LIR() {
    813   // Hold the labels of each block.
    814   block_label_list_ =
    815       static_cast<LIR*>(arena_->Alloc(sizeof(LIR) * mir_graph_->GetNumBlocks(),
    816                                       ArenaAllocator::kAllocLIR));
    817 
    818   PreOrderDfsIterator iter(mir_graph_, false /* not iterative */);
    819   for (BasicBlock* bb = iter.Next(); bb != NULL; bb = iter.Next()) {
    820     MethodBlockCodeGen(bb);
    821   }
    822 
    823   HandleSuspendLaunchPads();
    824 
    825   HandleThrowLaunchPads();
    826 
    827   HandleIntrinsicLaunchPads();
    828 
    829   if (!(cu_->disable_opt & (1 << kSafeOptimizations))) {
    830     RemoveRedundantBranches();
    831   }
    832 }
    833 
    834 }  // namespace art
    835