Home | History | Annotate | Download | only in arm
      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 "assembler_arm.h"
     18 
     19 #include "base/logging.h"
     20 #include "entrypoints/quick/quick_entrypoints.h"
     21 #include "offsets.h"
     22 #include "thread.h"
     23 #include "utils.h"
     24 
     25 namespace art {
     26 namespace arm {
     27 
     28 // Instruction encoding bits.
     29 enum {
     30   H   = 1 << 5,   // halfword (or byte)
     31   L   = 1 << 20,  // load (or store)
     32   S   = 1 << 20,  // set condition code (or leave unchanged)
     33   W   = 1 << 21,  // writeback base register (or leave unchanged)
     34   A   = 1 << 21,  // accumulate in multiply instruction (or not)
     35   B   = 1 << 22,  // unsigned byte (or word)
     36   N   = 1 << 22,  // long (or short)
     37   U   = 1 << 23,  // positive (or negative) offset/index
     38   P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
     39   I   = 1 << 25,  // immediate shifter operand (or not)
     40 
     41   B0 = 1,
     42   B1 = 1 << 1,
     43   B2 = 1 << 2,
     44   B3 = 1 << 3,
     45   B4 = 1 << 4,
     46   B5 = 1 << 5,
     47   B6 = 1 << 6,
     48   B7 = 1 << 7,
     49   B8 = 1 << 8,
     50   B9 = 1 << 9,
     51   B10 = 1 << 10,
     52   B11 = 1 << 11,
     53   B12 = 1 << 12,
     54   B16 = 1 << 16,
     55   B17 = 1 << 17,
     56   B18 = 1 << 18,
     57   B19 = 1 << 19,
     58   B20 = 1 << 20,
     59   B21 = 1 << 21,
     60   B22 = 1 << 22,
     61   B23 = 1 << 23,
     62   B24 = 1 << 24,
     63   B25 = 1 << 25,
     64   B26 = 1 << 26,
     65   B27 = 1 << 27,
     66 
     67   // Instruction bit masks.
     68   RdMask = 15 << 12,  // in str instruction
     69   CondMask = 15 << 28,
     70   CoprocessorMask = 15 << 8,
     71   OpCodeMask = 15 << 21,  // in data-processing instructions
     72   Imm24Mask = (1 << 24) - 1,
     73   Off12Mask = (1 << 12) - 1,
     74 
     75   // ldrex/strex register field encodings.
     76   kLdExRnShift = 16,
     77   kLdExRtShift = 12,
     78   kStrExRnShift = 16,
     79   kStrExRdShift = 12,
     80   kStrExRtShift = 0,
     81 };
     82 
     83 
     84 static const char* kRegisterNames[] = {
     85   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
     86   "fp", "ip", "sp", "lr", "pc"
     87 };
     88 std::ostream& operator<<(std::ostream& os, const Register& rhs) {
     89   if (rhs >= R0 && rhs <= PC) {
     90     os << kRegisterNames[rhs];
     91   } else {
     92     os << "Register[" << static_cast<int>(rhs) << "]";
     93   }
     94   return os;
     95 }
     96 
     97 
     98 std::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
     99   if (rhs >= S0 && rhs < kNumberOfSRegisters) {
    100     os << "s" << static_cast<int>(rhs);
    101   } else {
    102     os << "SRegister[" << static_cast<int>(rhs) << "]";
    103   }
    104   return os;
    105 }
    106 
    107 
    108 std::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
    109   if (rhs >= D0 && rhs < kNumberOfDRegisters) {
    110     os << "d" << static_cast<int>(rhs);
    111   } else {
    112     os << "DRegister[" << static_cast<int>(rhs) << "]";
    113   }
    114   return os;
    115 }
    116 
    117 
    118 static const char* kConditionNames[] = {
    119   "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT",
    120   "LE", "AL",
    121 };
    122 std::ostream& operator<<(std::ostream& os, const Condition& rhs) {
    123   if (rhs >= EQ && rhs <= AL) {
    124     os << kConditionNames[rhs];
    125   } else {
    126     os << "Condition[" << static_cast<int>(rhs) << "]";
    127   }
    128   return os;
    129 }
    130 
    131 void ArmAssembler::Emit(int32_t value) {
    132   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    133   buffer_.Emit<int32_t>(value);
    134 }
    135 
    136 
    137 void ArmAssembler::EmitType01(Condition cond,
    138                               int type,
    139                               Opcode opcode,
    140                               int set_cc,
    141                               Register rn,
    142                               Register rd,
    143                               ShifterOperand so) {
    144   CHECK_NE(rd, kNoRegister);
    145   CHECK_NE(cond, kNoCondition);
    146   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    147                      type << kTypeShift |
    148                      static_cast<int32_t>(opcode) << kOpcodeShift |
    149                      set_cc << kSShift |
    150                      static_cast<int32_t>(rn) << kRnShift |
    151                      static_cast<int32_t>(rd) << kRdShift |
    152                      so.encoding();
    153   Emit(encoding);
    154 }
    155 
    156 
    157 void ArmAssembler::EmitType5(Condition cond, int offset, bool link) {
    158   CHECK_NE(cond, kNoCondition);
    159   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    160                      5 << kTypeShift |
    161                      (link ? 1 : 0) << kLinkShift;
    162   Emit(ArmAssembler::EncodeBranchOffset(offset, encoding));
    163 }
    164 
    165 
    166 void ArmAssembler::EmitMemOp(Condition cond,
    167                              bool load,
    168                              bool byte,
    169                              Register rd,
    170                              Address ad) {
    171   CHECK_NE(rd, kNoRegister);
    172   CHECK_NE(cond, kNoCondition);
    173   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    174                      B26 |
    175                      (load ? L : 0) |
    176                      (byte ? B : 0) |
    177                      (static_cast<int32_t>(rd) << kRdShift) |
    178                      ad.encoding();
    179   Emit(encoding);
    180 }
    181 
    182 
    183 void ArmAssembler::EmitMemOpAddressMode3(Condition cond,
    184                                          int32_t mode,
    185                                          Register rd,
    186                                          Address ad) {
    187   CHECK_NE(rd, kNoRegister);
    188   CHECK_NE(cond, kNoCondition);
    189   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    190                      B22  |
    191                      mode |
    192                      (static_cast<int32_t>(rd) << kRdShift) |
    193                      ad.encoding3();
    194   Emit(encoding);
    195 }
    196 
    197 
    198 void ArmAssembler::EmitMultiMemOp(Condition cond,
    199                                   BlockAddressMode am,
    200                                   bool load,
    201                                   Register base,
    202                                   RegList regs) {
    203   CHECK_NE(base, kNoRegister);
    204   CHECK_NE(cond, kNoCondition);
    205   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    206                      B27 |
    207                      am |
    208                      (load ? L : 0) |
    209                      (static_cast<int32_t>(base) << kRnShift) |
    210                      regs;
    211   Emit(encoding);
    212 }
    213 
    214 
    215 void ArmAssembler::EmitShiftImmediate(Condition cond,
    216                                       Shift opcode,
    217                                       Register rd,
    218                                       Register rm,
    219                                       ShifterOperand so) {
    220   CHECK_NE(cond, kNoCondition);
    221   CHECK_EQ(so.type(), 1U);
    222   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    223                      static_cast<int32_t>(MOV) << kOpcodeShift |
    224                      static_cast<int32_t>(rd) << kRdShift |
    225                      so.encoding() << kShiftImmShift |
    226                      static_cast<int32_t>(opcode) << kShiftShift |
    227                      static_cast<int32_t>(rm);
    228   Emit(encoding);
    229 }
    230 
    231 
    232 void ArmAssembler::EmitShiftRegister(Condition cond,
    233                                      Shift opcode,
    234                                      Register rd,
    235                                      Register rm,
    236                                      ShifterOperand so) {
    237   CHECK_NE(cond, kNoCondition);
    238   CHECK_EQ(so.type(), 0U);
    239   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    240                      static_cast<int32_t>(MOV) << kOpcodeShift |
    241                      static_cast<int32_t>(rd) << kRdShift |
    242                      so.encoding() << kShiftRegisterShift |
    243                      static_cast<int32_t>(opcode) << kShiftShift |
    244                      B4 |
    245                      static_cast<int32_t>(rm);
    246   Emit(encoding);
    247 }
    248 
    249 
    250 void ArmAssembler::EmitBranch(Condition cond, Label* label, bool link) {
    251   if (label->IsBound()) {
    252     EmitType5(cond, label->Position() - buffer_.Size(), link);
    253   } else {
    254     int position = buffer_.Size();
    255     // Use the offset field of the branch instruction for linking the sites.
    256     EmitType5(cond, label->position_, link);
    257     label->LinkTo(position);
    258   }
    259 }
    260 
    261 void ArmAssembler::and_(Register rd, Register rn, ShifterOperand so,
    262                         Condition cond) {
    263   EmitType01(cond, so.type(), AND, 0, rn, rd, so);
    264 }
    265 
    266 
    267 void ArmAssembler::eor(Register rd, Register rn, ShifterOperand so,
    268                        Condition cond) {
    269   EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
    270 }
    271 
    272 
    273 void ArmAssembler::sub(Register rd, Register rn, ShifterOperand so,
    274                        Condition cond) {
    275   EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
    276 }
    277 
    278 void ArmAssembler::rsb(Register rd, Register rn, ShifterOperand so,
    279                        Condition cond) {
    280   EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
    281 }
    282 
    283 void ArmAssembler::rsbs(Register rd, Register rn, ShifterOperand so,
    284                         Condition cond) {
    285   EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
    286 }
    287 
    288 
    289 void ArmAssembler::add(Register rd, Register rn, ShifterOperand so,
    290                        Condition cond) {
    291   EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
    292 }
    293 
    294 
    295 void ArmAssembler::adds(Register rd, Register rn, ShifterOperand so,
    296                         Condition cond) {
    297   EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
    298 }
    299 
    300 
    301 void ArmAssembler::subs(Register rd, Register rn, ShifterOperand so,
    302                         Condition cond) {
    303   EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
    304 }
    305 
    306 
    307 void ArmAssembler::adc(Register rd, Register rn, ShifterOperand so,
    308                        Condition cond) {
    309   EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
    310 }
    311 
    312 
    313 void ArmAssembler::sbc(Register rd, Register rn, ShifterOperand so,
    314                        Condition cond) {
    315   EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
    316 }
    317 
    318 
    319 void ArmAssembler::rsc(Register rd, Register rn, ShifterOperand so,
    320                        Condition cond) {
    321   EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
    322 }
    323 
    324 
    325 void ArmAssembler::tst(Register rn, ShifterOperand so, Condition cond) {
    326   CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
    327   EmitType01(cond, so.type(), TST, 1, rn, R0, so);
    328 }
    329 
    330 
    331 void ArmAssembler::teq(Register rn, ShifterOperand so, Condition cond) {
    332   CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
    333   EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
    334 }
    335 
    336 
    337 void ArmAssembler::cmp(Register rn, ShifterOperand so, Condition cond) {
    338   EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
    339 }
    340 
    341 
    342 void ArmAssembler::cmn(Register rn, ShifterOperand so, Condition cond) {
    343   EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
    344 }
    345 
    346 
    347 void ArmAssembler::orr(Register rd, Register rn,
    348                     ShifterOperand so, Condition cond) {
    349   EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
    350 }
    351 
    352 
    353 void ArmAssembler::orrs(Register rd, Register rn,
    354                         ShifterOperand so, Condition cond) {
    355   EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
    356 }
    357 
    358 
    359 void ArmAssembler::mov(Register rd, ShifterOperand so, Condition cond) {
    360   EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
    361 }
    362 
    363 
    364 void ArmAssembler::movs(Register rd, ShifterOperand so, Condition cond) {
    365   EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
    366 }
    367 
    368 
    369 void ArmAssembler::bic(Register rd, Register rn, ShifterOperand so,
    370                        Condition cond) {
    371   EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
    372 }
    373 
    374 
    375 void ArmAssembler::mvn(Register rd, ShifterOperand so, Condition cond) {
    376   EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
    377 }
    378 
    379 
    380 void ArmAssembler::mvns(Register rd, ShifterOperand so, Condition cond) {
    381   EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
    382 }
    383 
    384 
    385 void ArmAssembler::clz(Register rd, Register rm, Condition cond) {
    386   CHECK_NE(rd, kNoRegister);
    387   CHECK_NE(rm, kNoRegister);
    388   CHECK_NE(cond, kNoCondition);
    389   CHECK_NE(rd, PC);
    390   CHECK_NE(rm, PC);
    391   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    392                      B24 | B22 | B21 | (0xf << 16) |
    393                      (static_cast<int32_t>(rd) << kRdShift) |
    394                      (0xf << 8) | B4 | static_cast<int32_t>(rm);
    395   Emit(encoding);
    396 }
    397 
    398 
    399 void ArmAssembler::movw(Register rd, uint16_t imm16, Condition cond) {
    400   CHECK_NE(cond, kNoCondition);
    401   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    402                      B25 | B24 | ((imm16 >> 12) << 16) |
    403                      static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
    404   Emit(encoding);
    405 }
    406 
    407 
    408 void ArmAssembler::movt(Register rd, uint16_t imm16, Condition cond) {
    409   CHECK_NE(cond, kNoCondition);
    410   int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
    411                      B25 | B24 | B22 | ((imm16 >> 12) << 16) |
    412                      static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
    413   Emit(encoding);
    414 }
    415 
    416 
    417 void ArmAssembler::EmitMulOp(Condition cond, int32_t opcode,
    418                              Register rd, Register rn,
    419                              Register rm, Register rs) {
    420   CHECK_NE(rd, kNoRegister);
    421   CHECK_NE(rn, kNoRegister);
    422   CHECK_NE(rm, kNoRegister);
    423   CHECK_NE(rs, kNoRegister);
    424   CHECK_NE(cond, kNoCondition);
    425   int32_t encoding = opcode |
    426       (static_cast<int32_t>(cond) << kConditionShift) |
    427       (static_cast<int32_t>(rn) << kRnShift) |
    428       (static_cast<int32_t>(rd) << kRdShift) |
    429       (static_cast<int32_t>(rs) << kRsShift) |
    430       B7 | B4 |
    431       (static_cast<int32_t>(rm) << kRmShift);
    432   Emit(encoding);
    433 }
    434 
    435 
    436 void ArmAssembler::mul(Register rd, Register rn, Register rm, Condition cond) {
    437   // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
    438   EmitMulOp(cond, 0, R0, rd, rn, rm);
    439 }
    440 
    441 
    442 void ArmAssembler::mla(Register rd, Register rn, Register rm, Register ra,
    443                        Condition cond) {
    444   // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
    445   EmitMulOp(cond, B21, ra, rd, rn, rm);
    446 }
    447 
    448 
    449 void ArmAssembler::mls(Register rd, Register rn, Register rm, Register ra,
    450                        Condition cond) {
    451   // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
    452   EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
    453 }
    454 
    455 
    456 void ArmAssembler::umull(Register rd_lo, Register rd_hi, Register rn,
    457                          Register rm, Condition cond) {
    458   // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
    459   EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
    460 }
    461 
    462 
    463 void ArmAssembler::ldr(Register rd, Address ad, Condition cond) {
    464   EmitMemOp(cond, true, false, rd, ad);
    465 }
    466 
    467 
    468 void ArmAssembler::str(Register rd, Address ad, Condition cond) {
    469   EmitMemOp(cond, false, false, rd, ad);
    470 }
    471 
    472 
    473 void ArmAssembler::ldrb(Register rd, Address ad, Condition cond) {
    474   EmitMemOp(cond, true, true, rd, ad);
    475 }
    476 
    477 
    478 void ArmAssembler::strb(Register rd, Address ad, Condition cond) {
    479   EmitMemOp(cond, false, true, rd, ad);
    480 }
    481 
    482 
    483 void ArmAssembler::ldrh(Register rd, Address ad, Condition cond) {
    484   EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
    485 }
    486 
    487 
    488 void ArmAssembler::strh(Register rd, Address ad, Condition cond) {
    489   EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
    490 }
    491 
    492 
    493 void ArmAssembler::ldrsb(Register rd, Address ad, Condition cond) {
    494   EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
    495 }
    496 
    497 
    498 void ArmAssembler::ldrsh(Register rd, Address ad, Condition cond) {
    499   EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
    500 }
    501 
    502 
    503 void ArmAssembler::ldrd(Register rd, Address ad, Condition cond) {
    504   CHECK_EQ(rd % 2, 0);
    505   EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
    506 }
    507 
    508 
    509 void ArmAssembler::strd(Register rd, Address ad, Condition cond) {
    510   CHECK_EQ(rd % 2, 0);
    511   EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
    512 }
    513 
    514 
    515 void ArmAssembler::ldm(BlockAddressMode am,
    516                        Register base,
    517                        RegList regs,
    518                        Condition cond) {
    519   EmitMultiMemOp(cond, am, true, base, regs);
    520 }
    521 
    522 
    523 void ArmAssembler::stm(BlockAddressMode am,
    524                        Register base,
    525                        RegList regs,
    526                        Condition cond) {
    527   EmitMultiMemOp(cond, am, false, base, regs);
    528 }
    529 
    530 
    531 void ArmAssembler::ldrex(Register rt, Register rn, Condition cond) {
    532   CHECK_NE(rn, kNoRegister);
    533   CHECK_NE(rt, kNoRegister);
    534   CHECK_NE(cond, kNoCondition);
    535   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    536                      B24 |
    537                      B23 |
    538                      L   |
    539                      (static_cast<int32_t>(rn) << kLdExRnShift) |
    540                      (static_cast<int32_t>(rt) << kLdExRtShift) |
    541                      B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
    542   Emit(encoding);
    543 }
    544 
    545 
    546 void ArmAssembler::strex(Register rd,
    547                          Register rt,
    548                          Register rn,
    549                          Condition cond) {
    550   CHECK_NE(rn, kNoRegister);
    551   CHECK_NE(rd, kNoRegister);
    552   CHECK_NE(rt, kNoRegister);
    553   CHECK_NE(cond, kNoCondition);
    554   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    555                      B24 |
    556                      B23 |
    557                      (static_cast<int32_t>(rn) << kStrExRnShift) |
    558                      (static_cast<int32_t>(rd) << kStrExRdShift) |
    559                      B11 | B10 | B9 | B8 | B7 | B4 |
    560                      (static_cast<int32_t>(rt) << kStrExRtShift);
    561   Emit(encoding);
    562 }
    563 
    564 
    565 void ArmAssembler::clrex() {
    566   int32_t encoding = (kSpecialCondition << kConditionShift) |
    567                      B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
    568   Emit(encoding);
    569 }
    570 
    571 
    572 void ArmAssembler::nop(Condition cond) {
    573   CHECK_NE(cond, kNoCondition);
    574   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    575                      B25 | B24 | B21 | (0xf << 12);
    576   Emit(encoding);
    577 }
    578 
    579 
    580 void ArmAssembler::vmovsr(SRegister sn, Register rt, Condition cond) {
    581   CHECK_NE(sn, kNoSRegister);
    582   CHECK_NE(rt, kNoRegister);
    583   CHECK_NE(rt, SP);
    584   CHECK_NE(rt, PC);
    585   CHECK_NE(cond, kNoCondition);
    586   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    587                      B27 | B26 | B25 |
    588                      ((static_cast<int32_t>(sn) >> 1)*B16) |
    589                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
    590                      ((static_cast<int32_t>(sn) & 1)*B7) | B4;
    591   Emit(encoding);
    592 }
    593 
    594 
    595 void ArmAssembler::vmovrs(Register rt, SRegister sn, Condition cond) {
    596   CHECK_NE(sn, kNoSRegister);
    597   CHECK_NE(rt, kNoRegister);
    598   CHECK_NE(rt, SP);
    599   CHECK_NE(rt, PC);
    600   CHECK_NE(cond, kNoCondition);
    601   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    602                      B27 | B26 | B25 | B20 |
    603                      ((static_cast<int32_t>(sn) >> 1)*B16) |
    604                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
    605                      ((static_cast<int32_t>(sn) & 1)*B7) | B4;
    606   Emit(encoding);
    607 }
    608 
    609 
    610 void ArmAssembler::vmovsrr(SRegister sm, Register rt, Register rt2,
    611                            Condition cond) {
    612   CHECK_NE(sm, kNoSRegister);
    613   CHECK_NE(sm, S31);
    614   CHECK_NE(rt, kNoRegister);
    615   CHECK_NE(rt, SP);
    616   CHECK_NE(rt, PC);
    617   CHECK_NE(rt2, kNoRegister);
    618   CHECK_NE(rt2, SP);
    619   CHECK_NE(rt2, PC);
    620   CHECK_NE(cond, kNoCondition);
    621   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    622                      B27 | B26 | B22 |
    623                      (static_cast<int32_t>(rt2)*B16) |
    624                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
    625                      ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
    626                      (static_cast<int32_t>(sm) >> 1);
    627   Emit(encoding);
    628 }
    629 
    630 
    631 void ArmAssembler::vmovrrs(Register rt, Register rt2, SRegister sm,
    632                            Condition cond) {
    633   CHECK_NE(sm, kNoSRegister);
    634   CHECK_NE(sm, S31);
    635   CHECK_NE(rt, kNoRegister);
    636   CHECK_NE(rt, SP);
    637   CHECK_NE(rt, PC);
    638   CHECK_NE(rt2, kNoRegister);
    639   CHECK_NE(rt2, SP);
    640   CHECK_NE(rt2, PC);
    641   CHECK_NE(rt, rt2);
    642   CHECK_NE(cond, kNoCondition);
    643   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    644                      B27 | B26 | B22 | B20 |
    645                      (static_cast<int32_t>(rt2)*B16) |
    646                      (static_cast<int32_t>(rt)*B12) | B11 | B9 |
    647                      ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
    648                      (static_cast<int32_t>(sm) >> 1);
    649   Emit(encoding);
    650 }
    651 
    652 
    653 void ArmAssembler::vmovdrr(DRegister dm, Register rt, Register rt2,
    654                            Condition cond) {
    655   CHECK_NE(dm, kNoDRegister);
    656   CHECK_NE(rt, kNoRegister);
    657   CHECK_NE(rt, SP);
    658   CHECK_NE(rt, PC);
    659   CHECK_NE(rt2, kNoRegister);
    660   CHECK_NE(rt2, SP);
    661   CHECK_NE(rt2, PC);
    662   CHECK_NE(cond, kNoCondition);
    663   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    664                      B27 | B26 | B22 |
    665                      (static_cast<int32_t>(rt2)*B16) |
    666                      (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
    667                      ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
    668                      (static_cast<int32_t>(dm) & 0xf);
    669   Emit(encoding);
    670 }
    671 
    672 
    673 void ArmAssembler::vmovrrd(Register rt, Register rt2, DRegister dm,
    674                            Condition cond) {
    675   CHECK_NE(dm, kNoDRegister);
    676   CHECK_NE(rt, kNoRegister);
    677   CHECK_NE(rt, SP);
    678   CHECK_NE(rt, PC);
    679   CHECK_NE(rt2, kNoRegister);
    680   CHECK_NE(rt2, SP);
    681   CHECK_NE(rt2, PC);
    682   CHECK_NE(rt, rt2);
    683   CHECK_NE(cond, kNoCondition);
    684   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    685                      B27 | B26 | B22 | B20 |
    686                      (static_cast<int32_t>(rt2)*B16) |
    687                      (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
    688                      ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
    689                      (static_cast<int32_t>(dm) & 0xf);
    690   Emit(encoding);
    691 }
    692 
    693 
    694 void ArmAssembler::vldrs(SRegister sd, Address ad, Condition cond) {
    695   CHECK_NE(sd, kNoSRegister);
    696   CHECK_NE(cond, kNoCondition);
    697   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    698                      B27 | B26 | B24 | B20 |
    699                      ((static_cast<int32_t>(sd) & 1)*B22) |
    700                      ((static_cast<int32_t>(sd) >> 1)*B12) |
    701                      B11 | B9 | ad.vencoding();
    702   Emit(encoding);
    703 }
    704 
    705 
    706 void ArmAssembler::vstrs(SRegister sd, Address ad, Condition cond) {
    707   CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
    708   CHECK_NE(sd, kNoSRegister);
    709   CHECK_NE(cond, kNoCondition);
    710   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    711                      B27 | B26 | B24 |
    712                      ((static_cast<int32_t>(sd) & 1)*B22) |
    713                      ((static_cast<int32_t>(sd) >> 1)*B12) |
    714                      B11 | B9 | ad.vencoding();
    715   Emit(encoding);
    716 }
    717 
    718 
    719 void ArmAssembler::vldrd(DRegister dd, Address ad, Condition cond) {
    720   CHECK_NE(dd, kNoDRegister);
    721   CHECK_NE(cond, kNoCondition);
    722   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    723                      B27 | B26 | B24 | B20 |
    724                      ((static_cast<int32_t>(dd) >> 4)*B22) |
    725                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
    726                      B11 | B9 | B8 | ad.vencoding();
    727   Emit(encoding);
    728 }
    729 
    730 
    731 void ArmAssembler::vstrd(DRegister dd, Address ad, Condition cond) {
    732   CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
    733   CHECK_NE(dd, kNoDRegister);
    734   CHECK_NE(cond, kNoCondition);
    735   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    736                      B27 | B26 | B24 |
    737                      ((static_cast<int32_t>(dd) >> 4)*B22) |
    738                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
    739                      B11 | B9 | B8 | ad.vencoding();
    740   Emit(encoding);
    741 }
    742 
    743 
    744 void ArmAssembler::EmitVFPsss(Condition cond, int32_t opcode,
    745                               SRegister sd, SRegister sn, SRegister sm) {
    746   CHECK_NE(sd, kNoSRegister);
    747   CHECK_NE(sn, kNoSRegister);
    748   CHECK_NE(sm, kNoSRegister);
    749   CHECK_NE(cond, kNoCondition);
    750   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    751                      B27 | B26 | B25 | B11 | B9 | opcode |
    752                      ((static_cast<int32_t>(sd) & 1)*B22) |
    753                      ((static_cast<int32_t>(sn) >> 1)*B16) |
    754                      ((static_cast<int32_t>(sd) >> 1)*B12) |
    755                      ((static_cast<int32_t>(sn) & 1)*B7) |
    756                      ((static_cast<int32_t>(sm) & 1)*B5) |
    757                      (static_cast<int32_t>(sm) >> 1);
    758   Emit(encoding);
    759 }
    760 
    761 
    762 void ArmAssembler::EmitVFPddd(Condition cond, int32_t opcode,
    763                               DRegister dd, DRegister dn, DRegister dm) {
    764   CHECK_NE(dd, kNoDRegister);
    765   CHECK_NE(dn, kNoDRegister);
    766   CHECK_NE(dm, kNoDRegister);
    767   CHECK_NE(cond, kNoCondition);
    768   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    769                      B27 | B26 | B25 | B11 | B9 | B8 | opcode |
    770                      ((static_cast<int32_t>(dd) >> 4)*B22) |
    771                      ((static_cast<int32_t>(dn) & 0xf)*B16) |
    772                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
    773                      ((static_cast<int32_t>(dn) >> 4)*B7) |
    774                      ((static_cast<int32_t>(dm) >> 4)*B5) |
    775                      (static_cast<int32_t>(dm) & 0xf);
    776   Emit(encoding);
    777 }
    778 
    779 
    780 void ArmAssembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
    781   EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
    782 }
    783 
    784 
    785 void ArmAssembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
    786   EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
    787 }
    788 
    789 
    790 bool ArmAssembler::vmovs(SRegister sd, float s_imm, Condition cond) {
    791   uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
    792   if (((imm32 & ((1 << 19) - 1)) == 0) &&
    793       ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
    794        (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
    795     uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
    796         ((imm32 >> 19) & ((1 << 6) -1));
    797     EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
    798                sd, S0, S0);
    799     return true;
    800   }
    801   return false;
    802 }
    803 
    804 
    805 bool ArmAssembler::vmovd(DRegister dd, double d_imm, Condition cond) {
    806   uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
    807   if (((imm64 & ((1LL << 48) - 1)) == 0) &&
    808       ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
    809        (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
    810     uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
    811         ((imm64 >> 48) & ((1 << 6) -1));
    812     EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
    813                dd, D0, D0);
    814     return true;
    815   }
    816   return false;
    817 }
    818 
    819 
    820 void ArmAssembler::vadds(SRegister sd, SRegister sn, SRegister sm,
    821                          Condition cond) {
    822   EmitVFPsss(cond, B21 | B20, sd, sn, sm);
    823 }
    824 
    825 
    826 void ArmAssembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
    827                          Condition cond) {
    828   EmitVFPddd(cond, B21 | B20, dd, dn, dm);
    829 }
    830 
    831 
    832 void ArmAssembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
    833                          Condition cond) {
    834   EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
    835 }
    836 
    837 
    838 void ArmAssembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
    839                          Condition cond) {
    840   EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
    841 }
    842 
    843 
    844 void ArmAssembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
    845                          Condition cond) {
    846   EmitVFPsss(cond, B21, sd, sn, sm);
    847 }
    848 
    849 
    850 void ArmAssembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
    851                          Condition cond) {
    852   EmitVFPddd(cond, B21, dd, dn, dm);
    853 }
    854 
    855 
    856 void ArmAssembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
    857                          Condition cond) {
    858   EmitVFPsss(cond, 0, sd, sn, sm);
    859 }
    860 
    861 
    862 void ArmAssembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
    863                          Condition cond) {
    864   EmitVFPddd(cond, 0, dd, dn, dm);
    865 }
    866 
    867 
    868 void ArmAssembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
    869                          Condition cond) {
    870   EmitVFPsss(cond, B6, sd, sn, sm);
    871 }
    872 
    873 
    874 void ArmAssembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
    875                          Condition cond) {
    876   EmitVFPddd(cond, B6, dd, dn, dm);
    877 }
    878 
    879 
    880 void ArmAssembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
    881                          Condition cond) {
    882   EmitVFPsss(cond, B23, sd, sn, sm);
    883 }
    884 
    885 
    886 void ArmAssembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
    887                          Condition cond) {
    888   EmitVFPddd(cond, B23, dd, dn, dm);
    889 }
    890 
    891 
    892 void ArmAssembler::vabss(SRegister sd, SRegister sm, Condition cond) {
    893   EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
    894 }
    895 
    896 
    897 void ArmAssembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
    898   EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
    899 }
    900 
    901 
    902 void ArmAssembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
    903   EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
    904 }
    905 
    906 
    907 void ArmAssembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
    908   EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
    909 }
    910 
    911 
    912 void ArmAssembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
    913   EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
    914 }
    915 
    916 void ArmAssembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
    917   EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
    918 }
    919 
    920 
    921 void ArmAssembler::EmitVFPsd(Condition cond, int32_t opcode,
    922                              SRegister sd, DRegister dm) {
    923   CHECK_NE(sd, kNoSRegister);
    924   CHECK_NE(dm, kNoDRegister);
    925   CHECK_NE(cond, kNoCondition);
    926   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    927                      B27 | B26 | B25 | B11 | B9 | opcode |
    928                      ((static_cast<int32_t>(sd) & 1)*B22) |
    929                      ((static_cast<int32_t>(sd) >> 1)*B12) |
    930                      ((static_cast<int32_t>(dm) >> 4)*B5) |
    931                      (static_cast<int32_t>(dm) & 0xf);
    932   Emit(encoding);
    933 }
    934 
    935 
    936 void ArmAssembler::EmitVFPds(Condition cond, int32_t opcode,
    937                              DRegister dd, SRegister sm) {
    938   CHECK_NE(dd, kNoDRegister);
    939   CHECK_NE(sm, kNoSRegister);
    940   CHECK_NE(cond, kNoCondition);
    941   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
    942                      B27 | B26 | B25 | B11 | B9 | opcode |
    943                      ((static_cast<int32_t>(dd) >> 4)*B22) |
    944                      ((static_cast<int32_t>(dd) & 0xf)*B12) |
    945                      ((static_cast<int32_t>(sm) & 1)*B5) |
    946                      (static_cast<int32_t>(sm) >> 1);
    947   Emit(encoding);
    948 }
    949 
    950 
    951 void ArmAssembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
    952   EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
    953 }
    954 
    955 
    956 void ArmAssembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
    957   EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
    958 }
    959 
    960 
    961 void ArmAssembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
    962   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
    963 }
    964 
    965 
    966 void ArmAssembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
    967   EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
    968 }
    969 
    970 
    971 void ArmAssembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
    972   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
    973 }
    974 
    975 
    976 void ArmAssembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
    977   EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
    978 }
    979 
    980 
    981 void ArmAssembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
    982   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
    983 }
    984 
    985 
    986 void ArmAssembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
    987   EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
    988 }
    989 
    990 
    991 void ArmAssembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
    992   EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
    993 }
    994 
    995 
    996 void ArmAssembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
    997   EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
    998 }
    999 
   1000 
   1001 void ArmAssembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
   1002   EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
   1003 }
   1004 
   1005 
   1006 void ArmAssembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
   1007   EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
   1008 }
   1009 
   1010 
   1011 void ArmAssembler::vcmpsz(SRegister sd, Condition cond) {
   1012   EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
   1013 }
   1014 
   1015 
   1016 void ArmAssembler::vcmpdz(DRegister dd, Condition cond) {
   1017   EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
   1018 }
   1019 
   1020 
   1021 void ArmAssembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
   1022   CHECK_NE(cond, kNoCondition);
   1023   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
   1024                      B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
   1025                      (static_cast<int32_t>(PC)*B12) |
   1026                      B11 | B9 | B4;
   1027   Emit(encoding);
   1028 }
   1029 
   1030 
   1031 void ArmAssembler::svc(uint32_t imm24) {
   1032   CHECK(IsUint(24, imm24)) << imm24;
   1033   int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
   1034   Emit(encoding);
   1035 }
   1036 
   1037 
   1038 void ArmAssembler::bkpt(uint16_t imm16) {
   1039   int32_t encoding = (AL << kConditionShift) | B24 | B21 |
   1040                      ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
   1041   Emit(encoding);
   1042 }
   1043 
   1044 
   1045 void ArmAssembler::b(Label* label, Condition cond) {
   1046   EmitBranch(cond, label, false);
   1047 }
   1048 
   1049 
   1050 void ArmAssembler::bl(Label* label, Condition cond) {
   1051   EmitBranch(cond, label, true);
   1052 }
   1053 
   1054 
   1055 void ArmAssembler::blx(Register rm, Condition cond) {
   1056   CHECK_NE(rm, kNoRegister);
   1057   CHECK_NE(cond, kNoCondition);
   1058   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
   1059                      B24 | B21 | (0xfff << 8) | B5 | B4 |
   1060                      (static_cast<int32_t>(rm) << kRmShift);
   1061   Emit(encoding);
   1062 }
   1063 
   1064 void ArmAssembler::bx(Register rm, Condition cond) {
   1065   CHECK_NE(rm, kNoRegister);
   1066   CHECK_NE(cond, kNoCondition);
   1067   int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
   1068                      B24 | B21 | (0xfff << 8) | B4 |
   1069                      (static_cast<int32_t>(rm) << kRmShift);
   1070   Emit(encoding);
   1071 }
   1072 
   1073 void ArmAssembler::MarkExceptionHandler(Label* label) {
   1074   EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
   1075   Label l;
   1076   b(&l);
   1077   EmitBranch(AL, label, false);
   1078   Bind(&l);
   1079 }
   1080 
   1081 
   1082 void ArmAssembler::Bind(Label* label) {
   1083   CHECK(!label->IsBound());
   1084   int bound_pc = buffer_.Size();
   1085   while (label->IsLinked()) {
   1086     int32_t position = label->Position();
   1087     int32_t next = buffer_.Load<int32_t>(position);
   1088     int32_t encoded = ArmAssembler::EncodeBranchOffset(bound_pc - position, next);
   1089     buffer_.Store<int32_t>(position, encoded);
   1090     label->position_ = ArmAssembler::DecodeBranchOffset(next);
   1091   }
   1092   label->BindTo(bound_pc);
   1093 }
   1094 
   1095 
   1096 void ArmAssembler::EncodeUint32InTstInstructions(uint32_t data) {
   1097   // TODO: Consider using movw ip, <16 bits>.
   1098   while (!IsUint(8, data)) {
   1099     tst(R0, ShifterOperand(data & 0xFF), VS);
   1100     data >>= 8;
   1101   }
   1102   tst(R0, ShifterOperand(data), MI);
   1103 }
   1104 
   1105 
   1106 int32_t ArmAssembler::EncodeBranchOffset(int offset, int32_t inst) {
   1107   // The offset is off by 8 due to the way the ARM CPUs read PC.
   1108   offset -= 8;
   1109   CHECK_ALIGNED(offset, 4);
   1110   CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)) << offset;
   1111 
   1112   // Properly preserve only the bits supported in the instruction.
   1113   offset >>= 2;
   1114   offset &= kBranchOffsetMask;
   1115   return (inst & ~kBranchOffsetMask) | offset;
   1116 }
   1117 
   1118 
   1119 int ArmAssembler::DecodeBranchOffset(int32_t inst) {
   1120   // Sign-extend, left-shift by 2, then add 8.
   1121   return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
   1122 }
   1123 
   1124 void ArmAssembler::AddConstant(Register rd, int32_t value, Condition cond) {
   1125   AddConstant(rd, rd, value, cond);
   1126 }
   1127 
   1128 
   1129 void ArmAssembler::AddConstant(Register rd, Register rn, int32_t value,
   1130                                Condition cond) {
   1131   if (value == 0) {
   1132     if (rd != rn) {
   1133       mov(rd, ShifterOperand(rn), cond);
   1134     }
   1135     return;
   1136   }
   1137   // We prefer to select the shorter code sequence rather than selecting add for
   1138   // positive values and sub for negatives ones, which would slightly improve
   1139   // the readability of generated code for some constants.
   1140   ShifterOperand shifter_op;
   1141   if (ShifterOperand::CanHold(value, &shifter_op)) {
   1142     add(rd, rn, shifter_op, cond);
   1143   } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
   1144     sub(rd, rn, shifter_op, cond);
   1145   } else {
   1146     CHECK(rn != IP);
   1147     if (ShifterOperand::CanHold(~value, &shifter_op)) {
   1148       mvn(IP, shifter_op, cond);
   1149       add(rd, rn, ShifterOperand(IP), cond);
   1150     } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
   1151       mvn(IP, shifter_op, cond);
   1152       sub(rd, rn, ShifterOperand(IP), cond);
   1153     } else {
   1154       movw(IP, Low16Bits(value), cond);
   1155       uint16_t value_high = High16Bits(value);
   1156       if (value_high != 0) {
   1157         movt(IP, value_high, cond);
   1158       }
   1159       add(rd, rn, ShifterOperand(IP), cond);
   1160     }
   1161   }
   1162 }
   1163 
   1164 
   1165 void ArmAssembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
   1166                                        Condition cond) {
   1167   ShifterOperand shifter_op;
   1168   if (ShifterOperand::CanHold(value, &shifter_op)) {
   1169     adds(rd, rn, shifter_op, cond);
   1170   } else if (ShifterOperand::CanHold(-value, &shifter_op)) {
   1171     subs(rd, rn, shifter_op, cond);
   1172   } else {
   1173     CHECK(rn != IP);
   1174     if (ShifterOperand::CanHold(~value, &shifter_op)) {
   1175       mvn(IP, shifter_op, cond);
   1176       adds(rd, rn, ShifterOperand(IP), cond);
   1177     } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) {
   1178       mvn(IP, shifter_op, cond);
   1179       subs(rd, rn, ShifterOperand(IP), cond);
   1180     } else {
   1181       movw(IP, Low16Bits(value), cond);
   1182       uint16_t value_high = High16Bits(value);
   1183       if (value_high != 0) {
   1184         movt(IP, value_high, cond);
   1185       }
   1186       adds(rd, rn, ShifterOperand(IP), cond);
   1187     }
   1188   }
   1189 }
   1190 
   1191 
   1192 void ArmAssembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
   1193   ShifterOperand shifter_op;
   1194   if (ShifterOperand::CanHold(value, &shifter_op)) {
   1195     mov(rd, shifter_op, cond);
   1196   } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
   1197     mvn(rd, shifter_op, cond);
   1198   } else {
   1199     movw(rd, Low16Bits(value), cond);
   1200     uint16_t value_high = High16Bits(value);
   1201     if (value_high != 0) {
   1202       movt(rd, value_high, cond);
   1203     }
   1204   }
   1205 }
   1206 
   1207 
   1208 bool Address::CanHoldLoadOffset(LoadOperandType type, int offset) {
   1209   switch (type) {
   1210     case kLoadSignedByte:
   1211     case kLoadSignedHalfword:
   1212     case kLoadUnsignedHalfword:
   1213     case kLoadWordPair:
   1214       return IsAbsoluteUint(8, offset);  // Addressing mode 3.
   1215     case kLoadUnsignedByte:
   1216     case kLoadWord:
   1217       return IsAbsoluteUint(12, offset);  // Addressing mode 2.
   1218     case kLoadSWord:
   1219     case kLoadDWord:
   1220       return IsAbsoluteUint(10, offset);  // VFP addressing mode.
   1221     default:
   1222       LOG(FATAL) << "UNREACHABLE";
   1223       return false;
   1224   }
   1225 }
   1226 
   1227 
   1228 bool Address::CanHoldStoreOffset(StoreOperandType type, int offset) {
   1229   switch (type) {
   1230     case kStoreHalfword:
   1231     case kStoreWordPair:
   1232       return IsAbsoluteUint(8, offset);  // Addressing mode 3.
   1233     case kStoreByte:
   1234     case kStoreWord:
   1235       return IsAbsoluteUint(12, offset);  // Addressing mode 2.
   1236     case kStoreSWord:
   1237     case kStoreDWord:
   1238       return IsAbsoluteUint(10, offset);  // VFP addressing mode.
   1239     default:
   1240       LOG(FATAL) << "UNREACHABLE";
   1241       return false;
   1242   }
   1243 }
   1244 
   1245 
   1246 // Implementation note: this method must emit at most one instruction when
   1247 // Address::CanHoldLoadOffset.
   1248 void ArmAssembler::LoadFromOffset(LoadOperandType type,
   1249                                   Register reg,
   1250                                   Register base,
   1251                                   int32_t offset,
   1252                                   Condition cond) {
   1253   if (!Address::CanHoldLoadOffset(type, offset)) {
   1254     CHECK(base != IP);
   1255     LoadImmediate(IP, offset, cond);
   1256     add(IP, IP, ShifterOperand(base), cond);
   1257     base = IP;
   1258     offset = 0;
   1259   }
   1260   CHECK(Address::CanHoldLoadOffset(type, offset));
   1261   switch (type) {
   1262     case kLoadSignedByte:
   1263       ldrsb(reg, Address(base, offset), cond);
   1264       break;
   1265     case kLoadUnsignedByte:
   1266       ldrb(reg, Address(base, offset), cond);
   1267       break;
   1268     case kLoadSignedHalfword:
   1269       ldrsh(reg, Address(base, offset), cond);
   1270       break;
   1271     case kLoadUnsignedHalfword:
   1272       ldrh(reg, Address(base, offset), cond);
   1273       break;
   1274     case kLoadWord:
   1275       ldr(reg, Address(base, offset), cond);
   1276       break;
   1277     case kLoadWordPair:
   1278       ldrd(reg, Address(base, offset), cond);
   1279       break;
   1280     default:
   1281       LOG(FATAL) << "UNREACHABLE";
   1282   }
   1283 }
   1284 
   1285 // Implementation note: this method must emit at most one instruction when
   1286 // Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
   1287 void ArmAssembler::LoadSFromOffset(SRegister reg,
   1288                                    Register base,
   1289                                    int32_t offset,
   1290                                    Condition cond) {
   1291   if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) {
   1292     CHECK_NE(base, IP);
   1293     LoadImmediate(IP, offset, cond);
   1294     add(IP, IP, ShifterOperand(base), cond);
   1295     base = IP;
   1296     offset = 0;
   1297   }
   1298   CHECK(Address::CanHoldLoadOffset(kLoadSWord, offset));
   1299   vldrs(reg, Address(base, offset), cond);
   1300 }
   1301 
   1302 // Implementation note: this method must emit at most one instruction when
   1303 // Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset.
   1304 void ArmAssembler::LoadDFromOffset(DRegister reg,
   1305                                    Register base,
   1306                                    int32_t offset,
   1307                                    Condition cond) {
   1308   if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) {
   1309     CHECK_NE(base, IP);
   1310     LoadImmediate(IP, offset, cond);
   1311     add(IP, IP, ShifterOperand(base), cond);
   1312     base = IP;
   1313     offset = 0;
   1314   }
   1315   CHECK(Address::CanHoldLoadOffset(kLoadDWord, offset));
   1316   vldrd(reg, Address(base, offset), cond);
   1317 }
   1318 
   1319 // Implementation note: this method must emit at most one instruction when
   1320 // Address::CanHoldStoreOffset.
   1321 void ArmAssembler::StoreToOffset(StoreOperandType type,
   1322                                  Register reg,
   1323                                  Register base,
   1324                                  int32_t offset,
   1325                                  Condition cond) {
   1326   if (!Address::CanHoldStoreOffset(type, offset)) {
   1327     CHECK(reg != IP);
   1328     CHECK(base != IP);
   1329     LoadImmediate(IP, offset, cond);
   1330     add(IP, IP, ShifterOperand(base), cond);
   1331     base = IP;
   1332     offset = 0;
   1333   }
   1334   CHECK(Address::CanHoldStoreOffset(type, offset));
   1335   switch (type) {
   1336     case kStoreByte:
   1337       strb(reg, Address(base, offset), cond);
   1338       break;
   1339     case kStoreHalfword:
   1340       strh(reg, Address(base, offset), cond);
   1341       break;
   1342     case kStoreWord:
   1343       str(reg, Address(base, offset), cond);
   1344       break;
   1345     case kStoreWordPair:
   1346       strd(reg, Address(base, offset), cond);
   1347       break;
   1348     default:
   1349       LOG(FATAL) << "UNREACHABLE";
   1350   }
   1351 }
   1352 
   1353 // Implementation note: this method must emit at most one instruction when
   1354 // Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreToOffset.
   1355 void ArmAssembler::StoreSToOffset(SRegister reg,
   1356                                   Register base,
   1357                                   int32_t offset,
   1358                                   Condition cond) {
   1359   if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) {
   1360     CHECK_NE(base, IP);
   1361     LoadImmediate(IP, offset, cond);
   1362     add(IP, IP, ShifterOperand(base), cond);
   1363     base = IP;
   1364     offset = 0;
   1365   }
   1366   CHECK(Address::CanHoldStoreOffset(kStoreSWord, offset));
   1367   vstrs(reg, Address(base, offset), cond);
   1368 }
   1369 
   1370 // Implementation note: this method must emit at most one instruction when
   1371 // Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreSToOffset.
   1372 void ArmAssembler::StoreDToOffset(DRegister reg,
   1373                                   Register base,
   1374                                   int32_t offset,
   1375                                   Condition cond) {
   1376   if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) {
   1377     CHECK_NE(base, IP);
   1378     LoadImmediate(IP, offset, cond);
   1379     add(IP, IP, ShifterOperand(base), cond);
   1380     base = IP;
   1381     offset = 0;
   1382   }
   1383   CHECK(Address::CanHoldStoreOffset(kStoreDWord, offset));
   1384   vstrd(reg, Address(base, offset), cond);
   1385 }
   1386 
   1387 void ArmAssembler::Push(Register rd, Condition cond) {
   1388   str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
   1389 }
   1390 
   1391 void ArmAssembler::Pop(Register rd, Condition cond) {
   1392   ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
   1393 }
   1394 
   1395 void ArmAssembler::PushList(RegList regs, Condition cond) {
   1396   stm(DB_W, SP, regs, cond);
   1397 }
   1398 
   1399 void ArmAssembler::PopList(RegList regs, Condition cond) {
   1400   ldm(IA_W, SP, regs, cond);
   1401 }
   1402 
   1403 void ArmAssembler::Mov(Register rd, Register rm, Condition cond) {
   1404   if (rd != rm) {
   1405     mov(rd, ShifterOperand(rm), cond);
   1406   }
   1407 }
   1408 
   1409 void ArmAssembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
   1410                        Condition cond) {
   1411   CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
   1412   mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
   1413 }
   1414 
   1415 void ArmAssembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
   1416                        Condition cond) {
   1417   CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
   1418   if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
   1419   mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
   1420 }
   1421 
   1422 void ArmAssembler::Asr(Register rd, Register rm, uint32_t shift_imm,
   1423                        Condition cond) {
   1424   CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
   1425   if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
   1426   mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
   1427 }
   1428 
   1429 void ArmAssembler::Ror(Register rd, Register rm, uint32_t shift_imm,
   1430                        Condition cond) {
   1431   CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
   1432   mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
   1433 }
   1434 
   1435 void ArmAssembler::Rrx(Register rd, Register rm, Condition cond) {
   1436   mov(rd, ShifterOperand(rm, ROR, 0), cond);
   1437 }
   1438 
   1439 void ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
   1440                               const std::vector<ManagedRegister>& callee_save_regs,
   1441                               const std::vector<ManagedRegister>& entry_spills) {
   1442   CHECK_ALIGNED(frame_size, kStackAlignment);
   1443   CHECK_EQ(R0, method_reg.AsArm().AsCoreRegister());
   1444 
   1445   // Push callee saves and link register.
   1446   RegList push_list = 1 << LR;
   1447   size_t pushed_values = 1;
   1448   for (size_t i = 0; i < callee_save_regs.size(); i++) {
   1449     Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
   1450     push_list |= 1 << reg;
   1451     pushed_values++;
   1452   }
   1453   PushList(push_list);
   1454 
   1455   // Increase frame to required size.
   1456   CHECK_GT(frame_size, pushed_values * kPointerSize);  // Must be at least space to push Method*
   1457   size_t adjust = frame_size - (pushed_values * kPointerSize);
   1458   IncreaseFrameSize(adjust);
   1459 
   1460   // Write out Method*.
   1461   StoreToOffset(kStoreWord, R0, SP, 0);
   1462 
   1463   // Write out entry spills.
   1464   for (size_t i = 0; i < entry_spills.size(); ++i) {
   1465     Register reg = entry_spills.at(i).AsArm().AsCoreRegister();
   1466     StoreToOffset(kStoreWord, reg, SP, frame_size + kPointerSize + (i * kPointerSize));
   1467   }
   1468 }
   1469 
   1470 void ArmAssembler::RemoveFrame(size_t frame_size,
   1471                               const std::vector<ManagedRegister>& callee_save_regs) {
   1472   CHECK_ALIGNED(frame_size, kStackAlignment);
   1473   // Compute callee saves to pop and PC
   1474   RegList pop_list = 1 << PC;
   1475   size_t pop_values = 1;
   1476   for (size_t i = 0; i < callee_save_regs.size(); i++) {
   1477     Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister();
   1478     pop_list |= 1 << reg;
   1479     pop_values++;
   1480   }
   1481 
   1482   // Decrease frame to start of callee saves
   1483   CHECK_GT(frame_size, pop_values * kPointerSize);
   1484   size_t adjust = frame_size - (pop_values * kPointerSize);
   1485   DecreaseFrameSize(adjust);
   1486 
   1487   // Pop callee saves and PC
   1488   PopList(pop_list);
   1489 }
   1490 
   1491 void ArmAssembler::IncreaseFrameSize(size_t adjust) {
   1492   AddConstant(SP, -adjust);
   1493 }
   1494 
   1495 void ArmAssembler::DecreaseFrameSize(size_t adjust) {
   1496   AddConstant(SP, adjust);
   1497 }
   1498 
   1499 void ArmAssembler::Store(FrameOffset dest, ManagedRegister msrc, size_t size) {
   1500   ArmManagedRegister src = msrc.AsArm();
   1501   if (src.IsNoRegister()) {
   1502     CHECK_EQ(0u, size);
   1503   } else if (src.IsCoreRegister()) {
   1504     CHECK_EQ(4u, size);
   1505     StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
   1506   } else if (src.IsRegisterPair()) {
   1507     CHECK_EQ(8u, size);
   1508     StoreToOffset(kStoreWord, src.AsRegisterPairLow(), SP, dest.Int32Value());
   1509     StoreToOffset(kStoreWord, src.AsRegisterPairHigh(),
   1510                   SP, dest.Int32Value() + 4);
   1511   } else if (src.IsSRegister()) {
   1512     StoreSToOffset(src.AsSRegister(), SP, dest.Int32Value());
   1513   } else {
   1514     CHECK(src.IsDRegister()) << src;
   1515     StoreDToOffset(src.AsDRegister(), SP, dest.Int32Value());
   1516   }
   1517 }
   1518 
   1519 void ArmAssembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
   1520   ArmManagedRegister src = msrc.AsArm();
   1521   CHECK(src.IsCoreRegister()) << src;
   1522   StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
   1523 }
   1524 
   1525 void ArmAssembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
   1526   ArmManagedRegister src = msrc.AsArm();
   1527   CHECK(src.IsCoreRegister()) << src;
   1528   StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
   1529 }
   1530 
   1531 void ArmAssembler::StoreSpanning(FrameOffset dest, ManagedRegister msrc,
   1532                               FrameOffset in_off, ManagedRegister mscratch) {
   1533   ArmManagedRegister src = msrc.AsArm();
   1534   ArmManagedRegister scratch = mscratch.AsArm();
   1535   StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value());
   1536   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, in_off.Int32Value());
   1537   StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
   1538 }
   1539 
   1540 void ArmAssembler::CopyRef(FrameOffset dest, FrameOffset src,
   1541                         ManagedRegister mscratch) {
   1542   ArmManagedRegister scratch = mscratch.AsArm();
   1543   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
   1544   StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
   1545 }
   1546 
   1547 void ArmAssembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
   1548                            MemberOffset offs) {
   1549   ArmManagedRegister dst = mdest.AsArm();
   1550   CHECK(dst.IsCoreRegister() && dst.IsCoreRegister()) << dst;
   1551   LoadFromOffset(kLoadWord, dst.AsCoreRegister(),
   1552                  base.AsArm().AsCoreRegister(), offs.Int32Value());
   1553 }
   1554 
   1555 void ArmAssembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
   1556   ArmManagedRegister dst = mdest.AsArm();
   1557   CHECK(dst.IsCoreRegister()) << dst;
   1558   LoadFromOffset(kLoadWord, dst.AsCoreRegister(), SP, src.Int32Value());
   1559 }
   1560 
   1561 void ArmAssembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
   1562                            Offset offs) {
   1563   ArmManagedRegister dst = mdest.AsArm();
   1564   CHECK(dst.IsCoreRegister() && dst.IsCoreRegister()) << dst;
   1565   LoadFromOffset(kLoadWord, dst.AsCoreRegister(),
   1566                  base.AsArm().AsCoreRegister(), offs.Int32Value());
   1567 }
   1568 
   1569 void ArmAssembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
   1570                                       ManagedRegister mscratch) {
   1571   ArmManagedRegister scratch = mscratch.AsArm();
   1572   CHECK(scratch.IsCoreRegister()) << scratch;
   1573   LoadImmediate(scratch.AsCoreRegister(), imm);
   1574   StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
   1575 }
   1576 
   1577 void ArmAssembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
   1578                                        ManagedRegister mscratch) {
   1579   ArmManagedRegister scratch = mscratch.AsArm();
   1580   CHECK(scratch.IsCoreRegister()) << scratch;
   1581   LoadImmediate(scratch.AsCoreRegister(), imm);
   1582   StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value());
   1583 }
   1584 
   1585 static void EmitLoad(ArmAssembler* assembler, ManagedRegister m_dst,
   1586                      Register src_register, int32_t src_offset, size_t size) {
   1587   ArmManagedRegister dst = m_dst.AsArm();
   1588   if (dst.IsNoRegister()) {
   1589     CHECK_EQ(0u, size) << dst;
   1590   } else if (dst.IsCoreRegister()) {
   1591     CHECK_EQ(4u, size) << dst;
   1592     assembler->LoadFromOffset(kLoadWord, dst.AsCoreRegister(), src_register, src_offset);
   1593   } else if (dst.IsRegisterPair()) {
   1594     CHECK_EQ(8u, size) << dst;
   1595     assembler->LoadFromOffset(kLoadWord, dst.AsRegisterPairLow(), src_register, src_offset);
   1596     assembler->LoadFromOffset(kLoadWord, dst.AsRegisterPairHigh(), src_register, src_offset + 4);
   1597   } else if (dst.IsSRegister()) {
   1598     assembler->LoadSFromOffset(dst.AsSRegister(), src_register, src_offset);
   1599   } else {
   1600     CHECK(dst.IsDRegister()) << dst;
   1601     assembler->LoadDFromOffset(dst.AsDRegister(), src_register, src_offset);
   1602   }
   1603 }
   1604 
   1605 void ArmAssembler::Load(ManagedRegister m_dst, FrameOffset src, size_t size) {
   1606   return EmitLoad(this, m_dst, SP, src.Int32Value(), size);
   1607 }
   1608 
   1609 void ArmAssembler::Load(ManagedRegister m_dst, ThreadOffset src, size_t size) {
   1610   return EmitLoad(this, m_dst, TR, src.Int32Value(), size);
   1611 }
   1612 
   1613 void ArmAssembler::LoadRawPtrFromThread(ManagedRegister m_dst, ThreadOffset offs) {
   1614   ArmManagedRegister dst = m_dst.AsArm();
   1615   CHECK(dst.IsCoreRegister()) << dst;
   1616   LoadFromOffset(kLoadWord, dst.AsCoreRegister(), TR, offs.Int32Value());
   1617 }
   1618 
   1619 void ArmAssembler::CopyRawPtrFromThread(FrameOffset fr_offs,
   1620                                         ThreadOffset thr_offs,
   1621                                         ManagedRegister mscratch) {
   1622   ArmManagedRegister scratch = mscratch.AsArm();
   1623   CHECK(scratch.IsCoreRegister()) << scratch;
   1624   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1625                  TR, thr_offs.Int32Value());
   1626   StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
   1627                 SP, fr_offs.Int32Value());
   1628 }
   1629 
   1630 void ArmAssembler::CopyRawPtrToThread(ThreadOffset thr_offs,
   1631                                       FrameOffset fr_offs,
   1632                                       ManagedRegister mscratch) {
   1633   ArmManagedRegister scratch = mscratch.AsArm();
   1634   CHECK(scratch.IsCoreRegister()) << scratch;
   1635   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1636                  SP, fr_offs.Int32Value());
   1637   StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
   1638                 TR, thr_offs.Int32Value());
   1639 }
   1640 
   1641 void ArmAssembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
   1642                                             FrameOffset fr_offs,
   1643                                             ManagedRegister mscratch) {
   1644   ArmManagedRegister scratch = mscratch.AsArm();
   1645   CHECK(scratch.IsCoreRegister()) << scratch;
   1646   AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL);
   1647   StoreToOffset(kStoreWord, scratch.AsCoreRegister(),
   1648                 TR, thr_offs.Int32Value());
   1649 }
   1650 
   1651 void ArmAssembler::StoreStackPointerToThread(ThreadOffset thr_offs) {
   1652   StoreToOffset(kStoreWord, SP, TR, thr_offs.Int32Value());
   1653 }
   1654 
   1655 void ArmAssembler::SignExtend(ManagedRegister /*mreg*/, size_t /*size*/) {
   1656   UNIMPLEMENTED(FATAL) << "no sign extension necessary for arm";
   1657 }
   1658 
   1659 void ArmAssembler::ZeroExtend(ManagedRegister /*mreg*/, size_t /*size*/) {
   1660   UNIMPLEMENTED(FATAL) << "no zero extension necessary for arm";
   1661 }
   1662 
   1663 void ArmAssembler::Move(ManagedRegister m_dst, ManagedRegister m_src, size_t /*size*/) {
   1664   ArmManagedRegister dst = m_dst.AsArm();
   1665   ArmManagedRegister src = m_src.AsArm();
   1666   if (!dst.Equals(src)) {
   1667     if (dst.IsCoreRegister()) {
   1668       CHECK(src.IsCoreRegister()) << src;
   1669       mov(dst.AsCoreRegister(), ShifterOperand(src.AsCoreRegister()));
   1670     } else if (dst.IsDRegister()) {
   1671       CHECK(src.IsDRegister()) << src;
   1672       vmovd(dst.AsDRegister(), src.AsDRegister());
   1673     } else if (dst.IsSRegister()) {
   1674       CHECK(src.IsSRegister()) << src;
   1675       vmovs(dst.AsSRegister(), src.AsSRegister());
   1676     } else {
   1677       CHECK(dst.IsRegisterPair()) << dst;
   1678       CHECK(src.IsRegisterPair()) << src;
   1679       // Ensure that the first move doesn't clobber the input of the second
   1680       if (src.AsRegisterPairHigh() != dst.AsRegisterPairLow()) {
   1681         mov(dst.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
   1682         mov(dst.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
   1683       } else {
   1684         mov(dst.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh()));
   1685         mov(dst.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow()));
   1686       }
   1687     }
   1688   }
   1689 }
   1690 
   1691 void ArmAssembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) {
   1692   ArmManagedRegister scratch = mscratch.AsArm();
   1693   CHECK(scratch.IsCoreRegister()) << scratch;
   1694   CHECK(size == 4 || size == 8) << size;
   1695   if (size == 4) {
   1696     LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
   1697     StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
   1698   } else if (size == 8) {
   1699     LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value());
   1700     StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value());
   1701     LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value() + 4);
   1702     StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4);
   1703   }
   1704 }
   1705 
   1706 void ArmAssembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset,
   1707                         ManagedRegister mscratch, size_t size) {
   1708   Register scratch = mscratch.AsArm().AsCoreRegister();
   1709   CHECK_EQ(size, 4u);
   1710   LoadFromOffset(kLoadWord, scratch, src_base.AsArm().AsCoreRegister(), src_offset.Int32Value());
   1711   StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value());
   1712 }
   1713 
   1714 void ArmAssembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
   1715                         ManagedRegister mscratch, size_t size) {
   1716   Register scratch = mscratch.AsArm().AsCoreRegister();
   1717   CHECK_EQ(size, 4u);
   1718   LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value());
   1719   StoreToOffset(kStoreWord, scratch, dest_base.AsArm().AsCoreRegister(), dest_offset.Int32Value());
   1720 }
   1721 
   1722 void ArmAssembler::Copy(FrameOffset /*dst*/, FrameOffset /*src_base*/, Offset /*src_offset*/,
   1723                         ManagedRegister /*mscratch*/, size_t /*size*/) {
   1724   UNIMPLEMENTED(FATAL);
   1725 }
   1726 
   1727 void ArmAssembler::Copy(ManagedRegister dest, Offset dest_offset,
   1728                         ManagedRegister src, Offset src_offset,
   1729                         ManagedRegister mscratch, size_t size) {
   1730   CHECK_EQ(size, 4u);
   1731   Register scratch = mscratch.AsArm().AsCoreRegister();
   1732   LoadFromOffset(kLoadWord, scratch, src.AsArm().AsCoreRegister(), src_offset.Int32Value());
   1733   StoreToOffset(kStoreWord, scratch, dest.AsArm().AsCoreRegister(), dest_offset.Int32Value());
   1734 }
   1735 
   1736 void ArmAssembler::Copy(FrameOffset /*dst*/, Offset /*dest_offset*/, FrameOffset /*src*/, Offset /*src_offset*/,
   1737                         ManagedRegister /*scratch*/, size_t /*size*/) {
   1738   UNIMPLEMENTED(FATAL);
   1739 }
   1740 
   1741 
   1742 void ArmAssembler::MemoryBarrier(ManagedRegister mscratch) {
   1743   CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
   1744 #if ANDROID_SMP != 0
   1745 #if defined(__ARM_HAVE_DMB)
   1746   int32_t encoding = 0xf57ff05f;  // dmb
   1747   Emit(encoding);
   1748 #elif  defined(__ARM_HAVE_LDREX_STREX)
   1749   LoadImmediate(R12, 0);
   1750   int32_t encoding = 0xee07cfba;  // mcr p15, 0, r12, c7, c10, 5
   1751   Emit(encoding);
   1752 #else
   1753   LoadImmediate(R12, 0xffff0fa0);  // kuser_memory_barrier
   1754   blx(R12);
   1755 #endif
   1756 #endif
   1757 }
   1758 
   1759 void ArmAssembler::CreateSirtEntry(ManagedRegister mout_reg,
   1760                                    FrameOffset sirt_offset,
   1761                                    ManagedRegister min_reg, bool null_allowed) {
   1762   ArmManagedRegister out_reg = mout_reg.AsArm();
   1763   ArmManagedRegister in_reg = min_reg.AsArm();
   1764   CHECK(in_reg.IsNoRegister() || in_reg.IsCoreRegister()) << in_reg;
   1765   CHECK(out_reg.IsCoreRegister()) << out_reg;
   1766   if (null_allowed) {
   1767     // Null values get a SIRT entry value of 0.  Otherwise, the SIRT entry is
   1768     // the address in the SIRT holding the reference.
   1769     // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset)
   1770     if (in_reg.IsNoRegister()) {
   1771       LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
   1772                      SP, sirt_offset.Int32Value());
   1773       in_reg = out_reg;
   1774     }
   1775     cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
   1776     if (!out_reg.Equals(in_reg)) {
   1777       LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
   1778     }
   1779     AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
   1780   } else {
   1781     AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
   1782   }
   1783 }
   1784 
   1785 void ArmAssembler::CreateSirtEntry(FrameOffset out_off,
   1786                                    FrameOffset sirt_offset,
   1787                                    ManagedRegister mscratch,
   1788                                    bool null_allowed) {
   1789   ArmManagedRegister scratch = mscratch.AsArm();
   1790   CHECK(scratch.IsCoreRegister()) << scratch;
   1791   if (null_allowed) {
   1792     LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP,
   1793                    sirt_offset.Int32Value());
   1794     // Null values get a SIRT entry value of 0.  Otherwise, the sirt entry is
   1795     // the address in the SIRT holding the reference.
   1796     // e.g. scratch = (scratch == 0) ? 0 : (SP+sirt_offset)
   1797     cmp(scratch.AsCoreRegister(), ShifterOperand(0));
   1798     AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE);
   1799   } else {
   1800     AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL);
   1801   }
   1802   StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value());
   1803 }
   1804 
   1805 void ArmAssembler::LoadReferenceFromSirt(ManagedRegister mout_reg,
   1806                                          ManagedRegister min_reg) {
   1807   ArmManagedRegister out_reg = mout_reg.AsArm();
   1808   ArmManagedRegister in_reg = min_reg.AsArm();
   1809   CHECK(out_reg.IsCoreRegister()) << out_reg;
   1810   CHECK(in_reg.IsCoreRegister()) << in_reg;
   1811   Label null_arg;
   1812   if (!out_reg.Equals(in_reg)) {
   1813     LoadImmediate(out_reg.AsCoreRegister(), 0, EQ);
   1814   }
   1815   cmp(in_reg.AsCoreRegister(), ShifterOperand(0));
   1816   LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(),
   1817                  in_reg.AsCoreRegister(), 0, NE);
   1818 }
   1819 
   1820 void ArmAssembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
   1821   // TODO: not validating references
   1822 }
   1823 
   1824 void ArmAssembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
   1825   // TODO: not validating references
   1826 }
   1827 
   1828 void ArmAssembler::Call(ManagedRegister mbase, Offset offset,
   1829                         ManagedRegister mscratch) {
   1830   ArmManagedRegister base = mbase.AsArm();
   1831   ArmManagedRegister scratch = mscratch.AsArm();
   1832   CHECK(base.IsCoreRegister()) << base;
   1833   CHECK(scratch.IsCoreRegister()) << scratch;
   1834   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1835                  base.AsCoreRegister(), offset.Int32Value());
   1836   blx(scratch.AsCoreRegister());
   1837   // TODO: place reference map on call
   1838 }
   1839 
   1840 void ArmAssembler::Call(FrameOffset base, Offset offset,
   1841                         ManagedRegister mscratch) {
   1842   ArmManagedRegister scratch = mscratch.AsArm();
   1843   CHECK(scratch.IsCoreRegister()) << scratch;
   1844   // Call *(*(SP + base) + offset)
   1845   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1846                  SP, base.Int32Value());
   1847   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1848                  scratch.AsCoreRegister(), offset.Int32Value());
   1849   blx(scratch.AsCoreRegister());
   1850   // TODO: place reference map on call
   1851 }
   1852 
   1853 void ArmAssembler::Call(ThreadOffset /*offset*/, ManagedRegister /*scratch*/) {
   1854   UNIMPLEMENTED(FATAL);
   1855 }
   1856 
   1857 void ArmAssembler::GetCurrentThread(ManagedRegister tr) {
   1858   mov(tr.AsArm().AsCoreRegister(), ShifterOperand(TR));
   1859 }
   1860 
   1861 void ArmAssembler::GetCurrentThread(FrameOffset offset,
   1862                                     ManagedRegister /*scratch*/) {
   1863   StoreToOffset(kStoreWord, TR, SP, offset.Int32Value(), AL);
   1864 }
   1865 
   1866 void ArmAssembler::ExceptionPoll(ManagedRegister mscratch, size_t stack_adjust) {
   1867   ArmManagedRegister scratch = mscratch.AsArm();
   1868   ArmExceptionSlowPath* slow = new ArmExceptionSlowPath(scratch, stack_adjust);
   1869   buffer_.EnqueueSlowPath(slow);
   1870   LoadFromOffset(kLoadWord, scratch.AsCoreRegister(),
   1871                  TR, Thread::ExceptionOffset().Int32Value());
   1872   cmp(scratch.AsCoreRegister(), ShifterOperand(0));
   1873   b(slow->Entry(), NE);
   1874 }
   1875 
   1876 void ArmExceptionSlowPath::Emit(Assembler* sasm) {
   1877   ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm);
   1878 #define __ sp_asm->
   1879   __ Bind(&entry_);
   1880   if (stack_adjust_ != 0) {  // Fix up the frame.
   1881     __ DecreaseFrameSize(stack_adjust_);
   1882   }
   1883   // Pass exception object as argument
   1884   // Don't care about preserving R0 as this call won't return
   1885   __ mov(R0, ShifterOperand(scratch_.AsCoreRegister()));
   1886   // Set up call to Thread::Current()->pDeliverException
   1887   __ LoadFromOffset(kLoadWord, R12, TR, QUICK_ENTRYPOINT_OFFSET(pDeliverException).Int32Value());
   1888   __ blx(R12);
   1889   // Call never returns
   1890   __ bkpt(0);
   1891 #undef __
   1892 }
   1893 
   1894 }  // namespace arm
   1895 }  // namespace art
   1896