assembler_thumb2.cc revision 8d486731559ba0c5e12c27b4a507181333702b7e
1/*
2 * Copyright (C) 2014 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_thumb2.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
25namespace art {
26namespace arm {
27
28void Thumb2Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
29                           Condition cond) {
30  EmitDataProcessing(cond, AND, 0, rn, rd, so);
31}
32
33
34void Thumb2Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
35                          Condition cond) {
36  EmitDataProcessing(cond, EOR, 0, rn, rd, so);
37}
38
39
40void Thumb2Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
41                          Condition cond) {
42  EmitDataProcessing(cond, SUB, 0, rn, rd, so);
43}
44
45
46void Thumb2Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
47                          Condition cond) {
48  EmitDataProcessing(cond, RSB, 0, rn, rd, so);
49}
50
51
52void Thumb2Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so,
53                           Condition cond) {
54  EmitDataProcessing(cond, RSB, 1, rn, rd, so);
55}
56
57
58void Thumb2Assembler::add(Register rd, Register rn, const ShifterOperand& so,
59                          Condition cond) {
60  EmitDataProcessing(cond, ADD, 0, rn, rd, so);
61}
62
63
64void Thumb2Assembler::adds(Register rd, Register rn, const ShifterOperand& so,
65                           Condition cond) {
66  EmitDataProcessing(cond, ADD, 1, rn, rd, so);
67}
68
69
70void Thumb2Assembler::subs(Register rd, Register rn, const ShifterOperand& so,
71                           Condition cond) {
72  EmitDataProcessing(cond, SUB, 1, rn, rd, so);
73}
74
75
76void Thumb2Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
77                          Condition cond) {
78  EmitDataProcessing(cond, ADC, 0, rn, rd, so);
79}
80
81
82void Thumb2Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
83                          Condition cond) {
84  EmitDataProcessing(cond, SBC, 0, rn, rd, so);
85}
86
87
88void Thumb2Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
89                          Condition cond) {
90  EmitDataProcessing(cond, RSC, 0, rn, rd, so);
91}
92
93
94void Thumb2Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
95  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
96  EmitDataProcessing(cond, TST, 1, rn, R0, so);
97}
98
99
100void Thumb2Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
101  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
102  EmitDataProcessing(cond, TEQ, 1, rn, R0, so);
103}
104
105
106void Thumb2Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
107  EmitDataProcessing(cond, CMP, 1, rn, R0, so);
108}
109
110
111void Thumb2Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
112  EmitDataProcessing(cond, CMN, 1, rn, R0, so);
113}
114
115
116void Thumb2Assembler::orr(Register rd, Register rn,
117                          const ShifterOperand& so, Condition cond) {
118  EmitDataProcessing(cond, ORR, 0, rn, rd, so);
119}
120
121
122void Thumb2Assembler::orrs(Register rd, Register rn,
123                           const ShifterOperand& so, Condition cond) {
124  EmitDataProcessing(cond, ORR, 1, rn, rd, so);
125}
126
127
128void Thumb2Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) {
129  EmitDataProcessing(cond, MOV, 0, R0, rd, so);
130}
131
132
133void Thumb2Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) {
134  EmitDataProcessing(cond, MOV, 1, R0, rd, so);
135}
136
137
138void Thumb2Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
139                       Condition cond) {
140  EmitDataProcessing(cond, BIC, 0, rn, rd, so);
141}
142
143
144void Thumb2Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) {
145  EmitDataProcessing(cond, MVN, 0, R0, rd, so);
146}
147
148
149void Thumb2Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) {
150  EmitDataProcessing(cond, MVN, 1, R0, rd, so);
151}
152
153
154void Thumb2Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
155  if (rd == rm && !IsHighRegister(rd) && !IsHighRegister(rn) && !force_32bit_) {
156    // 16 bit.
157    int16_t encoding = B14 | B9 | B8 | B6 |
158        rn << 3 | rd;
159    Emit16(encoding);
160  } else {
161    // 32 bit.
162    uint32_t op1 = 0b000;
163    uint32_t op2 = 0b00;
164    int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
165        op1 << 20 |
166        B15 | B14 | B13 | B12 |
167        op2 << 4 |
168        static_cast<uint32_t>(rd) << 8 |
169        static_cast<uint32_t>(rn) << 16 |
170        static_cast<uint32_t>(rm);
171
172    Emit32(encoding);
173  }
174}
175
176
177void Thumb2Assembler::mla(Register rd, Register rn, Register rm, Register ra,
178                          Condition cond) {
179  uint32_t op1 = 0b000;
180  uint32_t op2 = 0b00;
181  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
182      op1 << 20 |
183      op2 << 4 |
184      static_cast<uint32_t>(rd) << 8 |
185      static_cast<uint32_t>(ra) << 12 |
186      static_cast<uint32_t>(rn) << 16 |
187      static_cast<uint32_t>(rm);
188
189  Emit32(encoding);
190}
191
192
193void Thumb2Assembler::mls(Register rd, Register rn, Register rm, Register ra,
194                          Condition cond) {
195  uint32_t op1 = 0b000;
196  uint32_t op2 = 0b01;
197  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 |
198      op1 << 20 |
199      op2 << 4 |
200      static_cast<uint32_t>(rd) << 8 |
201      static_cast<uint32_t>(ra) << 12 |
202      static_cast<uint32_t>(rn) << 16 |
203      static_cast<uint32_t>(rm);
204
205  Emit32(encoding);
206}
207
208
209void Thumb2Assembler::umull(Register rd_lo, Register rd_hi, Register rn,
210                            Register rm, Condition cond) {
211  uint32_t op1 = 0b010;
212  uint32_t op2 = 0b0000;
213  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 |
214      op1 << 20 |
215      op2 << 4 |
216      static_cast<uint32_t>(rd_lo) << 12 |
217      static_cast<uint32_t>(rd_hi) << 8 |
218      static_cast<uint32_t>(rn) << 16 |
219      static_cast<uint32_t>(rm);
220
221  Emit32(encoding);
222}
223
224
225void Thumb2Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
226  uint32_t op1 = 0b001;
227  uint32_t op2 = 0b1111;
228  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B20 |
229      op1 << 20 |
230      op2 << 4 |
231      0xf << 12 |
232      static_cast<uint32_t>(rd) << 8 |
233      static_cast<uint32_t>(rn) << 16 |
234      static_cast<uint32_t>(rm);
235
236  Emit32(encoding);
237}
238
239
240void Thumb2Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
241  uint32_t op1 = 0b001;
242  uint32_t op2 = 0b1111;
243  int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 | B24 | B23 | B21 | B20 |
244      op1 << 20 |
245      op2 << 4 |
246      0xf << 12 |
247      static_cast<uint32_t>(rd) << 8 |
248      static_cast<uint32_t>(rn) << 16 |
249      static_cast<uint32_t>(rm);
250
251  Emit32(encoding);
252}
253
254
255void Thumb2Assembler::ldr(Register rd, const Address& ad, Condition cond) {
256  EmitLoadStore(cond, true, false, false, false, rd, ad);
257}
258
259
260void Thumb2Assembler::str(Register rd, const Address& ad, Condition cond) {
261  EmitLoadStore(cond, false, false, false, false, rd, ad);
262}
263
264
265void Thumb2Assembler::ldrb(Register rd, const Address& ad, Condition cond) {
266  EmitLoadStore(cond, true, true, false, false, rd, ad);
267}
268
269
270void Thumb2Assembler::strb(Register rd, const Address& ad, Condition cond) {
271  EmitLoadStore(cond, false, true, false, false, rd, ad);
272}
273
274
275void Thumb2Assembler::ldrh(Register rd, const Address& ad, Condition cond) {
276  EmitLoadStore(cond, true, false, true, false, rd, ad);
277}
278
279
280void Thumb2Assembler::strh(Register rd, const Address& ad, Condition cond) {
281  EmitLoadStore(cond, false, false, true, false, rd, ad);
282}
283
284
285void Thumb2Assembler::ldrsb(Register rd, const Address& ad, Condition cond) {
286  EmitLoadStore(cond, true, true, false, true, rd, ad);
287}
288
289
290void Thumb2Assembler::ldrsh(Register rd, const Address& ad, Condition cond) {
291  EmitLoadStore(cond, true, false, true, true, rd, ad);
292}
293
294
295void Thumb2Assembler::ldrd(Register rd, const Address& ad, Condition cond) {
296  CHECK_EQ(rd % 2, 0);
297  // This is different from other loads.  The encoding is like ARM.
298  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
299      static_cast<int32_t>(rd) << 12 |
300      (static_cast<int32_t>(rd) + 1) << 8 |
301      ad.encodingThumbLdrdStrd();
302  Emit32(encoding);
303}
304
305
306void Thumb2Assembler::strd(Register rd, const Address& ad, Condition cond) {
307  CHECK_EQ(rd % 2, 0);
308  // This is different from other loads.  The encoding is like ARM.
309  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
310      static_cast<int32_t>(rd) << 12 |
311      (static_cast<int32_t>(rd) + 1) << 8 |
312      ad.encodingThumbLdrdStrd();
313  Emit32(encoding);
314}
315
316
317void Thumb2Assembler::ldm(BlockAddressMode am,
318                          Register base,
319                          RegList regs,
320                          Condition cond) {
321  if (__builtin_popcount(regs) == 1) {
322    // Thumb doesn't support one reg in the list.
323    // Find the register number.
324    int reg = 0;
325    while (reg < 16) {
326      if ((regs & (1 << reg)) != 0) {
327         break;
328      }
329      ++reg;
330    }
331    CHECK_LT(reg, 16);
332    CHECK(am == DB_W);      // Only writeback is supported.
333    ldr(static_cast<Register>(reg), Address(base, kRegisterSize, Address::PostIndex), cond);
334  } else {
335    EmitMultiMemOp(cond, am, true, base, regs);
336  }
337}
338
339
340void Thumb2Assembler::stm(BlockAddressMode am,
341                          Register base,
342                          RegList regs,
343                          Condition cond) {
344  if (__builtin_popcount(regs) == 1) {
345    // Thumb doesn't support one reg in the list.
346    // Find the register number.
347    int reg = 0;
348    while (reg < 16) {
349      if ((regs & (1 << reg)) != 0) {
350         break;
351      }
352      ++reg;
353    }
354    CHECK_LT(reg, 16);
355    CHECK(am == IA || am == IA_W);
356    Address::Mode strmode = am == IA ? Address::PreIndex : Address::Offset;
357    str(static_cast<Register>(reg), Address(base, -kRegisterSize, strmode), cond);
358  } else {
359    EmitMultiMemOp(cond, am, false, base, regs);
360  }
361}
362
363
364bool Thumb2Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
365  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
366  if (((imm32 & ((1 << 19) - 1)) == 0) &&
367      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
368       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
369    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
370        ((imm32 >> 19) & ((1 << 6) -1));
371    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
372               sd, S0, S0);
373    return true;
374  }
375  return false;
376}
377
378
379bool Thumb2Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
380  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
381  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
382      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
383       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
384    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
385        ((imm64 >> 48) & ((1 << 6) -1));
386    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
387               dd, D0, D0);
388    return true;
389  }
390  return false;
391}
392
393
394void Thumb2Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
395  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
396}
397
398
399void Thumb2Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
400  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
401}
402
403
404void Thumb2Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
405                            Condition cond) {
406  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
407}
408
409
410void Thumb2Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
411                            Condition cond) {
412  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
413}
414
415
416void Thumb2Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
417                            Condition cond) {
418  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
419}
420
421
422void Thumb2Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
423                            Condition cond) {
424  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
425}
426
427
428void Thumb2Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
429                            Condition cond) {
430  EmitVFPsss(cond, B21, sd, sn, sm);
431}
432
433
434void Thumb2Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
435                            Condition cond) {
436  EmitVFPddd(cond, B21, dd, dn, dm);
437}
438
439
440void Thumb2Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
441                            Condition cond) {
442  EmitVFPsss(cond, 0, sd, sn, sm);
443}
444
445
446void Thumb2Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
447                            Condition cond) {
448  EmitVFPddd(cond, 0, dd, dn, dm);
449}
450
451
452void Thumb2Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
453                            Condition cond) {
454  EmitVFPsss(cond, B6, sd, sn, sm);
455}
456
457
458void Thumb2Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
459                            Condition cond) {
460  EmitVFPddd(cond, B6, dd, dn, dm);
461}
462
463
464void Thumb2Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
465                            Condition cond) {
466  EmitVFPsss(cond, B23, sd, sn, sm);
467}
468
469
470void Thumb2Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
471                            Condition cond) {
472  EmitVFPddd(cond, B23, dd, dn, dm);
473}
474
475
476void Thumb2Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
477  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
478}
479
480
481void Thumb2Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
482  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
483}
484
485
486void Thumb2Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
487  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
488}
489
490
491void Thumb2Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
492  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
493}
494
495
496void Thumb2Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
497  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
498}
499
500void Thumb2Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
501  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
502}
503
504
505void Thumb2Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
506  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
507}
508
509
510void Thumb2Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
511  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
512}
513
514
515void Thumb2Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
516  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
517}
518
519
520void Thumb2Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
521  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
522}
523
524
525void Thumb2Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
526  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
527}
528
529
530void Thumb2Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
531  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
532}
533
534
535void Thumb2Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
536  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
537}
538
539
540void Thumb2Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
541  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
542}
543
544
545void Thumb2Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
546  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
547}
548
549
550void Thumb2Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
551  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
552}
553
554
555void Thumb2Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
556  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
557}
558
559
560void Thumb2Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
561  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
562}
563
564
565void Thumb2Assembler::vcmpsz(SRegister sd, Condition cond) {
566  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
567}
568
569
570void Thumb2Assembler::vcmpdz(DRegister dd, Condition cond) {
571  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
572}
573
574void Thumb2Assembler::b(Label* label, Condition cond) {
575  EmitBranch(cond, label, false, false);
576}
577
578
579void Thumb2Assembler::bl(Label* label, Condition cond) {
580  CheckCondition(cond);
581  EmitBranch(cond, label, true, false);
582}
583
584
585void Thumb2Assembler::blx(Label* label) {
586  EmitBranch(AL, label, true, true);
587}
588
589
590void Thumb2Assembler::MarkExceptionHandler(Label* label) {
591  EmitDataProcessing(AL, TST, 1, PC, R0, ShifterOperand(0));
592  Label l;
593  b(&l);
594  EmitBranch(AL, label, false, false);
595  Bind(&l);
596}
597
598
599void Thumb2Assembler::Emit32(int32_t value) {
600  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
601  buffer_.Emit<int16_t>(value >> 16);
602  buffer_.Emit<int16_t>(value & 0xffff);
603}
604
605
606void Thumb2Assembler::Emit16(int16_t value) {
607  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
608  buffer_.Emit<int16_t>(value);
609}
610
611
612bool Thumb2Assembler::Is32BitDataProcessing(Condition cond,
613                                            Opcode opcode,
614                                            int set_cc,
615                                            Register rn,
616                                            Register rd,
617                                            const ShifterOperand& so) {
618  if (force_32bit_) {
619    return true;
620  }
621
622  bool can_contain_high_register = opcode == MOV || opcode == ADD || opcode == SUB;
623
624  if (IsHighRegister(rd) || IsHighRegister(rn)) {
625    if (can_contain_high_register) {
626      // There are high register instructions available for this opcode.
627      // However, there is no RRX available.
628      if (so.IsShift() && so.GetShift() == RRX) {
629        return true;
630      }
631
632      // Check special case for SP relative ADD and SUB immediate.
633      if ((opcode == ADD || opcode == SUB) && so.IsImmediate()) {
634        // If rn is SP and rd is a high register we need to use a 32 bit encoding.
635         if (rn == SP && rd != SP && IsHighRegister(rd)) {
636           return true;
637         }
638
639         uint32_t imm = so.GetImmediate();
640         // If the immediates are out of range use 32 bit.
641         if (rd == SP && rn == SP) {
642           if (imm > (1 << 9)) {    // 9 bit immediate.
643             return true;
644           }
645         } else if (opcode == ADD && rd != SP && rn == SP) {   // 10 bit immediate.
646           if (imm > (1 << 10)) {
647             return true;
648           }
649         } else if (opcode == SUB && rd != SP && rn == SP) {
650           // SUB rd, SP, #imm is always 32 bit.
651           return true;
652         }
653      }
654    }
655
656    // The ADD,SUB and MOV instructions that work with high registers don't have
657    // immediate variants.
658    if (so.IsImmediate()) {
659      return true;
660    }
661  }
662
663  if (so.IsRegister() && IsHighRegister(so.GetRegister()) && !can_contain_high_register) {
664    return true;
665  }
666
667  // Check for MOV with an ROR.
668  if (opcode == MOV && so.IsRegister() && so.IsShift() && so.GetShift() == ROR) {
669    if (so.GetImmediate() != 0) {
670      return true;
671    }
672  }
673
674  bool rn_is_valid = true;
675
676  // Check for single operand instructions and ADD/SUB.
677  switch (opcode) {
678    case CMP:
679    case MOV:
680    case TST:
681    case MVN:
682      rn_is_valid = false;      // There is no Rn for these instructions.
683      break;
684    case TEQ:
685      return true;
686      break;
687    case ADD:
688    case SUB:
689      break;
690    default:
691      if (so.IsRegister() && rd != rn) {
692        return true;
693      }
694  }
695
696  if (so.IsImmediate()) {
697    if (rn_is_valid && rn != rd) {
698      // The only thumb1 instruction with a register and an immediate are ADD and SUB.  The
699      // immediate must be 3 bits.
700      if (opcode != ADD && opcode != SUB) {
701        return true;
702      } else {
703        // Check that the immediate is 3 bits for ADD and SUB.
704        if (so.GetImmediate() >= 8) {
705          return true;
706        }
707      }
708    } else {
709      // ADD, SUB, CMP and MOV may be thumb1 only if the immediate is 8 bits.
710      if (!(opcode == ADD || opcode == SUB || opcode == MOV || opcode == CMP)) {
711        return true;
712      } else {
713        if (so.GetImmediate() > 255) {
714          return true;
715        }
716      }
717    }
718  }
719
720  // The instruction can be encoded in 16 bits.
721  return false;
722}
723
724
725void Thumb2Assembler::Emit32BitDataProcessing(Condition cond,
726                                              Opcode opcode,
727                                              int set_cc,
728                                              Register rn,
729                                              Register rd,
730                                              const ShifterOperand& so) {
731  uint8_t thumb_opcode = 0b11111111;
732  switch (opcode) {
733    case AND: thumb_opcode = 0b0000; break;
734    case EOR: thumb_opcode = 0b0100; break;
735    case SUB: thumb_opcode = 0b1101; break;
736    case RSB: thumb_opcode = 0b1110; break;
737    case ADD: thumb_opcode = 0b1000; break;
738    case ADC: thumb_opcode = 0b1010; break;
739    case SBC: thumb_opcode = 0b1011; break;
740    case RSC: break;
741    case TST: thumb_opcode = 0b0000; set_cc = true; rd = PC; break;
742    case TEQ: thumb_opcode = 0b0100; set_cc = true; rd = PC; break;
743    case CMP: thumb_opcode = 0b1101; set_cc = true; rd = PC; break;
744    case CMN: thumb_opcode = 0b1000; set_cc = true; rd = PC; break;
745    case ORR: thumb_opcode = 0b0010; break;
746    case MOV: thumb_opcode = 0b0010; rn = PC; break;
747    case BIC: thumb_opcode = 0b0001; break;
748    case MVN: thumb_opcode = 0b0011; rn = PC; break;
749    default:
750      break;
751  }
752
753  if (thumb_opcode == 0b11111111) {
754    LOG(FATAL) << "Invalid thumb2 opcode " << opcode;
755  }
756
757  int32_t encoding = 0;
758  if (so.IsImmediate()) {
759    // Check special cases.
760    if ((opcode == SUB || opcode == ADD) && rn == SP) {
761      // There are special ADD/SUB rd, SP, #imm12 instructions.
762      if (opcode == SUB) {
763        thumb_opcode = 0b0101;
764      } else {
765        thumb_opcode = 0;
766      }
767      uint32_t imm = so.GetImmediate();
768      CHECK_LT(imm, (1u << 12));
769
770      uint32_t i = (imm >> 11) & 1;
771      uint32_t imm3 = (imm >> 8) & 0b111;
772      uint32_t imm8 = imm & 0xff;
773
774      encoding = B31 | B30 | B29 | B28 | B25 |
775           B19 | B18 | B16 |
776           thumb_opcode << 21 |
777           rd << 8 |
778           i << 26 |
779           imm3 << 12 |
780           imm8;
781    } else {
782      // Modified immediate.
783      uint32_t imm = ModifiedImmediate(so.encodingThumb());
784      if (imm == kInvalidModifiedImmediate) {
785        LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate";
786      }
787      encoding = B31 | B30 | B29 | B28 |
788          thumb_opcode << 21 |
789          set_cc << 20 |
790          rn << 16 |
791          rd << 8 |
792          imm;
793    }
794  } else if (so.IsRegister()) {
795     // Register (possibly shifted)
796     encoding = B31 | B30 | B29 | B27 | B25 |
797         thumb_opcode << 21 |
798         set_cc << 20 |
799         rn << 16 |
800         rd << 8 |
801         so.encodingThumb();
802  }
803  Emit32(encoding);
804}
805
806
807void Thumb2Assembler::Emit16BitDataProcessing(Condition cond,
808                                              Opcode opcode,
809                                              int set_cc,
810                                              Register rn,
811                                              Register rd,
812                                              const ShifterOperand& so) {
813  if (opcode == ADD || opcode == SUB) {
814    Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so);
815    return;
816  }
817  uint8_t thumb_opcode = 0b11111111;
818  // Thumb1.
819  uint8_t dp_opcode = 0b01;
820  uint8_t opcode_shift = 6;
821  uint8_t rd_shift = 0;
822  uint8_t rn_shift = 3;
823  uint8_t immediate_shift = 0;
824  bool use_immediate = false;
825  uint8_t immediate = 0;
826
827  if (opcode == MOV && so.IsRegister() && so.IsShift()) {
828    // Convert shifted mov operand2 into 16 bit opcodes.
829    dp_opcode = 0;
830    opcode_shift = 11;
831
832    use_immediate = true;
833    immediate = so.GetImmediate();
834    immediate_shift = 6;
835
836    rn = so.GetRegister();
837
838    switch (so.GetShift()) {
839    case LSL: thumb_opcode = 0b00; break;
840    case LSR: thumb_opcode = 0b01; break;
841    case ASR: thumb_opcode = 0b10; break;
842    case ROR:
843      // ROR doesn't allow immediates.
844      thumb_opcode = 0b111;
845      dp_opcode = 0b01;
846      opcode_shift = 6;
847      use_immediate = false;
848      break;
849    case RRX: break;
850    default:
851     break;
852    }
853  } else {
854    if (so.IsImmediate()) {
855      use_immediate = true;
856      immediate = so.GetImmediate();
857    }
858
859    switch (opcode) {
860      case AND: thumb_opcode = 0b0000; break;
861      case EOR: thumb_opcode = 0b0001; break;
862      case SUB: break;
863      case RSB: thumb_opcode = 0b1001; break;
864      case ADD: break;
865      case ADC: thumb_opcode = 0b0101; break;
866      case SBC: thumb_opcode = 0b0110; break;
867      case RSC: break;
868      case TST: thumb_opcode = 0b1000; rn = so.GetRegister(); break;
869      case TEQ: break;
870      case CMP:
871        if (use_immediate) {
872          // T2 encoding.
873           dp_opcode = 0;
874           opcode_shift = 11;
875           thumb_opcode = 0b101;
876           rd_shift = 8;
877           rn_shift = 8;
878        } else {
879          thumb_opcode = 0b1010;
880          rd = rn;
881          rn = so.GetRegister();
882        }
883
884        break;
885      case CMN: thumb_opcode = 0b1011; rn = so.GetRegister(); break;
886      case ORR: thumb_opcode = 0b1100; break;
887      case MOV:
888        dp_opcode = 0;
889        if (use_immediate) {
890          // T2 encoding.
891          opcode_shift = 11;
892          thumb_opcode = 0b100;
893          rd_shift = 8;
894          rn_shift = 8;
895        } else {
896          rn = so.GetRegister();
897          if (IsHighRegister(rn) || IsHighRegister(rd)) {
898            // Special mov for high registers.
899            dp_opcode = 0b01;
900            opcode_shift = 7;
901            // Put the top bit of rd into the bottom bit of the opcode.
902            thumb_opcode = 0b0001100 | static_cast<uint32_t>(rd) >> 3;
903            rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
904          } else {
905            thumb_opcode = 0;
906          }
907        }
908        break;
909      case BIC: thumb_opcode = 0b1110; break;
910      case MVN: thumb_opcode = 0b1111; rn = so.GetRegister(); break;
911      default:
912        break;
913    }
914  }
915
916  if (thumb_opcode == 0b11111111) {
917    LOG(FATAL) << "Invalid thumb1 opcode " << opcode;
918  }
919
920  int16_t encoding = dp_opcode << 14 |
921      (thumb_opcode << opcode_shift) |
922      rd << rd_shift |
923      rn << rn_shift |
924      (use_immediate ? (immediate << immediate_shift) : 0);
925
926  Emit16(encoding);
927}
928
929
930// ADD and SUB are complex enough to warrant their own emitter.
931void Thumb2Assembler::Emit16BitAddSub(Condition cond,
932                                      Opcode opcode,
933                                      int set_cc,
934                                      Register rn,
935                                      Register rd,
936                                      const ShifterOperand& so) {
937  uint8_t dp_opcode = 0;
938  uint8_t opcode_shift = 6;
939  uint8_t rd_shift = 0;
940  uint8_t rn_shift = 3;
941  uint8_t immediate_shift = 0;
942  bool use_immediate = false;
943  uint8_t immediate = 0;
944  uint8_t thumb_opcode;;
945
946  if (so.IsImmediate()) {
947    use_immediate = true;
948    immediate = so.GetImmediate();
949  }
950
951  switch (opcode) {
952    case ADD:
953      if (so.IsRegister()) {
954        Register rm = so.GetRegister();
955        if (rn == rd) {
956          // Can use T2 encoding (allows 4 bit registers)
957          dp_opcode = 0b01;
958          opcode_shift = 10;
959          thumb_opcode = 0b0001;
960          // Make Rn also contain the top bit of rd.
961          rn = static_cast<Register>(static_cast<uint32_t>(rm) |
962                                     (static_cast<uint32_t>(rd) & 0b1000) << 1);
963          rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
964        } else {
965          // T1.
966          opcode_shift = 9;
967          thumb_opcode = 0b01100;
968          immediate = static_cast<uint32_t>(so.GetRegister());
969          use_immediate = true;
970          immediate_shift = 6;
971        }
972      } else {
973        // Immediate.
974        if (rd == SP && rn == SP) {
975          // ADD sp, sp, #imm
976          dp_opcode = 0b10;
977          thumb_opcode = 0b11;
978          opcode_shift = 12;
979          CHECK_LT(immediate, (1 << 9));
980          CHECK_EQ((immediate & 0b11), 0);
981
982          // Remove rd and rn from instruction by orring it with immed and clearing bits.
983          rn = R0;
984          rd = R0;
985          rd_shift = 0;
986          rn_shift = 0;
987          immediate >>= 2;
988        } else if (rd != SP && rn == SP) {
989          // ADD rd, SP, #imm
990          dp_opcode = 0b10;
991          thumb_opcode = 0b101;
992          opcode_shift = 11;
993          CHECK_LT(immediate, (1 << 10));
994          CHECK_EQ((immediate & 0b11), 0);
995
996          // Remove rn from instruction.
997          rn = R0;
998          rn_shift = 0;
999          rd_shift = 8;
1000          immediate >>= 2;
1001        } else if (rn != rd) {
1002          // Must use T1.
1003          opcode_shift = 9;
1004          thumb_opcode = 0b01110;
1005          immediate_shift = 6;
1006        } else {
1007          // T2 encoding.
1008          opcode_shift = 11;
1009          thumb_opcode = 0b110;
1010          rd_shift = 8;
1011          rn_shift = 8;
1012        }
1013      }
1014      break;
1015
1016    case SUB:
1017      if (so.IsRegister()) {
1018         // T1.
1019         opcode_shift = 9;
1020         thumb_opcode = 0b01101;
1021         immediate = static_cast<uint32_t>(so.GetRegister());
1022         use_immediate = true;
1023         immediate_shift = 6;
1024       } else {
1025         if (rd == SP && rn == SP) {
1026           // SUB sp, sp, #imm
1027           dp_opcode = 0b10;
1028           thumb_opcode = 0b1100001;
1029           opcode_shift = 7;
1030           CHECK_LT(immediate, (1 << 9));
1031           CHECK_EQ((immediate & 0b11), 0);
1032
1033           // Remove rd and rn from instruction by orring it with immed and clearing bits.
1034           rn = R0;
1035           rd = R0;
1036           rd_shift = 0;
1037           rn_shift = 0;
1038           immediate >>= 2;
1039         } else if (rn != rd) {
1040           // Must use T1.
1041           opcode_shift = 9;
1042           thumb_opcode = 0b01111;
1043           immediate_shift = 6;
1044         } else {
1045           // T2 encoding.
1046           opcode_shift = 11;
1047           thumb_opcode = 0b111;
1048           rd_shift = 8;
1049           rn_shift = 8;
1050         }
1051       }
1052      break;
1053    default:
1054      LOG(FATAL) << "This opcode is not an ADD or SUB: " << opcode;
1055      return;
1056  }
1057
1058  int16_t encoding = dp_opcode << 14 |
1059      (thumb_opcode << opcode_shift) |
1060      rd << rd_shift |
1061      rn << rn_shift |
1062      (use_immediate ? (immediate << immediate_shift) : 0);
1063
1064  Emit16(encoding);
1065}
1066
1067
1068void Thumb2Assembler::EmitDataProcessing(Condition cond,
1069                                         Opcode opcode,
1070                                         int set_cc,
1071                                         Register rn,
1072                                         Register rd,
1073                                         const ShifterOperand& so) {
1074  CHECK_NE(rd, kNoRegister);
1075  CheckCondition(cond);
1076
1077  if (Is32BitDataProcessing(cond, opcode, set_cc, rn, rd, so)) {
1078    Emit32BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1079  } else {
1080    Emit16BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1081  }
1082}
1083
1084void Thumb2Assembler::EmitShift(Register rd, Register rm, Shift shift, uint8_t amount, bool setcc) {
1085  CHECK_LT(amount, (1 << 5));
1086  if (IsHighRegister(rd) || IsHighRegister(rm) || shift == ROR || shift == RRX) {
1087    uint16_t opcode = 0;
1088    switch (shift) {
1089      case LSL: opcode = 0b00; break;
1090      case LSR: opcode = 0b01; break;
1091      case ASR: opcode = 0b10; break;
1092      case ROR: opcode = 0b11; break;
1093      case RRX: opcode = 0b11; amount = 0; break;
1094      default:
1095        LOG(FATAL) << "Unsupported thumb2 shift opcode";
1096    }
1097    // 32 bit.
1098    int32_t encoding = B31 | B30 | B29 | B27 | B25 | B22 |
1099        0xf << 16 | (setcc ? B20 : 0);
1100    uint32_t imm3 = amount >> 2;
1101    uint32_t imm2 = amount & 0b11;
1102    encoding |= imm3 << 12 | imm2 << 6 | static_cast<int16_t>(rm) |
1103        static_cast<int16_t>(rd) << 8 | opcode << 4;
1104    Emit32(encoding);
1105  } else {
1106    // 16 bit shift
1107    uint16_t opcode = 0;
1108    switch (shift) {
1109      case LSL: opcode = 0b00; break;
1110      case LSR: opcode = 0b01; break;
1111      case ASR: opcode = 0b10; break;
1112      default:
1113         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1114    }
1115    int16_t encoding = opcode << 11 | amount << 6 | static_cast<int16_t>(rm) << 3 |
1116        static_cast<int16_t>(rd);
1117    Emit16(encoding);
1118  }
1119}
1120
1121void Thumb2Assembler::EmitShift(Register rd, Register rn, Shift shift, Register rm, bool setcc) {
1122  CHECK_NE(shift, RRX);
1123  bool must_be_32bit = false;
1124  if (IsHighRegister(rd) || IsHighRegister(rm) || IsHighRegister(rn) || rd != rn) {
1125    must_be_32bit = true;
1126  }
1127
1128  if (must_be_32bit) {
1129    uint16_t opcode = 0;
1130     switch (shift) {
1131       case LSL: opcode = 0b00; break;
1132       case LSR: opcode = 0b01; break;
1133       case ASR: opcode = 0b10; break;
1134       case ROR: opcode = 0b11; break;
1135       default:
1136         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1137     }
1138     // 32 bit.
1139     int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 |
1140         0xf << 12 | (setcc ? B20 : 0);
1141     encoding |= static_cast<int16_t>(rn) << 16 | static_cast<int16_t>(rm) |
1142         static_cast<int16_t>(rd) << 8 | opcode << 21;
1143     Emit32(encoding);
1144  } else {
1145    uint16_t opcode = 0;
1146    switch (shift) {
1147      case LSL: opcode = 0b0010; break;
1148      case LSR: opcode = 0b0011; break;
1149      case ASR: opcode = 0b0100; break;
1150      default:
1151         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1152    }
1153    int16_t encoding = B14 | opcode << 6 | static_cast<int16_t>(rm) << 3 |
1154        static_cast<int16_t>(rd);
1155    Emit16(encoding);
1156  }
1157}
1158
1159
1160
1161void Thumb2Assembler::Branch::Emit(AssemblerBuffer* buffer) const {
1162  bool link = type_ == kUnconditionalLinkX || type_ == kUnconditionalLink;
1163  bool x = type_ == kUnconditionalX || type_ == kUnconditionalLinkX;
1164  int32_t offset = target_ - location_;
1165
1166  if (size_ == k32Bit) {
1167    int32_t encoding = B31 | B30 | B29 | B28 | B15;
1168    if (link) {
1169      // BL or BLX immediate.
1170      encoding |= B14;
1171      if (!x) {
1172        encoding |= B12;
1173      } else {
1174        // Bottom bit of offset must be 0.
1175        CHECK_EQ((offset & 1), 0);
1176      }
1177    } else {
1178      if (x) {
1179        LOG(FATAL) << "Invalid use of BX";
1180      } else {
1181        if (cond_ == AL) {
1182          // Can use the T4 encoding allowing a 24 bit offset.
1183          if (!x) {
1184            encoding |= B12;
1185          }
1186        } else {
1187          // Must be T3 encoding with a 20 bit offset.
1188          encoding |= cond_ << 22;
1189        }
1190      }
1191    }
1192    encoding = Thumb2Assembler::EncodeBranchOffset(offset, encoding);
1193    buffer->Store<int16_t>(location_, static_cast<int16_t>(encoding >> 16));
1194    buffer->Store<int16_t>(location_+2, static_cast<int16_t>(encoding & 0xffff));
1195  } else {
1196    if (IsCompareAndBranch()) {
1197      offset -= 4;
1198      uint16_t i = (offset >> 6) & 1;
1199      uint16_t imm5 = (offset >> 1) & 0b11111;
1200      int16_t encoding = B15 | B13 | B12 |
1201            (type_ ==  kCompareAndBranchNonZero ? B11 : 0) |
1202            static_cast<uint32_t>(rn_) |
1203            B8 |
1204            i << 9 |
1205            imm5 << 3;
1206      buffer->Store<int16_t>(location_, encoding);
1207    } else {
1208      offset -= 4;    // Account for PC offset.
1209      int16_t encoding;
1210      // 16 bit.
1211      if (cond_ == AL) {
1212        encoding = B15 | B14 | B13 |
1213            ((offset >> 1) & 0x7ff);
1214      } else {
1215        encoding = B15 | B14 | B12 |
1216            cond_ << 8 | ((offset >> 1) & 0xff);
1217      }
1218      buffer->Store<int16_t>(location_, encoding);
1219    }
1220  }
1221}
1222
1223
1224uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
1225  uint32_t location = buffer_.Size();
1226
1227  // This is always unresolved as it must be a forward branch.
1228  Emit16(prev);      // Previous link.
1229  return AddBranch(n ? Branch::kCompareAndBranchNonZero : Branch::kCompareAndBranchZero,
1230      location, rn);
1231}
1232
1233
1234// NOTE: this only support immediate offsets, not [rx,ry].
1235// TODO: support [rx,ry] instructions.
1236void Thumb2Assembler::EmitLoadStore(Condition cond,
1237                                    bool load,
1238                                    bool byte,
1239                                    bool half,
1240                                    bool is_signed,
1241                                    Register rd,
1242                                    const Address& ad) {
1243  CHECK_NE(rd, kNoRegister);
1244  CheckCondition(cond);
1245  bool must_be_32bit = force_32bit_;
1246  if (IsHighRegister(rd)) {
1247    must_be_32bit = true;
1248  }
1249
1250  Register rn = ad.GetRegister();
1251  if (IsHighRegister(rn) && rn != SP && rn != PC) {
1252    must_be_32bit = true;
1253  }
1254
1255  if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) {
1256    must_be_32bit = true;
1257  }
1258
1259  if (ad.IsImmediate()) {
1260    // Immediate offset
1261    int32_t offset = ad.GetOffset();
1262
1263    // The 16 bit SP relative instruction can only have a 10 bit offset.
1264    if (rn == SP && offset >= (1 << 10)) {
1265      must_be_32bit = true;
1266    }
1267
1268    if (byte) {
1269      // 5 bit offset, no shift.
1270      if (offset >= (1 << 5)) {
1271        must_be_32bit = true;
1272      }
1273    } else if (half) {
1274      // 6 bit offset, shifted by 1.
1275      if (offset >= (1 << 6)) {
1276        must_be_32bit = true;
1277      }
1278    } else {
1279      // 7 bit offset, shifted by 2.
1280      if (offset >= (1 << 7)) {
1281        must_be_32bit = true;
1282      }
1283    }
1284
1285    if (must_be_32bit) {
1286      int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1287          (load ? B20 : 0) |
1288          (is_signed ? B24 : 0) |
1289          static_cast<uint32_t>(rd) << 12 |
1290          ad.encodingThumb(true) |
1291          (byte ? 0 : half ? B21 : B22);
1292      Emit32(encoding);
1293    } else {
1294      // 16 bit thumb1.
1295      uint8_t opA = 0;
1296      bool sp_relative = false;
1297
1298      if (byte) {
1299        opA = 0b0111;
1300      } else if (half) {
1301        opA = 0b1000;
1302      } else {
1303        if (rn == SP) {
1304          opA = 0b1001;
1305          sp_relative = true;
1306        } else {
1307          opA = 0b0110;
1308        }
1309      }
1310      int16_t encoding = opA << 12 |
1311          (load ? B11 : 0);
1312
1313      CHECK_GE(offset, 0);
1314      if (sp_relative) {
1315        // SP relative, 10 bit offset.
1316        CHECK_LT(offset, (1 << 10));
1317        CHECK_EQ((offset & 0b11), 0);
1318        encoding |= rd << 8 | offset >> 2;
1319      } else {
1320        // No SP relative.  The offset is shifted right depending on
1321        // the size of the load/store.
1322        encoding |= static_cast<uint32_t>(rd);
1323
1324        if (byte) {
1325          // 5 bit offset, no shift.
1326          CHECK_LT(offset, (1 << 5));
1327        } else if (half) {
1328          // 6 bit offset, shifted by 1.
1329          CHECK_LT(offset, (1 << 6));
1330          CHECK_EQ((offset & 0b1), 0);
1331          offset >>= 1;
1332        } else {
1333          // 7 bit offset, shifted by 2.
1334          CHECK_LT(offset, (1 << 7));
1335          CHECK_EQ((offset & 0b11), 0);
1336          offset >>= 2;
1337        }
1338        encoding |= rn << 3 | offset  << 6;
1339      }
1340
1341      Emit16(encoding);
1342    }
1343  } else {
1344    // Register shift.
1345    if (ad.GetRegister() == PC) {
1346       // PC relative literal encoding.
1347      int32_t offset = ad.GetOffset();
1348      if (must_be_32bit || offset < 0 || offset >= (1 << 10) || !load) {
1349        int32_t up = B23;
1350        if (offset < 0) {
1351          offset = -offset;
1352          up = 0;
1353        }
1354        CHECK_LT(offset, (1 << 12));
1355        int32_t encoding = 0x1f << 27 | 0xf << 16 | B22 | (load ? B20 : 0) |
1356            offset | up |
1357            static_cast<uint32_t>(rd) << 12;
1358        Emit32(encoding);
1359      } else {
1360        // 16 bit literal load.
1361        CHECK_GE(offset, 0);
1362        CHECK_LT(offset, (1 << 10));
1363        int32_t encoding = B14 | (load ? B11 : 0) | static_cast<uint32_t>(rd) << 8 | offset >> 2;
1364        Emit16(encoding);
1365      }
1366    } else {
1367      if (ad.GetShiftCount() != 0) {
1368        // If there is a shift count this must be 32 bit.
1369        must_be_32bit = true;
1370      } else if (IsHighRegister(ad.GetRegisterOffset())) {
1371        must_be_32bit = true;
1372      }
1373
1374      if (must_be_32bit) {
1375        int32_t encoding = 0x1f << 27 | B22 | (load ? B20 : 0) | static_cast<uint32_t>(rd) << 12 |
1376            ad.encodingThumb(true);
1377        Emit32(encoding);
1378      } else {
1379        // 16 bit register offset.
1380        int32_t encoding = B14 | B12 | (load ? B11 : 0) | static_cast<uint32_t>(rd) |
1381            ad.encodingThumb(false);
1382        Emit16(encoding);
1383      }
1384    }
1385  }
1386}
1387
1388
1389void Thumb2Assembler::EmitMultiMemOp(Condition cond,
1390                                     BlockAddressMode am,
1391                                     bool load,
1392                                     Register base,
1393                                     RegList regs) {
1394  CHECK_NE(base, kNoRegister);
1395  CheckCondition(cond);
1396  bool must_be_32bit = force_32bit_;
1397
1398  if ((regs & 0xff00) != 0) {
1399    must_be_32bit = true;
1400  }
1401
1402  uint32_t w_bit = am == IA_W || am == DB_W || am == DA_W || am == IB_W;
1403  // 16 bit always uses writeback.
1404  if (!w_bit) {
1405    must_be_32bit = true;
1406  }
1407
1408  if (must_be_32bit) {
1409    uint32_t op = 0;
1410    switch (am) {
1411      case IA:
1412      case IA_W:
1413        op = 0b01;
1414        break;
1415      case DB:
1416      case DB_W:
1417        op = 0b10;
1418        break;
1419      case DA:
1420      case IB:
1421      case DA_W:
1422      case IB_W:
1423        LOG(FATAL) << "LDM/STM mode not supported on thumb: " << am;
1424    }
1425    if (load) {
1426      // Cannot have SP in the list.
1427      CHECK_EQ((regs & (1 << SP)), 0);
1428    } else {
1429      // Cannot have PC or SP in the list.
1430      CHECK_EQ((regs & (1 << PC | 1 << SP)), 0);
1431    }
1432    int32_t encoding = B31 | B30 | B29 | B27 |
1433                    (op << 23) |
1434                    (load ? B20 : 0) |
1435                    base << 16 |
1436                    regs |
1437                    (w_bit << 21);
1438    Emit32(encoding);
1439  } else {
1440    int16_t encoding = B15 | B14 |
1441                    (load ? B11 : 0) |
1442                    base << 8 |
1443                    regs;
1444    Emit16(encoding);
1445  }
1446}
1447
1448
1449void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
1450  uint32_t pc = buffer_.Size();
1451  Branch::Type branch_type;
1452  if (cond == AL) {
1453    if (link) {
1454      if (x) {
1455        branch_type = Branch::kUnconditionalLinkX;      // BLX.
1456      } else {
1457        branch_type = Branch::kUnconditionalLink;       // BX.
1458      }
1459    } else {
1460      branch_type = Branch::kUnconditional;             // B.
1461    }
1462  } else {
1463    branch_type = Branch::kConditional;                 // B<cond>.
1464  }
1465
1466  if (label->IsBound()) {
1467    Branch::Size size = AddBranch(branch_type, pc, label->Position(), cond);  // Resolved branch.
1468
1469    // The branch is to a bound label which means that it's a backwards branch.  We know the
1470    // current size of it so we can emit the appropriate space.  Note that if it's a 16 bit
1471    // branch the size may change if it so happens that other branches change size that change
1472    // the distance to the target and that distance puts this branch over the limit for 16 bits.
1473    if (size == Branch::k16Bit) {
1474      DCHECK(!force_32bit_branches_);
1475      Emit16(0);          // Space for a 16 bit branch.
1476    } else {
1477      Emit32(0);            // Space for a 32 bit branch.
1478    }
1479  } else {
1480    // Branch is to an unbound label.  Emit space for it.
1481    uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
1482    if (force_32bit_branches_ || force_32bit_) {
1483      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1484      Emit16(0);                   // another 16 bits.
1485    } else {
1486      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1487    }
1488    label->LinkTo(branch_id);           // Link to the branch ID.
1489  }
1490}
1491
1492
1493void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) {
1494  CHECK_NE(rd, kNoRegister);
1495  CHECK_NE(rm, kNoRegister);
1496  CheckCondition(cond);
1497  CHECK_NE(rd, PC);
1498  CHECK_NE(rm, PC);
1499  int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1500      B25 | B23 | B21 | B20 |
1501      static_cast<uint32_t>(rm) << 16 |
1502      0xf << 12 |
1503      static_cast<uint32_t>(rd) << 8 |
1504      B7 |
1505      static_cast<uint32_t>(rm);
1506  Emit32(encoding);
1507}
1508
1509
1510void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
1511  CheckCondition(cond);
1512  bool must_be_32bit = force_32bit_;
1513  if (IsHighRegister(rd)|| imm16 >= 256u) {
1514    must_be_32bit = true;
1515  }
1516
1517  if (must_be_32bit) {
1518    // Use encoding T3.
1519    uint32_t imm4 = (imm16 >> 12) & 0b1111;
1520    uint32_t i = (imm16 >> 11) & 0b1;
1521    uint32_t imm3 = (imm16 >> 8) & 0b111;
1522    uint32_t imm8 = imm16 & 0xff;
1523    int32_t encoding = B31 | B30 | B29 | B28 |
1524                    B25 | B22 |
1525                    static_cast<uint32_t>(rd) << 8 |
1526                    i << 26 |
1527                    imm4 << 16 |
1528                    imm3 << 12 |
1529                    imm8;
1530    Emit32(encoding);
1531  } else {
1532    int16_t encoding = B13 | static_cast<uint16_t>(rd) << 8 |
1533                imm16;
1534    Emit16(encoding);
1535  }
1536}
1537
1538
1539void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
1540  CheckCondition(cond);
1541  // Always 32 bits.
1542  uint32_t imm4 = (imm16 >> 12) & 0b1111;
1543  uint32_t i = (imm16 >> 11) & 0b1;
1544  uint32_t imm3 = (imm16 >> 8) & 0b111;
1545  uint32_t imm8 = imm16 & 0xff;
1546  int32_t encoding = B31 | B30 | B29 | B28 |
1547                  B25 | B23 | B22 |
1548                  static_cast<uint32_t>(rd) << 8 |
1549                  i << 26 |
1550                  imm4 << 16 |
1551                  imm3 << 12 |
1552                  imm8;
1553  Emit32(encoding);
1554}
1555
1556
1557void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) {
1558  CHECK_NE(rn, kNoRegister);
1559  CHECK_NE(rt, kNoRegister);
1560  CheckCondition(cond);
1561  CHECK_NE(rn, kNoRegister);
1562  CHECK_NE(rt, kNoRegister);
1563  CheckCondition(cond);
1564  CHECK_LT(imm, (1u << 10));
1565
1566  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
1567      static_cast<uint32_t>(rn) << 16 |
1568      static_cast<uint32_t>(rt) << 12 |
1569      0xf << 8 |
1570      imm >> 2;
1571  Emit32(encoding);
1572}
1573
1574
1575void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) {
1576  ldrex(rt, rn, 0, cond);
1577}
1578
1579
1580void Thumb2Assembler::strex(Register rd,
1581                            Register rt,
1582                            Register rn,
1583                            uint16_t imm,
1584                            Condition cond) {
1585  CHECK_NE(rn, kNoRegister);
1586  CHECK_NE(rd, kNoRegister);
1587  CHECK_NE(rt, kNoRegister);
1588  CheckCondition(cond);
1589  CHECK_LT(imm, (1u << 10));
1590
1591  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
1592      static_cast<uint32_t>(rn) << 16 |
1593      static_cast<uint32_t>(rt) << 12 |
1594      static_cast<uint32_t>(rd) << 8 |
1595      imm >> 2;
1596  Emit32(encoding);
1597}
1598
1599
1600void Thumb2Assembler::strex(Register rd,
1601                            Register rt,
1602                            Register rn,
1603                            Condition cond) {
1604  strex(rd, rt, rn, 0, cond);
1605}
1606
1607
1608void Thumb2Assembler::clrex(Condition cond) {
1609  CheckCondition(cond);
1610  int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 |
1611      B21 | B20 |
1612      0xf << 16 |
1613      B15 |
1614      0xf << 8 |
1615      B5 |
1616      0xf;
1617  Emit32(encoding);
1618}
1619
1620
1621void Thumb2Assembler::nop(Condition cond) {
1622  CheckCondition(cond);
1623  int16_t encoding = B15 | B13 | B12 |
1624      B11 | B10 | B9 | B8;
1625  Emit16(encoding);
1626}
1627
1628
1629void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
1630  CHECK_NE(sn, kNoSRegister);
1631  CHECK_NE(rt, kNoRegister);
1632  CHECK_NE(rt, SP);
1633  CHECK_NE(rt, PC);
1634  CheckCondition(cond);
1635  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1636                     B27 | B26 | B25 |
1637                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1638                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1639                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1640  Emit32(encoding);
1641}
1642
1643
1644void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
1645  CHECK_NE(sn, kNoSRegister);
1646  CHECK_NE(rt, kNoRegister);
1647  CHECK_NE(rt, SP);
1648  CHECK_NE(rt, PC);
1649  CheckCondition(cond);
1650  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1651                     B27 | B26 | B25 | B20 |
1652                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1653                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1654                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1655  Emit32(encoding);
1656}
1657
1658
1659void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
1660                              Condition cond) {
1661  CHECK_NE(sm, kNoSRegister);
1662  CHECK_NE(sm, S31);
1663  CHECK_NE(rt, kNoRegister);
1664  CHECK_NE(rt, SP);
1665  CHECK_NE(rt, PC);
1666  CHECK_NE(rt2, kNoRegister);
1667  CHECK_NE(rt2, SP);
1668  CHECK_NE(rt2, PC);
1669  CheckCondition(cond);
1670  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1671                     B27 | B26 | B22 |
1672                     (static_cast<int32_t>(rt2)*B16) |
1673                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1674                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1675                     (static_cast<int32_t>(sm) >> 1);
1676  Emit32(encoding);
1677}
1678
1679
1680void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
1681                              Condition cond) {
1682  CHECK_NE(sm, kNoSRegister);
1683  CHECK_NE(sm, S31);
1684  CHECK_NE(rt, kNoRegister);
1685  CHECK_NE(rt, SP);
1686  CHECK_NE(rt, PC);
1687  CHECK_NE(rt2, kNoRegister);
1688  CHECK_NE(rt2, SP);
1689  CHECK_NE(rt2, PC);
1690  CHECK_NE(rt, rt2);
1691  CheckCondition(cond);
1692  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1693                     B27 | B26 | B22 | B20 |
1694                     (static_cast<int32_t>(rt2)*B16) |
1695                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1696                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1697                     (static_cast<int32_t>(sm) >> 1);
1698  Emit32(encoding);
1699}
1700
1701
1702void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
1703                              Condition cond) {
1704  CHECK_NE(dm, kNoDRegister);
1705  CHECK_NE(rt, kNoRegister);
1706  CHECK_NE(rt, SP);
1707  CHECK_NE(rt, PC);
1708  CHECK_NE(rt2, kNoRegister);
1709  CHECK_NE(rt2, SP);
1710  CHECK_NE(rt2, PC);
1711  CheckCondition(cond);
1712  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1713                     B27 | B26 | B22 |
1714                     (static_cast<int32_t>(rt2)*B16) |
1715                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1716                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1717                     (static_cast<int32_t>(dm) & 0xf);
1718  Emit32(encoding);
1719}
1720
1721
1722void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
1723                              Condition cond) {
1724  CHECK_NE(dm, kNoDRegister);
1725  CHECK_NE(rt, kNoRegister);
1726  CHECK_NE(rt, SP);
1727  CHECK_NE(rt, PC);
1728  CHECK_NE(rt2, kNoRegister);
1729  CHECK_NE(rt2, SP);
1730  CHECK_NE(rt2, PC);
1731  CHECK_NE(rt, rt2);
1732  CheckCondition(cond);
1733  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1734                     B27 | B26 | B22 | B20 |
1735                     (static_cast<int32_t>(rt2)*B16) |
1736                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1737                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1738                     (static_cast<int32_t>(dm) & 0xf);
1739  Emit32(encoding);
1740}
1741
1742
1743void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
1744  const Address& addr = static_cast<const Address&>(ad);
1745  CHECK_NE(sd, kNoSRegister);
1746  CheckCondition(cond);
1747  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1748                     B27 | B26 | B24 | B20 |
1749                     ((static_cast<int32_t>(sd) & 1)*B22) |
1750                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1751                     B11 | B9 | addr.vencoding();
1752  Emit32(encoding);
1753}
1754
1755
1756void Thumb2Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
1757  const Address& addr = static_cast<const Address&>(ad);
1758  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1759  CHECK_NE(sd, kNoSRegister);
1760  CheckCondition(cond);
1761  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1762                     B27 | B26 | B24 |
1763                     ((static_cast<int32_t>(sd) & 1)*B22) |
1764                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1765                     B11 | B9 | addr.vencoding();
1766  Emit32(encoding);
1767}
1768
1769
1770void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
1771  const Address& addr = static_cast<const Address&>(ad);
1772  CHECK_NE(dd, kNoDRegister);
1773  CheckCondition(cond);
1774  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1775                     B27 | B26 | B24 | B20 |
1776                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1777                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1778                     B11 | B9 | B8 | addr.vencoding();
1779  Emit32(encoding);
1780}
1781
1782
1783void Thumb2Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
1784  const Address& addr = static_cast<const Address&>(ad);
1785  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1786  CHECK_NE(dd, kNoDRegister);
1787  CheckCondition(cond);
1788  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1789                     B27 | B26 | B24 |
1790                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1791                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1792                     B11 | B9 | B8 | addr.vencoding();
1793  Emit32(encoding);
1794}
1795
1796
1797void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
1798  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
1799}
1800
1801
1802void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
1803  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
1804}
1805
1806
1807void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) {
1808  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
1809}
1810
1811
1812void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
1813  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
1814}
1815
1816
1817void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
1818  CheckCondition(cond);
1819
1820  uint32_t D;
1821  uint32_t Vd;
1822  if (dbl) {
1823    // Encoded as D:Vd.
1824    D = (reg >> 4) & 1;
1825    Vd = reg & 0b1111;
1826  } else {
1827    // Encoded as Vd:D.
1828    D = reg & 1;
1829    Vd = (reg >> 1) & 0b1111;
1830  }
1831  int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
1832                    B11 | B9 |
1833        (dbl ? B8 : 0) |
1834        (push ? B24 : (B23 | B20)) |
1835        0b1110 << 28 |
1836        nregs << (dbl ? 1 : 0) |
1837        D << 22 |
1838        Vd << 12;
1839  Emit32(encoding);
1840}
1841
1842
1843void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode,
1844                                 SRegister sd, SRegister sn, SRegister sm) {
1845  CHECK_NE(sd, kNoSRegister);
1846  CHECK_NE(sn, kNoSRegister);
1847  CHECK_NE(sm, kNoSRegister);
1848  CheckCondition(cond);
1849  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1850                     B27 | B26 | B25 | B11 | B9 | opcode |
1851                     ((static_cast<int32_t>(sd) & 1)*B22) |
1852                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1853                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1854                     ((static_cast<int32_t>(sn) & 1)*B7) |
1855                     ((static_cast<int32_t>(sm) & 1)*B5) |
1856                     (static_cast<int32_t>(sm) >> 1);
1857  Emit32(encoding);
1858}
1859
1860
1861void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode,
1862                                 DRegister dd, DRegister dn, DRegister dm) {
1863  CHECK_NE(dd, kNoDRegister);
1864  CHECK_NE(dn, kNoDRegister);
1865  CHECK_NE(dm, kNoDRegister);
1866  CheckCondition(cond);
1867  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1868                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1869                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1870                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
1871                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1872                     ((static_cast<int32_t>(dn) >> 4)*B7) |
1873                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1874                     (static_cast<int32_t>(dm) & 0xf);
1875  Emit32(encoding);
1876}
1877
1878
1879void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1880                                SRegister sd, DRegister dm) {
1881  CHECK_NE(sd, kNoSRegister);
1882  CHECK_NE(dm, kNoDRegister);
1883  CheckCondition(cond);
1884  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1885                     B27 | B26 | B25 | B11 | B9 | opcode |
1886                     ((static_cast<int32_t>(sd) & 1)*B22) |
1887                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1888                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1889                     (static_cast<int32_t>(dm) & 0xf);
1890  Emit32(encoding);
1891}
1892
1893
1894void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode,
1895                                DRegister dd, SRegister sm) {
1896  CHECK_NE(dd, kNoDRegister);
1897  CHECK_NE(sm, kNoSRegister);
1898  CheckCondition(cond);
1899  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1900                     B27 | B26 | B25 | B11 | B9 | opcode |
1901                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1902                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1903                     ((static_cast<int32_t>(sm) & 1)*B5) |
1904                     (static_cast<int32_t>(sm) >> 1);
1905  Emit32(encoding);
1906}
1907
1908
1909void Thumb2Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR.
1910  CheckCondition(cond);
1911  UNIMPLEMENTED(FATAL) << "Unimplemented thumb instruction";
1912}
1913
1914
1915void Thumb2Assembler::svc(uint32_t imm8) {
1916  CHECK(IsUint(8, imm8)) << imm8;
1917  int16_t encoding = B15 | B14 | B12 |
1918       B11 | B10 | B9 | B8 |
1919       imm8;
1920  Emit16(encoding);
1921}
1922
1923
1924void Thumb2Assembler::bkpt(uint16_t imm8) {
1925  CHECK(IsUint(8, imm8)) << imm8;
1926  int16_t encoding = B15 | B13 | B12 |
1927      B11 | B10 | B9 |
1928      imm8;
1929  Emit16(encoding);
1930}
1931
1932// Convert the given IT state to a mask bit given bit 0 of the first
1933// condition and a shift position.
1934static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) {
1935  switch (s) {
1936  case kItOmitted: return 1 << shift;
1937  case kItThen: return firstcond0 << shift;
1938  case kItElse: return !firstcond0 << shift;
1939  }
1940  return 0;
1941}
1942
1943
1944// Set the IT condition in the given position for the given state.  This is used
1945// to check that conditional instructions match the preceding IT statement.
1946void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) {
1947  switch (s) {
1948  case kItOmitted: it_conditions_[index] = AL; break;
1949  case kItThen: it_conditions_[index] = cond; break;
1950  case kItElse:
1951    it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1);
1952    break;
1953  }
1954}
1955
1956
1957void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) {
1958  CheckCondition(AL);       // Not allowed in IT block.
1959  uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1;
1960
1961  // All conditions to AL.
1962  for (uint8_t i = 0; i < 4; ++i) {
1963    it_conditions_[i] = AL;
1964  }
1965
1966  SetItCondition(kItThen, firstcond, 0);
1967  uint8_t mask = ToItMask(i1, firstcond0, 3);
1968  SetItCondition(i1, firstcond, 1);
1969
1970  if (i1 != kItOmitted) {
1971    mask |= ToItMask(i2, firstcond0, 2);
1972    SetItCondition(i2, firstcond, 2);
1973    if (i2 != kItOmitted) {
1974      mask |= ToItMask(i3, firstcond0, 1);
1975      SetItCondition(i3, firstcond, 3);
1976      if (i3 != kItOmitted) {
1977        mask |= 0b0001;
1978      }
1979    }
1980  }
1981
1982  // Start at first condition.
1983  it_cond_index_ = 0;
1984  next_condition_ = it_conditions_[0];
1985  uint16_t encoding = B15 | B13 | B12 |
1986        B11 | B10 | B9 | B8 |
1987        firstcond << 4 |
1988        mask;
1989  Emit16(encoding);
1990}
1991
1992
1993void Thumb2Assembler::cbz(Register rn, Label* label) {
1994  CheckCondition(AL);
1995  if (label->IsBound()) {
1996    LOG(FATAL) << "cbz can only be used to branch forwards";
1997  } else {
1998    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
1999    label->LinkTo(branchid);
2000  }
2001}
2002
2003
2004void Thumb2Assembler::cbnz(Register rn, Label* label) {
2005  CheckCondition(AL);
2006  if (label->IsBound()) {
2007    LOG(FATAL) << "cbnz can only be used to branch forwards";
2008  } else {
2009    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
2010    label->LinkTo(branchid);
2011  }
2012}
2013
2014
2015void Thumb2Assembler::blx(Register rm, Condition cond) {
2016  CHECK_NE(rm, kNoRegister);
2017  CheckCondition(cond);
2018  int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3;
2019  Emit16(encoding);
2020}
2021
2022
2023void Thumb2Assembler::bx(Register rm, Condition cond) {
2024  CHECK_NE(rm, kNoRegister);
2025  CheckCondition(cond);
2026  int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3;
2027  Emit16(encoding);
2028}
2029
2030
2031void Thumb2Assembler::Push(Register rd, Condition cond) {
2032  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
2033}
2034
2035
2036void Thumb2Assembler::Pop(Register rd, Condition cond) {
2037  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
2038}
2039
2040
2041void Thumb2Assembler::PushList(RegList regs, Condition cond) {
2042  stm(DB_W, SP, regs, cond);
2043}
2044
2045
2046void Thumb2Assembler::PopList(RegList regs, Condition cond) {
2047  ldm(IA_W, SP, regs, cond);
2048}
2049
2050
2051void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
2052  if (cond != AL || rd != rm) {
2053    mov(rd, ShifterOperand(rm), cond);
2054  }
2055}
2056
2057
2058// A branch has changed size.  Make a hole for it.
2059void Thumb2Assembler::MakeHoleForBranch(uint32_t location, uint32_t delta) {
2060  // Move the contents of the buffer using: Move(newposition, oldposition)
2061  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2062  buffer_.Move(location + delta, location);
2063}
2064
2065
2066void Thumb2Assembler::Bind(Label* label) {
2067  CHECK(!label->IsBound());
2068  uint32_t bound_pc = buffer_.Size();
2069  std::vector<Branch*> changed_branches;
2070
2071  while (label->IsLinked()) {
2072    uint16_t position = label->Position();                  // Branch id for linked branch.
2073    Branch* branch = GetBranch(position);                   // Get the branch at this id.
2074    bool changed = branch->Resolve(bound_pc);               // Branch can be resolved now.
2075    uint32_t branch_location = branch->GetLocation();
2076    uint16_t next = buffer_.Load<uint16_t>(branch_location);       // Get next in chain.
2077    if (changed) {
2078      DCHECK(!force_32bit_branches_);
2079      MakeHoleForBranch(branch->GetLocation(), 2);
2080      if (branch->IsCompareAndBranch()) {
2081        // A cbz/cbnz instruction has changed size.  There is no valid encoding for
2082        // a 32 bit cbz/cbnz so we need to change this to an instruction pair:
2083        // cmp rn, #0
2084        // b<eq|ne> target
2085        bool n = branch->GetType() == Branch::kCompareAndBranchNonZero;
2086        Condition cond = n ? NE : EQ;
2087        branch->Move(2);      // Move the branch forward by 2 bytes.
2088        branch->ResetTypeAndCondition(Branch::kConditional, cond);
2089        branch->ResetSize(Branch::k16Bit);
2090
2091        // Now add a compare instruction in the place the branch was.
2092        int16_t cmp = B13 | B11 | static_cast<int16_t>(branch->GetRegister()) << 8;
2093        buffer_.Store<int16_t>(branch_location, cmp);
2094
2095        // Since have moved made a hole in the code we need to reload the
2096        // current pc.
2097        bound_pc = buffer_.Size();
2098
2099        // Now resolve the newly added branch.
2100        changed = branch->Resolve(bound_pc);
2101        if (changed) {
2102          MakeHoleForBranch(branch->GetLocation(), 2);
2103          changed_branches.push_back(branch);
2104        }
2105      } else {
2106        changed_branches.push_back(branch);
2107      }
2108    }
2109    label->position_ = next;                                // Move to next.
2110  }
2111  label->BindTo(bound_pc);
2112
2113  // Now relocate any changed branches.  Do this until there are no more changes.
2114  std::vector<Branch*> branches_to_process = changed_branches;
2115  while (branches_to_process.size() != 0) {
2116    changed_branches.clear();
2117    for (auto& changed_branch : branches_to_process) {
2118      for (auto& branch : branches_) {
2119        bool changed = branch->Relocate(changed_branch->GetLocation(), 2);
2120        if (changed) {
2121          changed_branches.push_back(branch);
2122        }
2123      }
2124      branches_to_process = changed_branches;
2125    }
2126  }
2127}
2128
2129
2130void Thumb2Assembler::EmitBranches() {
2131  for (auto& branch : branches_) {
2132    branch->Emit(&buffer_);
2133  }
2134}
2135
2136
2137void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
2138                          bool setcc, Condition cond) {
2139  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
2140  CheckCondition(cond);
2141  EmitShift(rd, rm, LSL, shift_imm, setcc);
2142}
2143
2144
2145void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
2146                          bool setcc, Condition cond) {
2147  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
2148  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2149  CheckCondition(cond);
2150  EmitShift(rd, rm, LSR, shift_imm, setcc);
2151}
2152
2153
2154void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
2155                          bool setcc, Condition cond) {
2156  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
2157  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2158  CheckCondition(cond);
2159  EmitShift(rd, rm, ASR, shift_imm, setcc);
2160}
2161
2162
2163void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
2164                          bool setcc, Condition cond) {
2165  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
2166  CheckCondition(cond);
2167  EmitShift(rd, rm, ROR, shift_imm, setcc);
2168}
2169
2170
2171void Thumb2Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
2172  CheckCondition(cond);
2173  EmitShift(rd, rm, RRX, rm, setcc);
2174}
2175
2176
2177void Thumb2Assembler::Lsl(Register rd, Register rm, Register rn,
2178                          bool setcc, Condition cond) {
2179  CheckCondition(cond);
2180  EmitShift(rd, rm, LSL, rn, setcc);
2181}
2182
2183
2184void Thumb2Assembler::Lsr(Register rd, Register rm, Register rn,
2185                          bool setcc, Condition cond) {
2186  CheckCondition(cond);
2187  EmitShift(rd, rm, LSR, rn, setcc);
2188}
2189
2190
2191void Thumb2Assembler::Asr(Register rd, Register rm, Register rn,
2192                          bool setcc, Condition cond) {
2193  CheckCondition(cond);
2194  EmitShift(rd, rm, ASR, rn, setcc);
2195}
2196
2197
2198void Thumb2Assembler::Ror(Register rd, Register rm, Register rn,
2199                          bool setcc, Condition cond) {
2200  CheckCondition(cond);
2201  EmitShift(rd, rm, ROR, rn, setcc);
2202}
2203
2204
2205int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
2206  // The offset is off by 4 due to the way the ARM CPUs read PC.
2207  offset -= 4;
2208  offset >>= 1;
2209
2210  uint32_t value = 0;
2211  // There are two different encodings depending on the value of bit 12.  In one case
2212  // intermediate values are calculated using the sign bit.
2213  if ((inst & B12) == B12) {
2214    // 25 bits of offset.
2215    uint32_t signbit = (offset >> 31) & 0x1;
2216    uint32_t i1 = (offset >> 22) & 0x1;
2217    uint32_t i2 = (offset >> 21) & 0x1;
2218    uint32_t imm10 = (offset >> 11) & 0x03ff;
2219    uint32_t imm11 = offset & 0x07ff;
2220    uint32_t j1 = (i1 ^ signbit) ? 0 : 1;
2221    uint32_t j2 = (i2 ^ signbit) ? 0 : 1;
2222    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) |
2223                      imm11;
2224    // Remove the offset from the current encoding.
2225    inst &= ~(0x3ff << 16 | 0x7ff);
2226  } else {
2227    uint32_t signbit = (offset >> 31) & 0x1;
2228    uint32_t imm6 = (offset >> 11) & 0x03f;
2229    uint32_t imm11 = offset & 0x07ff;
2230    uint32_t j1 = (offset >> 19) & 1;
2231    uint32_t j2 = (offset >> 17) & 1;
2232    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) |
2233        imm11;
2234    // Remove the offset from the current encoding.
2235    inst &= ~(0x3f << 16 | 0x7ff);
2236  }
2237  // Mask out offset bits in current instruction.
2238  inst &= ~(B26 | B13 | B11);
2239  inst |= value;
2240  return inst;
2241}
2242
2243
2244int Thumb2Assembler::DecodeBranchOffset(int32_t instr) {
2245  int32_t imm32;
2246  if ((instr & B12) == B12) {
2247    uint32_t S = (instr >> 26) & 1;
2248    uint32_t J2 = (instr >> 11) & 1;
2249    uint32_t J1 = (instr >> 13) & 1;
2250    uint32_t imm10 = (instr >> 16) & 0x3FF;
2251    uint32_t imm11 = instr & 0x7FF;
2252
2253    uint32_t I1 = ~(J1 ^ S) & 1;
2254    uint32_t I2 = ~(J2 ^ S) & 1;
2255    imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2256    imm32 = (imm32 << 8) >> 8;  // sign extend 24 bit immediate.
2257  } else {
2258    uint32_t S = (instr >> 26) & 1;
2259    uint32_t J2 = (instr >> 11) & 1;
2260    uint32_t J1 = (instr >> 13) & 1;
2261    uint32_t imm6 = (instr >> 16) & 0x3F;
2262    uint32_t imm11 = instr & 0x7FF;
2263
2264    imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2265    imm32 = (imm32 << 11) >> 11;  // sign extend 21 bit immediate.
2266  }
2267  imm32 += 4;
2268  return imm32;
2269}
2270
2271
2272void Thumb2Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
2273  AddConstant(rd, rd, value, cond);
2274}
2275
2276
2277void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value,
2278                                  Condition cond) {
2279  if (value == 0) {
2280    if (rd != rn) {
2281      mov(rd, ShifterOperand(rn), cond);
2282    }
2283    return;
2284  }
2285  // We prefer to select the shorter code sequence rather than selecting add for
2286  // positive values and sub for negatives ones, which would slightly improve
2287  // the readability of generated code for some constants.
2288  ShifterOperand shifter_op;
2289  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2290    add(rd, rn, shifter_op, cond);
2291  } else if (ShifterOperand::CanHoldThumb(rd, rn, SUB, -value, &shifter_op)) {
2292    sub(rd, rn, shifter_op, cond);
2293  } else {
2294    CHECK(rn != IP);
2295    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2296      mvn(IP, shifter_op, cond);
2297      add(rd, rn, ShifterOperand(IP), cond);
2298    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2299      mvn(IP, shifter_op, cond);
2300      sub(rd, rn, ShifterOperand(IP), cond);
2301    } else {
2302      movw(IP, Low16Bits(value), cond);
2303      uint16_t value_high = High16Bits(value);
2304      if (value_high != 0) {
2305        movt(IP, value_high, cond);
2306      }
2307      add(rd, rn, ShifterOperand(IP), cond);
2308    }
2309  }
2310}
2311
2312
2313void Thumb2Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
2314                                          Condition cond) {
2315  ShifterOperand shifter_op;
2316  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2317    adds(rd, rn, shifter_op, cond);
2318  } else if (ShifterOperand::CanHoldThumb(rd, rn, ADD, -value, &shifter_op)) {
2319    subs(rd, rn, shifter_op, cond);
2320  } else {
2321    CHECK(rn != IP);
2322    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2323      mvn(IP, shifter_op, cond);
2324      adds(rd, rn, ShifterOperand(IP), cond);
2325    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2326      mvn(IP, shifter_op, cond);
2327      subs(rd, rn, ShifterOperand(IP), cond);
2328    } else {
2329      movw(IP, Low16Bits(value), cond);
2330      uint16_t value_high = High16Bits(value);
2331      if (value_high != 0) {
2332        movt(IP, value_high, cond);
2333      }
2334      adds(rd, rn, ShifterOperand(IP), cond);
2335    }
2336  }
2337}
2338
2339
2340void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2341  ShifterOperand shifter_op;
2342  if (ShifterOperand::CanHoldThumb(rd, R0, MOV, value, &shifter_op)) {
2343    mov(rd, shifter_op, cond);
2344  } else if (ShifterOperand::CanHoldThumb(rd, R0, MVN, ~value, &shifter_op)) {
2345    mvn(rd, shifter_op, cond);
2346  } else {
2347    movw(rd, Low16Bits(value), cond);
2348    uint16_t value_high = High16Bits(value);
2349    if (value_high != 0) {
2350      movt(rd, value_high, cond);
2351    }
2352  }
2353}
2354
2355// Implementation note: this method must emit at most one instruction when
2356// Address::CanHoldLoadOffsetThumb.
2357void Thumb2Assembler::LoadFromOffset(LoadOperandType type,
2358                                     Register reg,
2359                                     Register base,
2360                                     int32_t offset,
2361                                     Condition cond) {
2362  if (!Address::CanHoldLoadOffsetThumb(type, offset)) {
2363    CHECK(base != IP);
2364    LoadImmediate(IP, offset, cond);
2365    add(IP, IP, ShifterOperand(base), cond);
2366    base = IP;
2367    offset = 0;
2368  }
2369  CHECK(Address::CanHoldLoadOffsetThumb(type, offset));
2370  switch (type) {
2371    case kLoadSignedByte:
2372      ldrsb(reg, Address(base, offset), cond);
2373      break;
2374    case kLoadUnsignedByte:
2375      ldrb(reg, Address(base, offset), cond);
2376      break;
2377    case kLoadSignedHalfword:
2378      ldrsh(reg, Address(base, offset), cond);
2379      break;
2380    case kLoadUnsignedHalfword:
2381      ldrh(reg, Address(base, offset), cond);
2382      break;
2383    case kLoadWord:
2384      ldr(reg, Address(base, offset), cond);
2385      break;
2386    case kLoadWordPair:
2387      ldrd(reg, Address(base, offset), cond);
2388      break;
2389    default:
2390      LOG(FATAL) << "UNREACHABLE";
2391  }
2392}
2393
2394
2395// Implementation note: this method must emit at most one instruction when
2396// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2397void Thumb2Assembler::LoadSFromOffset(SRegister reg,
2398                                      Register base,
2399                                      int32_t offset,
2400                                      Condition cond) {
2401  if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) {
2402    CHECK_NE(base, IP);
2403    LoadImmediate(IP, offset, cond);
2404    add(IP, IP, ShifterOperand(base), cond);
2405    base = IP;
2406    offset = 0;
2407  }
2408  CHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset));
2409  vldrs(reg, Address(base, offset), cond);
2410}
2411
2412
2413// Implementation note: this method must emit at most one instruction when
2414// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2415void Thumb2Assembler::LoadDFromOffset(DRegister reg,
2416                                      Register base,
2417                                      int32_t offset,
2418                                      Condition cond) {
2419  if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) {
2420    CHECK_NE(base, IP);
2421    LoadImmediate(IP, offset, cond);
2422    add(IP, IP, ShifterOperand(base), cond);
2423    base = IP;
2424    offset = 0;
2425  }
2426  CHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset));
2427  vldrd(reg, Address(base, offset), cond);
2428}
2429
2430
2431// Implementation note: this method must emit at most one instruction when
2432// Address::CanHoldStoreOffsetThumb.
2433void Thumb2Assembler::StoreToOffset(StoreOperandType type,
2434                                    Register reg,
2435                                    Register base,
2436                                    int32_t offset,
2437                                    Condition cond) {
2438  if (!Address::CanHoldStoreOffsetThumb(type, offset)) {
2439    CHECK(reg != IP);
2440    CHECK(base != IP);
2441    LoadImmediate(IP, offset, cond);
2442    add(IP, IP, ShifterOperand(base), cond);
2443    base = IP;
2444    offset = 0;
2445  }
2446  CHECK(Address::CanHoldStoreOffsetThumb(type, offset));
2447  switch (type) {
2448    case kStoreByte:
2449      strb(reg, Address(base, offset), cond);
2450      break;
2451    case kStoreHalfword:
2452      strh(reg, Address(base, offset), cond);
2453      break;
2454    case kStoreWord:
2455      str(reg, Address(base, offset), cond);
2456      break;
2457    case kStoreWordPair:
2458      strd(reg, Address(base, offset), cond);
2459      break;
2460    default:
2461      LOG(FATAL) << "UNREACHABLE";
2462  }
2463}
2464
2465
2466// Implementation note: this method must emit at most one instruction when
2467// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset.
2468void Thumb2Assembler::StoreSToOffset(SRegister reg,
2469                                     Register base,
2470                                     int32_t offset,
2471                                     Condition cond) {
2472  if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) {
2473    CHECK_NE(base, IP);
2474    LoadImmediate(IP, offset, cond);
2475    add(IP, IP, ShifterOperand(base), cond);
2476    base = IP;
2477    offset = 0;
2478  }
2479  CHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset));
2480  vstrs(reg, Address(base, offset), cond);
2481}
2482
2483
2484// Implementation note: this method must emit at most one instruction when
2485// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset.
2486void Thumb2Assembler::StoreDToOffset(DRegister reg,
2487                                     Register base,
2488                                     int32_t offset,
2489                                     Condition cond) {
2490  if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) {
2491    CHECK_NE(base, IP);
2492    LoadImmediate(IP, offset, cond);
2493    add(IP, IP, ShifterOperand(base), cond);
2494    base = IP;
2495    offset = 0;
2496  }
2497  CHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset));
2498  vstrd(reg, Address(base, offset), cond);
2499}
2500
2501
2502void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) {
2503  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
2504#if ANDROID_SMP != 0
2505  int32_t encoding = 0xf3bf8f5f;  // dmb in T1 encoding.
2506  Emit32(encoding);
2507#endif
2508}
2509
2510
2511void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
2512  cbz(r, label);
2513}
2514
2515
2516void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
2517  cbnz(r, label);
2518}
2519}  // namespace arm
2520}  // namespace art
2521