assembler_thumb2.cc revision 1a43dd78d054dbad8d7af9ba4829ea2f1cb70b53
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)
623      || ((opcode == ADD || opcode == SUB) && (rn == rd));
624
625  if (IsHighRegister(rd) || IsHighRegister(rn)) {
626    if (can_contain_high_register) {
627      // There are high register instructions available for this opcode.
628      // However, there is no RRX available.
629      if (so.IsShift() && so.GetShift() == RRX) {
630        return true;
631      }
632
633      // Check special case for SP relative ADD and SUB immediate.
634      if ((opcode == ADD || opcode == SUB) && so.IsImmediate()) {
635        // If rn is SP and rd is a high register we need to use a 32 bit encoding.
636         if (rn == SP && rd != SP && IsHighRegister(rd)) {
637           return true;
638         }
639
640         uint32_t imm = so.GetImmediate();
641         // If the immediates are out of range use 32 bit.
642         if (rd == SP && rn == SP) {
643           if (imm > (1 << 9)) {    // 9 bit immediate.
644             return true;
645           }
646         } else if (opcode == ADD && rd != SP && rn == SP) {   // 10 bit immediate.
647           if (imm > (1 << 10)) {
648             return true;
649           }
650         } else if (opcode == SUB && rd != SP && rn == SP) {
651           // SUB rd, SP, #imm is always 32 bit.
652           return true;
653         }
654      }
655    }
656
657    // The ADD,SUB and MOV instructions that work with high registers don't have
658    // immediate variants.
659    if (so.IsImmediate()) {
660      return true;
661    }
662  }
663
664  if (so.IsRegister() && IsHighRegister(so.GetRegister()) && !can_contain_high_register) {
665    return true;
666  }
667
668  // Check for MOV with an ROR.
669  if (opcode == MOV && so.IsRegister() && so.IsShift() && so.GetShift() == ROR) {
670    if (so.GetImmediate() != 0) {
671      return true;
672    }
673  }
674
675  bool rn_is_valid = true;
676
677  // Check for single operand instructions and ADD/SUB.
678  switch (opcode) {
679    case CMP:
680    case MOV:
681    case TST:
682    case MVN:
683      rn_is_valid = false;      // There is no Rn for these instructions.
684      break;
685    case TEQ:
686      return true;
687      break;
688    case ADD:
689    case SUB:
690      break;
691    default:
692      if (so.IsRegister() && rd != rn) {
693        return true;
694      }
695  }
696
697  if (so.IsImmediate()) {
698    if (rn_is_valid && rn != rd) {
699      // The only thumb1 instruction with a register and an immediate are ADD and SUB.  The
700      // immediate must be 3 bits.
701      if (opcode != ADD && opcode != SUB) {
702        return true;
703      } else {
704        // Check that the immediate is 3 bits for ADD and SUB.
705        if (so.GetImmediate() >= 8) {
706          return true;
707        }
708      }
709    } else {
710      // ADD, SUB, CMP and MOV may be thumb1 only if the immediate is 8 bits.
711      if (!(opcode == ADD || opcode == SUB || opcode == MOV || opcode == CMP)) {
712        return true;
713      } else {
714        if (so.GetImmediate() > 255) {
715          return true;
716        }
717      }
718    }
719  }
720
721  // The instruction can be encoded in 16 bits.
722  return false;
723}
724
725
726void Thumb2Assembler::Emit32BitDataProcessing(Condition cond,
727                                              Opcode opcode,
728                                              int set_cc,
729                                              Register rn,
730                                              Register rd,
731                                              const ShifterOperand& so) {
732  uint8_t thumb_opcode = 0b11111111;
733  switch (opcode) {
734    case AND: thumb_opcode = 0b0000; break;
735    case EOR: thumb_opcode = 0b0100; break;
736    case SUB: thumb_opcode = 0b1101; break;
737    case RSB: thumb_opcode = 0b1110; break;
738    case ADD: thumb_opcode = 0b1000; break;
739    case ADC: thumb_opcode = 0b1010; break;
740    case SBC: thumb_opcode = 0b1011; break;
741    case RSC: break;
742    case TST: thumb_opcode = 0b0000; set_cc = true; rd = PC; break;
743    case TEQ: thumb_opcode = 0b0100; set_cc = true; rd = PC; break;
744    case CMP: thumb_opcode = 0b1101; set_cc = true; rd = PC; break;
745    case CMN: thumb_opcode = 0b1000; set_cc = true; rd = PC; break;
746    case ORR: thumb_opcode = 0b0010; break;
747    case MOV: thumb_opcode = 0b0010; rn = PC; break;
748    case BIC: thumb_opcode = 0b0001; break;
749    case MVN: thumb_opcode = 0b0011; rn = PC; break;
750    default:
751      break;
752  }
753
754  if (thumb_opcode == 0b11111111) {
755    LOG(FATAL) << "Invalid thumb2 opcode " << opcode;
756  }
757
758  int32_t encoding = 0;
759  if (so.IsImmediate()) {
760    // Check special cases.
761    if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12))) {
762      if (opcode == SUB) {
763        thumb_opcode = 0b0101;
764      } else {
765        thumb_opcode = 0;
766      }
767      uint32_t imm = so.GetImmediate();
768
769      uint32_t i = (imm >> 11) & 1;
770      uint32_t imm3 = (imm >> 8) & 0b111;
771      uint32_t imm8 = imm & 0xff;
772
773      encoding = B31 | B30 | B29 | B28 | B25 |
774           thumb_opcode << 21 |
775           rn << 16 |
776           rd << 8 |
777           i << 26 |
778           imm3 << 12 |
779           imm8;
780    } else {
781      // Modified immediate.
782      uint32_t imm = ModifiedImmediate(so.encodingThumb());
783      if (imm == kInvalidModifiedImmediate) {
784        LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate";
785      }
786      encoding = B31 | B30 | B29 | B28 |
787          thumb_opcode << 21 |
788          set_cc << 20 |
789          rn << 16 |
790          rd << 8 |
791          imm;
792    }
793  } else if (so.IsRegister()) {
794     // Register (possibly shifted)
795     encoding = B31 | B30 | B29 | B27 | B25 |
796         thumb_opcode << 21 |
797         set_cc << 20 |
798         rn << 16 |
799         rd << 8 |
800         so.encodingThumb();
801  }
802  Emit32(encoding);
803}
804
805
806void Thumb2Assembler::Emit16BitDataProcessing(Condition cond,
807                                              Opcode opcode,
808                                              int set_cc,
809                                              Register rn,
810                                              Register rd,
811                                              const ShifterOperand& so) {
812  if (opcode == ADD || opcode == SUB) {
813    Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so);
814    return;
815  }
816  uint8_t thumb_opcode = 0b11111111;
817  // Thumb1.
818  uint8_t dp_opcode = 0b01;
819  uint8_t opcode_shift = 6;
820  uint8_t rd_shift = 0;
821  uint8_t rn_shift = 3;
822  uint8_t immediate_shift = 0;
823  bool use_immediate = false;
824  uint8_t immediate = 0;
825
826  if (opcode == MOV && so.IsRegister() && so.IsShift()) {
827    // Convert shifted mov operand2 into 16 bit opcodes.
828    dp_opcode = 0;
829    opcode_shift = 11;
830
831    use_immediate = true;
832    immediate = so.GetImmediate();
833    immediate_shift = 6;
834
835    rn = so.GetRegister();
836
837    switch (so.GetShift()) {
838    case LSL: thumb_opcode = 0b00; break;
839    case LSR: thumb_opcode = 0b01; break;
840    case ASR: thumb_opcode = 0b10; break;
841    case ROR:
842      // ROR doesn't allow immediates.
843      thumb_opcode = 0b111;
844      dp_opcode = 0b01;
845      opcode_shift = 6;
846      use_immediate = false;
847      break;
848    case RRX: break;
849    default:
850     break;
851    }
852  } else {
853    if (so.IsImmediate()) {
854      use_immediate = true;
855      immediate = so.GetImmediate();
856    }
857
858    switch (opcode) {
859      case AND: thumb_opcode = 0b0000; break;
860      case EOR: thumb_opcode = 0b0001; break;
861      case SUB: break;
862      case RSB: thumb_opcode = 0b1001; break;
863      case ADD: break;
864      case ADC: thumb_opcode = 0b0101; break;
865      case SBC: thumb_opcode = 0b0110; break;
866      case RSC: break;
867      case TST: thumb_opcode = 0b1000; rn = so.GetRegister(); break;
868      case TEQ: break;
869      case CMP:
870        if (use_immediate) {
871          // T2 encoding.
872           dp_opcode = 0;
873           opcode_shift = 11;
874           thumb_opcode = 0b101;
875           rd_shift = 8;
876           rn_shift = 8;
877        } else {
878          thumb_opcode = 0b1010;
879          rd = rn;
880          rn = so.GetRegister();
881        }
882
883        break;
884      case CMN: {
885        thumb_opcode = 0b1011;
886        rd = rn;
887        rn = so.GetRegister();
888        break;
889      }
890      case ORR: thumb_opcode = 0b1100; break;
891      case MOV:
892        dp_opcode = 0;
893        if (use_immediate) {
894          // T2 encoding.
895          opcode_shift = 11;
896          thumb_opcode = 0b100;
897          rd_shift = 8;
898          rn_shift = 8;
899        } else {
900          rn = so.GetRegister();
901          if (IsHighRegister(rn) || IsHighRegister(rd)) {
902            // Special mov for high registers.
903            dp_opcode = 0b01;
904            opcode_shift = 7;
905            // Put the top bit of rd into the bottom bit of the opcode.
906            thumb_opcode = 0b0001100 | static_cast<uint32_t>(rd) >> 3;
907            rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
908          } else {
909            thumb_opcode = 0;
910          }
911        }
912        break;
913      case BIC: thumb_opcode = 0b1110; break;
914      case MVN: thumb_opcode = 0b1111; rn = so.GetRegister(); break;
915      default:
916        break;
917    }
918  }
919
920  if (thumb_opcode == 0b11111111) {
921    LOG(FATAL) << "Invalid thumb1 opcode " << opcode;
922  }
923
924  int16_t encoding = dp_opcode << 14 |
925      (thumb_opcode << opcode_shift) |
926      rd << rd_shift |
927      rn << rn_shift |
928      (use_immediate ? (immediate << immediate_shift) : 0);
929
930  Emit16(encoding);
931}
932
933
934// ADD and SUB are complex enough to warrant their own emitter.
935void Thumb2Assembler::Emit16BitAddSub(Condition cond,
936                                      Opcode opcode,
937                                      int set_cc,
938                                      Register rn,
939                                      Register rd,
940                                      const ShifterOperand& so) {
941  uint8_t dp_opcode = 0;
942  uint8_t opcode_shift = 6;
943  uint8_t rd_shift = 0;
944  uint8_t rn_shift = 3;
945  uint8_t immediate_shift = 0;
946  bool use_immediate = false;
947  uint8_t immediate = 0;
948  uint8_t thumb_opcode;;
949
950  if (so.IsImmediate()) {
951    use_immediate = true;
952    immediate = so.GetImmediate();
953  }
954
955  switch (opcode) {
956    case ADD:
957      if (so.IsRegister()) {
958        Register rm = so.GetRegister();
959        if (rn == rd) {
960          // Can use T2 encoding (allows 4 bit registers)
961          dp_opcode = 0b01;
962          opcode_shift = 10;
963          thumb_opcode = 0b0001;
964          // Make Rn also contain the top bit of rd.
965          rn = static_cast<Register>(static_cast<uint32_t>(rm) |
966                                     (static_cast<uint32_t>(rd) & 0b1000) << 1);
967          rd = static_cast<Register>(static_cast<uint32_t>(rd) & 0b111);
968        } else {
969          // T1.
970          opcode_shift = 9;
971          thumb_opcode = 0b01100;
972          immediate = static_cast<uint32_t>(so.GetRegister());
973          use_immediate = true;
974          immediate_shift = 6;
975        }
976      } else {
977        // Immediate.
978        if (rd == SP && rn == SP) {
979          // ADD sp, sp, #imm
980          dp_opcode = 0b10;
981          thumb_opcode = 0b11;
982          opcode_shift = 12;
983          CHECK_LT(immediate, (1 << 9));
984          CHECK_EQ((immediate & 0b11), 0);
985
986          // Remove rd and rn from instruction by orring it with immed and clearing bits.
987          rn = R0;
988          rd = R0;
989          rd_shift = 0;
990          rn_shift = 0;
991          immediate >>= 2;
992        } else if (rd != SP && rn == SP) {
993          // ADD rd, SP, #imm
994          dp_opcode = 0b10;
995          thumb_opcode = 0b101;
996          opcode_shift = 11;
997          CHECK_LT(immediate, (1 << 10));
998          CHECK_EQ((immediate & 0b11), 0);
999
1000          // Remove rn from instruction.
1001          rn = R0;
1002          rn_shift = 0;
1003          rd_shift = 8;
1004          immediate >>= 2;
1005        } else if (rn != rd) {
1006          // Must use T1.
1007          opcode_shift = 9;
1008          thumb_opcode = 0b01110;
1009          immediate_shift = 6;
1010        } else {
1011          // T2 encoding.
1012          opcode_shift = 11;
1013          thumb_opcode = 0b110;
1014          rd_shift = 8;
1015          rn_shift = 8;
1016        }
1017      }
1018      break;
1019
1020    case SUB:
1021      if (so.IsRegister()) {
1022         // T1.
1023         opcode_shift = 9;
1024         thumb_opcode = 0b01101;
1025         immediate = static_cast<uint32_t>(so.GetRegister());
1026         use_immediate = true;
1027         immediate_shift = 6;
1028       } else {
1029         if (rd == SP && rn == SP) {
1030           // SUB sp, sp, #imm
1031           dp_opcode = 0b10;
1032           thumb_opcode = 0b1100001;
1033           opcode_shift = 7;
1034           CHECK_LT(immediate, (1 << 9));
1035           CHECK_EQ((immediate & 0b11), 0);
1036
1037           // Remove rd and rn from instruction by orring it with immed and clearing bits.
1038           rn = R0;
1039           rd = R0;
1040           rd_shift = 0;
1041           rn_shift = 0;
1042           immediate >>= 2;
1043         } else if (rn != rd) {
1044           // Must use T1.
1045           opcode_shift = 9;
1046           thumb_opcode = 0b01111;
1047           immediate_shift = 6;
1048         } else {
1049           // T2 encoding.
1050           opcode_shift = 11;
1051           thumb_opcode = 0b111;
1052           rd_shift = 8;
1053           rn_shift = 8;
1054         }
1055       }
1056      break;
1057    default:
1058      LOG(FATAL) << "This opcode is not an ADD or SUB: " << opcode;
1059      return;
1060  }
1061
1062  int16_t encoding = dp_opcode << 14 |
1063      (thumb_opcode << opcode_shift) |
1064      rd << rd_shift |
1065      rn << rn_shift |
1066      (use_immediate ? (immediate << immediate_shift) : 0);
1067
1068  Emit16(encoding);
1069}
1070
1071
1072void Thumb2Assembler::EmitDataProcessing(Condition cond,
1073                                         Opcode opcode,
1074                                         int set_cc,
1075                                         Register rn,
1076                                         Register rd,
1077                                         const ShifterOperand& so) {
1078  CHECK_NE(rd, kNoRegister);
1079  CheckCondition(cond);
1080
1081  if (Is32BitDataProcessing(cond, opcode, set_cc, rn, rd, so)) {
1082    Emit32BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1083  } else {
1084    Emit16BitDataProcessing(cond, opcode, set_cc, rn, rd, so);
1085  }
1086}
1087
1088void Thumb2Assembler::EmitShift(Register rd, Register rm, Shift shift, uint8_t amount, bool setcc) {
1089  CHECK_LT(amount, (1 << 5));
1090  if (IsHighRegister(rd) || IsHighRegister(rm) || shift == ROR || shift == RRX) {
1091    uint16_t opcode = 0;
1092    switch (shift) {
1093      case LSL: opcode = 0b00; break;
1094      case LSR: opcode = 0b01; break;
1095      case ASR: opcode = 0b10; break;
1096      case ROR: opcode = 0b11; break;
1097      case RRX: opcode = 0b11; amount = 0; break;
1098      default:
1099        LOG(FATAL) << "Unsupported thumb2 shift opcode";
1100    }
1101    // 32 bit.
1102    int32_t encoding = B31 | B30 | B29 | B27 | B25 | B22 |
1103        0xf << 16 | (setcc ? B20 : 0);
1104    uint32_t imm3 = amount >> 2;
1105    uint32_t imm2 = amount & 0b11;
1106    encoding |= imm3 << 12 | imm2 << 6 | static_cast<int16_t>(rm) |
1107        static_cast<int16_t>(rd) << 8 | opcode << 4;
1108    Emit32(encoding);
1109  } else {
1110    // 16 bit shift
1111    uint16_t opcode = 0;
1112    switch (shift) {
1113      case LSL: opcode = 0b00; break;
1114      case LSR: opcode = 0b01; break;
1115      case ASR: opcode = 0b10; break;
1116      default:
1117         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1118    }
1119    int16_t encoding = opcode << 11 | amount << 6 | static_cast<int16_t>(rm) << 3 |
1120        static_cast<int16_t>(rd);
1121    Emit16(encoding);
1122  }
1123}
1124
1125void Thumb2Assembler::EmitShift(Register rd, Register rn, Shift shift, Register rm, bool setcc) {
1126  CHECK_NE(shift, RRX);
1127  bool must_be_32bit = false;
1128  if (IsHighRegister(rd) || IsHighRegister(rm) || IsHighRegister(rn) || rd != rn) {
1129    must_be_32bit = true;
1130  }
1131
1132  if (must_be_32bit) {
1133    uint16_t opcode = 0;
1134     switch (shift) {
1135       case LSL: opcode = 0b00; break;
1136       case LSR: opcode = 0b01; break;
1137       case ASR: opcode = 0b10; break;
1138       case ROR: opcode = 0b11; break;
1139       default:
1140         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1141     }
1142     // 32 bit.
1143     int32_t encoding = B31 | B30 | B29 | B28 | B27 | B25 |
1144         0xf << 12 | (setcc ? B20 : 0);
1145     encoding |= static_cast<int16_t>(rn) << 16 | static_cast<int16_t>(rm) |
1146         static_cast<int16_t>(rd) << 8 | opcode << 21;
1147     Emit32(encoding);
1148  } else {
1149    uint16_t opcode = 0;
1150    switch (shift) {
1151      case LSL: opcode = 0b0010; break;
1152      case LSR: opcode = 0b0011; break;
1153      case ASR: opcode = 0b0100; break;
1154      default:
1155         LOG(FATAL) << "Unsupported thumb2 shift opcode";
1156    }
1157    int16_t encoding = B14 | opcode << 6 | static_cast<int16_t>(rm) << 3 |
1158        static_cast<int16_t>(rd);
1159    Emit16(encoding);
1160  }
1161}
1162
1163
1164
1165void Thumb2Assembler::Branch::Emit(AssemblerBuffer* buffer) const {
1166  bool link = type_ == kUnconditionalLinkX || type_ == kUnconditionalLink;
1167  bool x = type_ == kUnconditionalX || type_ == kUnconditionalLinkX;
1168  int32_t offset = target_ - location_;
1169
1170  if (size_ == k32Bit) {
1171    int32_t encoding = B31 | B30 | B29 | B28 | B15;
1172    if (link) {
1173      // BL or BLX immediate.
1174      encoding |= B14;
1175      if (!x) {
1176        encoding |= B12;
1177      } else {
1178        // Bottom bit of offset must be 0.
1179        CHECK_EQ((offset & 1), 0);
1180      }
1181    } else {
1182      if (x) {
1183        LOG(FATAL) << "Invalid use of BX";
1184      } else {
1185        if (cond_ == AL) {
1186          // Can use the T4 encoding allowing a 24 bit offset.
1187          if (!x) {
1188            encoding |= B12;
1189          }
1190        } else {
1191          // Must be T3 encoding with a 20 bit offset.
1192          encoding |= cond_ << 22;
1193        }
1194      }
1195    }
1196    encoding = Thumb2Assembler::EncodeBranchOffset(offset, encoding);
1197    buffer->Store<int16_t>(location_, static_cast<int16_t>(encoding >> 16));
1198    buffer->Store<int16_t>(location_+2, static_cast<int16_t>(encoding & 0xffff));
1199  } else {
1200    if (IsCompareAndBranch()) {
1201      offset -= 4;
1202      uint16_t i = (offset >> 6) & 1;
1203      uint16_t imm5 = (offset >> 1) & 0b11111;
1204      int16_t encoding = B15 | B13 | B12 |
1205            (type_ ==  kCompareAndBranchNonZero ? B11 : 0) |
1206            static_cast<uint32_t>(rn_) |
1207            B8 |
1208            i << 9 |
1209            imm5 << 3;
1210      buffer->Store<int16_t>(location_, encoding);
1211    } else {
1212      offset -= 4;    // Account for PC offset.
1213      int16_t encoding;
1214      // 16 bit.
1215      if (cond_ == AL) {
1216        encoding = B15 | B14 | B13 |
1217            ((offset >> 1) & 0x7ff);
1218      } else {
1219        encoding = B15 | B14 | B12 |
1220            cond_ << 8 | ((offset >> 1) & 0xff);
1221      }
1222      buffer->Store<int16_t>(location_, encoding);
1223    }
1224  }
1225}
1226
1227
1228uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
1229  uint32_t location = buffer_.Size();
1230
1231  // This is always unresolved as it must be a forward branch.
1232  Emit16(prev);      // Previous link.
1233  return AddBranch(n ? Branch::kCompareAndBranchNonZero : Branch::kCompareAndBranchZero,
1234      location, rn);
1235}
1236
1237
1238// NOTE: this only support immediate offsets, not [rx,ry].
1239// TODO: support [rx,ry] instructions.
1240void Thumb2Assembler::EmitLoadStore(Condition cond,
1241                                    bool load,
1242                                    bool byte,
1243                                    bool half,
1244                                    bool is_signed,
1245                                    Register rd,
1246                                    const Address& ad) {
1247  CHECK_NE(rd, kNoRegister);
1248  CheckCondition(cond);
1249  bool must_be_32bit = force_32bit_;
1250  if (IsHighRegister(rd)) {
1251    must_be_32bit = true;
1252  }
1253
1254  Register rn = ad.GetRegister();
1255  if (IsHighRegister(rn) && rn != SP && rn != PC) {
1256    must_be_32bit = true;
1257  }
1258
1259  if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) {
1260    must_be_32bit = true;
1261  }
1262
1263  if (ad.IsImmediate()) {
1264    // Immediate offset
1265    int32_t offset = ad.GetOffset();
1266
1267    // The 16 bit SP relative instruction can only have a 10 bit offset.
1268    if (rn == SP && offset >= (1 << 10)) {
1269      must_be_32bit = true;
1270    }
1271
1272    if (byte) {
1273      // 5 bit offset, no shift.
1274      if (offset >= (1 << 5)) {
1275        must_be_32bit = true;
1276      }
1277    } else if (half) {
1278      // 6 bit offset, shifted by 1.
1279      if (offset >= (1 << 6)) {
1280        must_be_32bit = true;
1281      }
1282    } else {
1283      // 7 bit offset, shifted by 2.
1284      if (offset >= (1 << 7)) {
1285        must_be_32bit = true;
1286      }
1287    }
1288
1289    if (must_be_32bit) {
1290      int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1291          (load ? B20 : 0) |
1292          (is_signed ? B24 : 0) |
1293          static_cast<uint32_t>(rd) << 12 |
1294          ad.encodingThumb(true) |
1295          (byte ? 0 : half ? B21 : B22);
1296      Emit32(encoding);
1297    } else {
1298      // 16 bit thumb1.
1299      uint8_t opA = 0;
1300      bool sp_relative = false;
1301
1302      if (byte) {
1303        opA = 0b0111;
1304      } else if (half) {
1305        opA = 0b1000;
1306      } else {
1307        if (rn == SP) {
1308          opA = 0b1001;
1309          sp_relative = true;
1310        } else {
1311          opA = 0b0110;
1312        }
1313      }
1314      int16_t encoding = opA << 12 |
1315          (load ? B11 : 0);
1316
1317      CHECK_GE(offset, 0);
1318      if (sp_relative) {
1319        // SP relative, 10 bit offset.
1320        CHECK_LT(offset, (1 << 10));
1321        CHECK_EQ((offset & 0b11), 0);
1322        encoding |= rd << 8 | offset >> 2;
1323      } else {
1324        // No SP relative.  The offset is shifted right depending on
1325        // the size of the load/store.
1326        encoding |= static_cast<uint32_t>(rd);
1327
1328        if (byte) {
1329          // 5 bit offset, no shift.
1330          CHECK_LT(offset, (1 << 5));
1331        } else if (half) {
1332          // 6 bit offset, shifted by 1.
1333          CHECK_LT(offset, (1 << 6));
1334          CHECK_EQ((offset & 0b1), 0);
1335          offset >>= 1;
1336        } else {
1337          // 7 bit offset, shifted by 2.
1338          CHECK_LT(offset, (1 << 7));
1339          CHECK_EQ((offset & 0b11), 0);
1340          offset >>= 2;
1341        }
1342        encoding |= rn << 3 | offset  << 6;
1343      }
1344
1345      Emit16(encoding);
1346    }
1347  } else {
1348    // Register shift.
1349    if (ad.GetRegister() == PC) {
1350       // PC relative literal encoding.
1351      int32_t offset = ad.GetOffset();
1352      if (must_be_32bit || offset < 0 || offset >= (1 << 10) || !load) {
1353        int32_t up = B23;
1354        if (offset < 0) {
1355          offset = -offset;
1356          up = 0;
1357        }
1358        CHECK_LT(offset, (1 << 12));
1359        int32_t encoding = 0x1f << 27 | 0xf << 16 | B22 | (load ? B20 : 0) |
1360            offset | up |
1361            static_cast<uint32_t>(rd) << 12;
1362        Emit32(encoding);
1363      } else {
1364        // 16 bit literal load.
1365        CHECK_GE(offset, 0);
1366        CHECK_LT(offset, (1 << 10));
1367        int32_t encoding = B14 | (load ? B11 : 0) | static_cast<uint32_t>(rd) << 8 | offset >> 2;
1368        Emit16(encoding);
1369      }
1370    } else {
1371      if (ad.GetShiftCount() != 0) {
1372        // If there is a shift count this must be 32 bit.
1373        must_be_32bit = true;
1374      } else if (IsHighRegister(ad.GetRegisterOffset())) {
1375        must_be_32bit = true;
1376      }
1377
1378      if (must_be_32bit) {
1379        int32_t encoding = 0x1f << 27 | (load ? B20 : 0) | static_cast<uint32_t>(rd) << 12 |
1380            ad.encodingThumb(true);
1381        if (half) {
1382          encoding |= B21;
1383        } else if (!byte) {
1384          encoding |= B22;
1385        }
1386        Emit32(encoding);
1387      } else {
1388        // 16 bit register offset.
1389        int32_t encoding = B14 | B12 | (load ? B11 : 0) | static_cast<uint32_t>(rd) |
1390            ad.encodingThumb(false);
1391        if (byte) {
1392          encoding |= B10;
1393        } else if (half) {
1394          encoding |= B9;
1395        }
1396        Emit16(encoding);
1397      }
1398    }
1399  }
1400}
1401
1402
1403void Thumb2Assembler::EmitMultiMemOp(Condition cond,
1404                                     BlockAddressMode am,
1405                                     bool load,
1406                                     Register base,
1407                                     RegList regs) {
1408  CHECK_NE(base, kNoRegister);
1409  CheckCondition(cond);
1410  bool must_be_32bit = force_32bit_;
1411
1412  if ((regs & 0xff00) != 0) {
1413    must_be_32bit = true;
1414  }
1415
1416  uint32_t w_bit = am == IA_W || am == DB_W || am == DA_W || am == IB_W;
1417  // 16 bit always uses writeback.
1418  if (!w_bit) {
1419    must_be_32bit = true;
1420  }
1421
1422  if (must_be_32bit) {
1423    uint32_t op = 0;
1424    switch (am) {
1425      case IA:
1426      case IA_W:
1427        op = 0b01;
1428        break;
1429      case DB:
1430      case DB_W:
1431        op = 0b10;
1432        break;
1433      case DA:
1434      case IB:
1435      case DA_W:
1436      case IB_W:
1437        LOG(FATAL) << "LDM/STM mode not supported on thumb: " << am;
1438    }
1439    if (load) {
1440      // Cannot have SP in the list.
1441      CHECK_EQ((regs & (1 << SP)), 0);
1442    } else {
1443      // Cannot have PC or SP in the list.
1444      CHECK_EQ((regs & (1 << PC | 1 << SP)), 0);
1445    }
1446    int32_t encoding = B31 | B30 | B29 | B27 |
1447                    (op << 23) |
1448                    (load ? B20 : 0) |
1449                    base << 16 |
1450                    regs |
1451                    (w_bit << 21);
1452    Emit32(encoding);
1453  } else {
1454    int16_t encoding = B15 | B14 |
1455                    (load ? B11 : 0) |
1456                    base << 8 |
1457                    regs;
1458    Emit16(encoding);
1459  }
1460}
1461
1462
1463void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
1464  uint32_t pc = buffer_.Size();
1465  Branch::Type branch_type;
1466  if (cond == AL) {
1467    if (link) {
1468      if (x) {
1469        branch_type = Branch::kUnconditionalLinkX;      // BLX.
1470      } else {
1471        branch_type = Branch::kUnconditionalLink;       // BX.
1472      }
1473    } else {
1474      branch_type = Branch::kUnconditional;             // B.
1475    }
1476  } else {
1477    branch_type = Branch::kConditional;                 // B<cond>.
1478  }
1479
1480  if (label->IsBound()) {
1481    Branch::Size size = AddBranch(branch_type, pc, label->Position(), cond);  // Resolved branch.
1482
1483    // The branch is to a bound label which means that it's a backwards branch.  We know the
1484    // current size of it so we can emit the appropriate space.  Note that if it's a 16 bit
1485    // branch the size may change if it so happens that other branches change size that change
1486    // the distance to the target and that distance puts this branch over the limit for 16 bits.
1487    if (size == Branch::k16Bit) {
1488      DCHECK(!force_32bit_branches_);
1489      Emit16(0);          // Space for a 16 bit branch.
1490    } else {
1491      Emit32(0);            // Space for a 32 bit branch.
1492    }
1493  } else {
1494    // Branch is to an unbound label.  Emit space for it.
1495    uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
1496    if (force_32bit_branches_ || force_32bit_) {
1497      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1498      Emit16(0);                   // another 16 bits.
1499    } else {
1500      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1501    }
1502    label->LinkTo(branch_id);           // Link to the branch ID.
1503  }
1504}
1505
1506
1507void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) {
1508  CHECK_NE(rd, kNoRegister);
1509  CHECK_NE(rm, kNoRegister);
1510  CheckCondition(cond);
1511  CHECK_NE(rd, PC);
1512  CHECK_NE(rm, PC);
1513  int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1514      B25 | B23 | B21 | B20 |
1515      static_cast<uint32_t>(rm) << 16 |
1516      0xf << 12 |
1517      static_cast<uint32_t>(rd) << 8 |
1518      B7 |
1519      static_cast<uint32_t>(rm);
1520  Emit32(encoding);
1521}
1522
1523
1524void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
1525  CheckCondition(cond);
1526  bool must_be_32bit = force_32bit_;
1527  if (IsHighRegister(rd)|| imm16 >= 256u) {
1528    must_be_32bit = true;
1529  }
1530
1531  if (must_be_32bit) {
1532    // Use encoding T3.
1533    uint32_t imm4 = (imm16 >> 12) & 0b1111;
1534    uint32_t i = (imm16 >> 11) & 0b1;
1535    uint32_t imm3 = (imm16 >> 8) & 0b111;
1536    uint32_t imm8 = imm16 & 0xff;
1537    int32_t encoding = B31 | B30 | B29 | B28 |
1538                    B25 | B22 |
1539                    static_cast<uint32_t>(rd) << 8 |
1540                    i << 26 |
1541                    imm4 << 16 |
1542                    imm3 << 12 |
1543                    imm8;
1544    Emit32(encoding);
1545  } else {
1546    int16_t encoding = B13 | static_cast<uint16_t>(rd) << 8 |
1547                imm16;
1548    Emit16(encoding);
1549  }
1550}
1551
1552
1553void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
1554  CheckCondition(cond);
1555  // Always 32 bits.
1556  uint32_t imm4 = (imm16 >> 12) & 0b1111;
1557  uint32_t i = (imm16 >> 11) & 0b1;
1558  uint32_t imm3 = (imm16 >> 8) & 0b111;
1559  uint32_t imm8 = imm16 & 0xff;
1560  int32_t encoding = B31 | B30 | B29 | B28 |
1561                  B25 | B23 | B22 |
1562                  static_cast<uint32_t>(rd) << 8 |
1563                  i << 26 |
1564                  imm4 << 16 |
1565                  imm3 << 12 |
1566                  imm8;
1567  Emit32(encoding);
1568}
1569
1570
1571void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) {
1572  CHECK_NE(rn, kNoRegister);
1573  CHECK_NE(rt, kNoRegister);
1574  CheckCondition(cond);
1575  CHECK_NE(rn, kNoRegister);
1576  CHECK_NE(rt, kNoRegister);
1577  CheckCondition(cond);
1578  CHECK_LT(imm, (1u << 10));
1579
1580  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
1581      static_cast<uint32_t>(rn) << 16 |
1582      static_cast<uint32_t>(rt) << 12 |
1583      0xf << 8 |
1584      imm >> 2;
1585  Emit32(encoding);
1586}
1587
1588
1589void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) {
1590  ldrex(rt, rn, 0, cond);
1591}
1592
1593
1594void Thumb2Assembler::strex(Register rd,
1595                            Register rt,
1596                            Register rn,
1597                            uint16_t imm,
1598                            Condition cond) {
1599  CHECK_NE(rn, kNoRegister);
1600  CHECK_NE(rd, kNoRegister);
1601  CHECK_NE(rt, kNoRegister);
1602  CheckCondition(cond);
1603  CHECK_LT(imm, (1u << 10));
1604
1605  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
1606      static_cast<uint32_t>(rn) << 16 |
1607      static_cast<uint32_t>(rt) << 12 |
1608      static_cast<uint32_t>(rd) << 8 |
1609      imm >> 2;
1610  Emit32(encoding);
1611}
1612
1613
1614void Thumb2Assembler::strex(Register rd,
1615                            Register rt,
1616                            Register rn,
1617                            Condition cond) {
1618  strex(rd, rt, rn, 0, cond);
1619}
1620
1621
1622void Thumb2Assembler::clrex(Condition cond) {
1623  CheckCondition(cond);
1624  int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 |
1625      B21 | B20 |
1626      0xf << 16 |
1627      B15 |
1628      0xf << 8 |
1629      B5 |
1630      0xf;
1631  Emit32(encoding);
1632}
1633
1634
1635void Thumb2Assembler::nop(Condition cond) {
1636  CheckCondition(cond);
1637  int16_t encoding = B15 | B13 | B12 |
1638      B11 | B10 | B9 | B8;
1639  Emit16(encoding);
1640}
1641
1642
1643void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
1644  CHECK_NE(sn, kNoSRegister);
1645  CHECK_NE(rt, kNoRegister);
1646  CHECK_NE(rt, SP);
1647  CHECK_NE(rt, PC);
1648  CheckCondition(cond);
1649  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1650                     B27 | B26 | B25 |
1651                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1652                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1653                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1654  Emit32(encoding);
1655}
1656
1657
1658void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
1659  CHECK_NE(sn, kNoSRegister);
1660  CHECK_NE(rt, kNoRegister);
1661  CHECK_NE(rt, SP);
1662  CHECK_NE(rt, PC);
1663  CheckCondition(cond);
1664  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1665                     B27 | B26 | B25 | B20 |
1666                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1667                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1668                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1669  Emit32(encoding);
1670}
1671
1672
1673void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
1674                              Condition cond) {
1675  CHECK_NE(sm, kNoSRegister);
1676  CHECK_NE(sm, S31);
1677  CHECK_NE(rt, kNoRegister);
1678  CHECK_NE(rt, SP);
1679  CHECK_NE(rt, PC);
1680  CHECK_NE(rt2, kNoRegister);
1681  CHECK_NE(rt2, SP);
1682  CHECK_NE(rt2, PC);
1683  CheckCondition(cond);
1684  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1685                     B27 | B26 | B22 |
1686                     (static_cast<int32_t>(rt2)*B16) |
1687                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1688                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1689                     (static_cast<int32_t>(sm) >> 1);
1690  Emit32(encoding);
1691}
1692
1693
1694void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
1695                              Condition cond) {
1696  CHECK_NE(sm, kNoSRegister);
1697  CHECK_NE(sm, S31);
1698  CHECK_NE(rt, kNoRegister);
1699  CHECK_NE(rt, SP);
1700  CHECK_NE(rt, PC);
1701  CHECK_NE(rt2, kNoRegister);
1702  CHECK_NE(rt2, SP);
1703  CHECK_NE(rt2, PC);
1704  CHECK_NE(rt, rt2);
1705  CheckCondition(cond);
1706  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1707                     B27 | B26 | B22 | B20 |
1708                     (static_cast<int32_t>(rt2)*B16) |
1709                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1710                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1711                     (static_cast<int32_t>(sm) >> 1);
1712  Emit32(encoding);
1713}
1714
1715
1716void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
1717                              Condition cond) {
1718  CHECK_NE(dm, kNoDRegister);
1719  CHECK_NE(rt, kNoRegister);
1720  CHECK_NE(rt, SP);
1721  CHECK_NE(rt, PC);
1722  CHECK_NE(rt2, kNoRegister);
1723  CHECK_NE(rt2, SP);
1724  CHECK_NE(rt2, PC);
1725  CheckCondition(cond);
1726  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1727                     B27 | B26 | B22 |
1728                     (static_cast<int32_t>(rt2)*B16) |
1729                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1730                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1731                     (static_cast<int32_t>(dm) & 0xf);
1732  Emit32(encoding);
1733}
1734
1735
1736void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
1737                              Condition cond) {
1738  CHECK_NE(dm, kNoDRegister);
1739  CHECK_NE(rt, kNoRegister);
1740  CHECK_NE(rt, SP);
1741  CHECK_NE(rt, PC);
1742  CHECK_NE(rt2, kNoRegister);
1743  CHECK_NE(rt2, SP);
1744  CHECK_NE(rt2, PC);
1745  CHECK_NE(rt, rt2);
1746  CheckCondition(cond);
1747  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1748                     B27 | B26 | B22 | B20 |
1749                     (static_cast<int32_t>(rt2)*B16) |
1750                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1751                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1752                     (static_cast<int32_t>(dm) & 0xf);
1753  Emit32(encoding);
1754}
1755
1756
1757void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
1758  const Address& addr = static_cast<const Address&>(ad);
1759  CHECK_NE(sd, kNoSRegister);
1760  CheckCondition(cond);
1761  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1762                     B27 | B26 | B24 | B20 |
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::vstrs(SRegister sd, const Address& ad, Condition cond) {
1771  const Address& addr = static_cast<const Address&>(ad);
1772  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1773  CHECK_NE(sd, kNoSRegister);
1774  CheckCondition(cond);
1775  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1776                     B27 | B26 | B24 |
1777                     ((static_cast<int32_t>(sd) & 1)*B22) |
1778                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1779                     B11 | B9 | addr.vencoding();
1780  Emit32(encoding);
1781}
1782
1783
1784void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
1785  const Address& addr = static_cast<const Address&>(ad);
1786  CHECK_NE(dd, kNoDRegister);
1787  CheckCondition(cond);
1788  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1789                     B27 | B26 | B24 | B20 |
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::vstrd(DRegister dd, const Address& ad, Condition cond) {
1798  const Address& addr = static_cast<const Address&>(ad);
1799  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1800  CHECK_NE(dd, kNoDRegister);
1801  CheckCondition(cond);
1802  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1803                     B27 | B26 | B24 |
1804                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1805                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1806                     B11 | B9 | B8 | addr.vencoding();
1807  Emit32(encoding);
1808}
1809
1810
1811void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
1812  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
1813}
1814
1815
1816void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
1817  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
1818}
1819
1820
1821void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) {
1822  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
1823}
1824
1825
1826void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
1827  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
1828}
1829
1830
1831void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
1832  CheckCondition(cond);
1833
1834  uint32_t D;
1835  uint32_t Vd;
1836  if (dbl) {
1837    // Encoded as D:Vd.
1838    D = (reg >> 4) & 1;
1839    Vd = reg & 0b1111;
1840  } else {
1841    // Encoded as Vd:D.
1842    D = reg & 1;
1843    Vd = (reg >> 1) & 0b1111;
1844  }
1845  int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
1846                    B11 | B9 |
1847        (dbl ? B8 : 0) |
1848        (push ? B24 : (B23 | B20)) |
1849        0b1110 << 28 |
1850        nregs << (dbl ? 1 : 0) |
1851        D << 22 |
1852        Vd << 12;
1853  Emit32(encoding);
1854}
1855
1856
1857void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode,
1858                                 SRegister sd, SRegister sn, SRegister sm) {
1859  CHECK_NE(sd, kNoSRegister);
1860  CHECK_NE(sn, kNoSRegister);
1861  CHECK_NE(sm, kNoSRegister);
1862  CheckCondition(cond);
1863  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1864                     B27 | B26 | B25 | B11 | B9 | opcode |
1865                     ((static_cast<int32_t>(sd) & 1)*B22) |
1866                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1867                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1868                     ((static_cast<int32_t>(sn) & 1)*B7) |
1869                     ((static_cast<int32_t>(sm) & 1)*B5) |
1870                     (static_cast<int32_t>(sm) >> 1);
1871  Emit32(encoding);
1872}
1873
1874
1875void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode,
1876                                 DRegister dd, DRegister dn, DRegister dm) {
1877  CHECK_NE(dd, kNoDRegister);
1878  CHECK_NE(dn, kNoDRegister);
1879  CHECK_NE(dm, kNoDRegister);
1880  CheckCondition(cond);
1881  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1882                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1883                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1884                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
1885                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1886                     ((static_cast<int32_t>(dn) >> 4)*B7) |
1887                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1888                     (static_cast<int32_t>(dm) & 0xf);
1889  Emit32(encoding);
1890}
1891
1892
1893void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1894                                SRegister sd, DRegister dm) {
1895  CHECK_NE(sd, kNoSRegister);
1896  CHECK_NE(dm, kNoDRegister);
1897  CheckCondition(cond);
1898  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1899                     B27 | B26 | B25 | B11 | B9 | opcode |
1900                     ((static_cast<int32_t>(sd) & 1)*B22) |
1901                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1902                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1903                     (static_cast<int32_t>(dm) & 0xf);
1904  Emit32(encoding);
1905}
1906
1907
1908void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode,
1909                                DRegister dd, SRegister sm) {
1910  CHECK_NE(dd, kNoDRegister);
1911  CHECK_NE(sm, kNoSRegister);
1912  CheckCondition(cond);
1913  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1914                     B27 | B26 | B25 | B11 | B9 | opcode |
1915                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1916                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1917                     ((static_cast<int32_t>(sm) & 1)*B5) |
1918                     (static_cast<int32_t>(sm) >> 1);
1919  Emit32(encoding);
1920}
1921
1922
1923void Thumb2Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR.
1924  CheckCondition(cond);
1925  UNIMPLEMENTED(FATAL) << "Unimplemented thumb instruction";
1926}
1927
1928
1929void Thumb2Assembler::svc(uint32_t imm8) {
1930  CHECK(IsUint(8, imm8)) << imm8;
1931  int16_t encoding = B15 | B14 | B12 |
1932       B11 | B10 | B9 | B8 |
1933       imm8;
1934  Emit16(encoding);
1935}
1936
1937
1938void Thumb2Assembler::bkpt(uint16_t imm8) {
1939  CHECK(IsUint(8, imm8)) << imm8;
1940  int16_t encoding = B15 | B13 | B12 |
1941      B11 | B10 | B9 |
1942      imm8;
1943  Emit16(encoding);
1944}
1945
1946// Convert the given IT state to a mask bit given bit 0 of the first
1947// condition and a shift position.
1948static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) {
1949  switch (s) {
1950  case kItOmitted: return 1 << shift;
1951  case kItThen: return firstcond0 << shift;
1952  case kItElse: return !firstcond0 << shift;
1953  }
1954  return 0;
1955}
1956
1957
1958// Set the IT condition in the given position for the given state.  This is used
1959// to check that conditional instructions match the preceding IT statement.
1960void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) {
1961  switch (s) {
1962  case kItOmitted: it_conditions_[index] = AL; break;
1963  case kItThen: it_conditions_[index] = cond; break;
1964  case kItElse:
1965    it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1);
1966    break;
1967  }
1968}
1969
1970
1971void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) {
1972  CheckCondition(AL);       // Not allowed in IT block.
1973  uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1;
1974
1975  // All conditions to AL.
1976  for (uint8_t i = 0; i < 4; ++i) {
1977    it_conditions_[i] = AL;
1978  }
1979
1980  SetItCondition(kItThen, firstcond, 0);
1981  uint8_t mask = ToItMask(i1, firstcond0, 3);
1982  SetItCondition(i1, firstcond, 1);
1983
1984  if (i1 != kItOmitted) {
1985    mask |= ToItMask(i2, firstcond0, 2);
1986    SetItCondition(i2, firstcond, 2);
1987    if (i2 != kItOmitted) {
1988      mask |= ToItMask(i3, firstcond0, 1);
1989      SetItCondition(i3, firstcond, 3);
1990      if (i3 != kItOmitted) {
1991        mask |= 0b0001;
1992      }
1993    }
1994  }
1995
1996  // Start at first condition.
1997  it_cond_index_ = 0;
1998  next_condition_ = it_conditions_[0];
1999  uint16_t encoding = B15 | B13 | B12 |
2000        B11 | B10 | B9 | B8 |
2001        firstcond << 4 |
2002        mask;
2003  Emit16(encoding);
2004}
2005
2006
2007void Thumb2Assembler::cbz(Register rn, Label* label) {
2008  CheckCondition(AL);
2009  if (label->IsBound()) {
2010    LOG(FATAL) << "cbz can only be used to branch forwards";
2011  } else {
2012    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
2013    label->LinkTo(branchid);
2014  }
2015}
2016
2017
2018void Thumb2Assembler::cbnz(Register rn, Label* label) {
2019  CheckCondition(AL);
2020  if (label->IsBound()) {
2021    LOG(FATAL) << "cbnz can only be used to branch forwards";
2022  } else {
2023    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
2024    label->LinkTo(branchid);
2025  }
2026}
2027
2028
2029void Thumb2Assembler::blx(Register rm, Condition cond) {
2030  CHECK_NE(rm, kNoRegister);
2031  CheckCondition(cond);
2032  int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3;
2033  Emit16(encoding);
2034}
2035
2036
2037void Thumb2Assembler::bx(Register rm, Condition cond) {
2038  CHECK_NE(rm, kNoRegister);
2039  CheckCondition(cond);
2040  int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3;
2041  Emit16(encoding);
2042}
2043
2044
2045void Thumb2Assembler::Push(Register rd, Condition cond) {
2046  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
2047}
2048
2049
2050void Thumb2Assembler::Pop(Register rd, Condition cond) {
2051  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
2052}
2053
2054
2055void Thumb2Assembler::PushList(RegList regs, Condition cond) {
2056  stm(DB_W, SP, regs, cond);
2057}
2058
2059
2060void Thumb2Assembler::PopList(RegList regs, Condition cond) {
2061  ldm(IA_W, SP, regs, cond);
2062}
2063
2064
2065void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
2066  if (cond != AL || rd != rm) {
2067    mov(rd, ShifterOperand(rm), cond);
2068  }
2069}
2070
2071
2072// A branch has changed size.  Make a hole for it.
2073void Thumb2Assembler::MakeHoleForBranch(uint32_t location, uint32_t delta) {
2074  // Move the contents of the buffer using: Move(newposition, oldposition)
2075  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2076  buffer_.Move(location + delta, location);
2077}
2078
2079
2080void Thumb2Assembler::Bind(Label* label) {
2081  CHECK(!label->IsBound());
2082  uint32_t bound_pc = buffer_.Size();
2083  std::vector<Branch*> changed_branches;
2084
2085  while (label->IsLinked()) {
2086    uint16_t position = label->Position();                  // Branch id for linked branch.
2087    Branch* branch = GetBranch(position);                   // Get the branch at this id.
2088    bool changed = branch->Resolve(bound_pc);               // Branch can be resolved now.
2089    uint32_t branch_location = branch->GetLocation();
2090    uint16_t next = buffer_.Load<uint16_t>(branch_location);       // Get next in chain.
2091    if (changed) {
2092      DCHECK(!force_32bit_branches_);
2093      MakeHoleForBranch(branch->GetLocation(), 2);
2094      if (branch->IsCompareAndBranch()) {
2095        // A cbz/cbnz instruction has changed size.  There is no valid encoding for
2096        // a 32 bit cbz/cbnz so we need to change this to an instruction pair:
2097        // cmp rn, #0
2098        // b<eq|ne> target
2099        bool n = branch->GetType() == Branch::kCompareAndBranchNonZero;
2100        Condition cond = n ? NE : EQ;
2101        branch->Move(2);      // Move the branch forward by 2 bytes.
2102        branch->ResetTypeAndCondition(Branch::kConditional, cond);
2103        branch->ResetSize(Branch::k16Bit);
2104
2105        // Now add a compare instruction in the place the branch was.
2106        int16_t cmp = B13 | B11 | static_cast<int16_t>(branch->GetRegister()) << 8;
2107        buffer_.Store<int16_t>(branch_location, cmp);
2108
2109        // Since have moved made a hole in the code we need to reload the
2110        // current pc.
2111        bound_pc = buffer_.Size();
2112
2113        // Now resolve the newly added branch.
2114        changed = branch->Resolve(bound_pc);
2115        if (changed) {
2116          MakeHoleForBranch(branch->GetLocation(), 2);
2117          changed_branches.push_back(branch);
2118        }
2119      } else {
2120        changed_branches.push_back(branch);
2121      }
2122    }
2123    label->position_ = next;                                // Move to next.
2124  }
2125  label->BindTo(bound_pc);
2126
2127  // Now relocate any changed branches.  Do this until there are no more changes.
2128  std::vector<Branch*> branches_to_process = changed_branches;
2129  while (branches_to_process.size() != 0) {
2130    changed_branches.clear();
2131    for (auto& changed_branch : branches_to_process) {
2132      for (auto& branch : branches_) {
2133        bool changed = branch->Relocate(changed_branch->GetLocation(), 2);
2134        if (changed) {
2135          changed_branches.push_back(branch);
2136        }
2137      }
2138      branches_to_process = changed_branches;
2139    }
2140  }
2141}
2142
2143
2144void Thumb2Assembler::EmitBranches() {
2145  for (auto& branch : branches_) {
2146    branch->Emit(&buffer_);
2147  }
2148}
2149
2150
2151void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
2152                          bool setcc, Condition cond) {
2153  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
2154  CheckCondition(cond);
2155  EmitShift(rd, rm, LSL, shift_imm, setcc);
2156}
2157
2158
2159void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
2160                          bool setcc, Condition cond) {
2161  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
2162  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2163  CheckCondition(cond);
2164  EmitShift(rd, rm, LSR, shift_imm, setcc);
2165}
2166
2167
2168void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
2169                          bool setcc, Condition cond) {
2170  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
2171  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2172  CheckCondition(cond);
2173  EmitShift(rd, rm, ASR, shift_imm, setcc);
2174}
2175
2176
2177void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
2178                          bool setcc, Condition cond) {
2179  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
2180  CheckCondition(cond);
2181  EmitShift(rd, rm, ROR, shift_imm, setcc);
2182}
2183
2184
2185void Thumb2Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
2186  CheckCondition(cond);
2187  EmitShift(rd, rm, RRX, rm, setcc);
2188}
2189
2190
2191void Thumb2Assembler::Lsl(Register rd, Register rm, Register rn,
2192                          bool setcc, Condition cond) {
2193  CheckCondition(cond);
2194  EmitShift(rd, rm, LSL, rn, setcc);
2195}
2196
2197
2198void Thumb2Assembler::Lsr(Register rd, Register rm, Register rn,
2199                          bool setcc, Condition cond) {
2200  CheckCondition(cond);
2201  EmitShift(rd, rm, LSR, rn, setcc);
2202}
2203
2204
2205void Thumb2Assembler::Asr(Register rd, Register rm, Register rn,
2206                          bool setcc, Condition cond) {
2207  CheckCondition(cond);
2208  EmitShift(rd, rm, ASR, rn, setcc);
2209}
2210
2211
2212void Thumb2Assembler::Ror(Register rd, Register rm, Register rn,
2213                          bool setcc, Condition cond) {
2214  CheckCondition(cond);
2215  EmitShift(rd, rm, ROR, rn, setcc);
2216}
2217
2218
2219int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
2220  // The offset is off by 4 due to the way the ARM CPUs read PC.
2221  offset -= 4;
2222  offset >>= 1;
2223
2224  uint32_t value = 0;
2225  // There are two different encodings depending on the value of bit 12.  In one case
2226  // intermediate values are calculated using the sign bit.
2227  if ((inst & B12) == B12) {
2228    // 25 bits of offset.
2229    uint32_t signbit = (offset >> 31) & 0x1;
2230    uint32_t i1 = (offset >> 22) & 0x1;
2231    uint32_t i2 = (offset >> 21) & 0x1;
2232    uint32_t imm10 = (offset >> 11) & 0x03ff;
2233    uint32_t imm11 = offset & 0x07ff;
2234    uint32_t j1 = (i1 ^ signbit) ? 0 : 1;
2235    uint32_t j2 = (i2 ^ signbit) ? 0 : 1;
2236    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) |
2237                      imm11;
2238    // Remove the offset from the current encoding.
2239    inst &= ~(0x3ff << 16 | 0x7ff);
2240  } else {
2241    uint32_t signbit = (offset >> 31) & 0x1;
2242    uint32_t imm6 = (offset >> 11) & 0x03f;
2243    uint32_t imm11 = offset & 0x07ff;
2244    uint32_t j1 = (offset >> 19) & 1;
2245    uint32_t j2 = (offset >> 17) & 1;
2246    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) |
2247        imm11;
2248    // Remove the offset from the current encoding.
2249    inst &= ~(0x3f << 16 | 0x7ff);
2250  }
2251  // Mask out offset bits in current instruction.
2252  inst &= ~(B26 | B13 | B11);
2253  inst |= value;
2254  return inst;
2255}
2256
2257
2258int Thumb2Assembler::DecodeBranchOffset(int32_t instr) {
2259  int32_t imm32;
2260  if ((instr & B12) == B12) {
2261    uint32_t S = (instr >> 26) & 1;
2262    uint32_t J2 = (instr >> 11) & 1;
2263    uint32_t J1 = (instr >> 13) & 1;
2264    uint32_t imm10 = (instr >> 16) & 0x3FF;
2265    uint32_t imm11 = instr & 0x7FF;
2266
2267    uint32_t I1 = ~(J1 ^ S) & 1;
2268    uint32_t I2 = ~(J2 ^ S) & 1;
2269    imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2270    imm32 = (imm32 << 8) >> 8;  // sign extend 24 bit immediate.
2271  } else {
2272    uint32_t S = (instr >> 26) & 1;
2273    uint32_t J2 = (instr >> 11) & 1;
2274    uint32_t J1 = (instr >> 13) & 1;
2275    uint32_t imm6 = (instr >> 16) & 0x3F;
2276    uint32_t imm11 = instr & 0x7FF;
2277
2278    imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2279    imm32 = (imm32 << 11) >> 11;  // sign extend 21 bit immediate.
2280  }
2281  imm32 += 4;
2282  return imm32;
2283}
2284
2285
2286void Thumb2Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
2287  AddConstant(rd, rd, value, cond);
2288}
2289
2290
2291void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value,
2292                                  Condition cond) {
2293  if (value == 0) {
2294    if (rd != rn) {
2295      mov(rd, ShifterOperand(rn), cond);
2296    }
2297    return;
2298  }
2299  // We prefer to select the shorter code sequence rather than selecting add for
2300  // positive values and sub for negatives ones, which would slightly improve
2301  // the readability of generated code for some constants.
2302  ShifterOperand shifter_op;
2303  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2304    add(rd, rn, shifter_op, cond);
2305  } else if (ShifterOperand::CanHoldThumb(rd, rn, SUB, -value, &shifter_op)) {
2306    sub(rd, rn, shifter_op, cond);
2307  } else {
2308    CHECK(rn != IP);
2309    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2310      mvn(IP, shifter_op, cond);
2311      add(rd, rn, ShifterOperand(IP), cond);
2312    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2313      mvn(IP, shifter_op, cond);
2314      sub(rd, rn, ShifterOperand(IP), cond);
2315    } else {
2316      movw(IP, Low16Bits(value), cond);
2317      uint16_t value_high = High16Bits(value);
2318      if (value_high != 0) {
2319        movt(IP, value_high, cond);
2320      }
2321      add(rd, rn, ShifterOperand(IP), cond);
2322    }
2323  }
2324}
2325
2326
2327void Thumb2Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
2328                                          Condition cond) {
2329  ShifterOperand shifter_op;
2330  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2331    adds(rd, rn, shifter_op, cond);
2332  } else if (ShifterOperand::CanHoldThumb(rd, rn, ADD, -value, &shifter_op)) {
2333    subs(rd, rn, shifter_op, cond);
2334  } else {
2335    CHECK(rn != IP);
2336    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2337      mvn(IP, shifter_op, cond);
2338      adds(rd, rn, ShifterOperand(IP), cond);
2339    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2340      mvn(IP, shifter_op, cond);
2341      subs(rd, rn, ShifterOperand(IP), cond);
2342    } else {
2343      movw(IP, Low16Bits(value), cond);
2344      uint16_t value_high = High16Bits(value);
2345      if (value_high != 0) {
2346        movt(IP, value_high, cond);
2347      }
2348      adds(rd, rn, ShifterOperand(IP), cond);
2349    }
2350  }
2351}
2352
2353
2354void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2355  ShifterOperand shifter_op;
2356  if (ShifterOperand::CanHoldThumb(rd, R0, MOV, value, &shifter_op)) {
2357    mov(rd, shifter_op, cond);
2358  } else if (ShifterOperand::CanHoldThumb(rd, R0, MVN, ~value, &shifter_op)) {
2359    mvn(rd, shifter_op, cond);
2360  } else {
2361    movw(rd, Low16Bits(value), cond);
2362    uint16_t value_high = High16Bits(value);
2363    if (value_high != 0) {
2364      movt(rd, value_high, cond);
2365    }
2366  }
2367}
2368
2369// Implementation note: this method must emit at most one instruction when
2370// Address::CanHoldLoadOffsetThumb.
2371void Thumb2Assembler::LoadFromOffset(LoadOperandType type,
2372                                     Register reg,
2373                                     Register base,
2374                                     int32_t offset,
2375                                     Condition cond) {
2376  if (!Address::CanHoldLoadOffsetThumb(type, offset)) {
2377    CHECK(base != IP);
2378    LoadImmediate(IP, offset, cond);
2379    add(IP, IP, ShifterOperand(base), cond);
2380    base = IP;
2381    offset = 0;
2382  }
2383  CHECK(Address::CanHoldLoadOffsetThumb(type, offset));
2384  switch (type) {
2385    case kLoadSignedByte:
2386      ldrsb(reg, Address(base, offset), cond);
2387      break;
2388    case kLoadUnsignedByte:
2389      ldrb(reg, Address(base, offset), cond);
2390      break;
2391    case kLoadSignedHalfword:
2392      ldrsh(reg, Address(base, offset), cond);
2393      break;
2394    case kLoadUnsignedHalfword:
2395      ldrh(reg, Address(base, offset), cond);
2396      break;
2397    case kLoadWord:
2398      ldr(reg, Address(base, offset), cond);
2399      break;
2400    case kLoadWordPair:
2401      ldrd(reg, Address(base, offset), cond);
2402      break;
2403    default:
2404      LOG(FATAL) << "UNREACHABLE";
2405  }
2406}
2407
2408
2409// Implementation note: this method must emit at most one instruction when
2410// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2411void Thumb2Assembler::LoadSFromOffset(SRegister reg,
2412                                      Register base,
2413                                      int32_t offset,
2414                                      Condition cond) {
2415  if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) {
2416    CHECK_NE(base, IP);
2417    LoadImmediate(IP, offset, cond);
2418    add(IP, IP, ShifterOperand(base), cond);
2419    base = IP;
2420    offset = 0;
2421  }
2422  CHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset));
2423  vldrs(reg, Address(base, offset), cond);
2424}
2425
2426
2427// Implementation note: this method must emit at most one instruction when
2428// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2429void Thumb2Assembler::LoadDFromOffset(DRegister reg,
2430                                      Register base,
2431                                      int32_t offset,
2432                                      Condition cond) {
2433  if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) {
2434    CHECK_NE(base, IP);
2435    LoadImmediate(IP, offset, cond);
2436    add(IP, IP, ShifterOperand(base), cond);
2437    base = IP;
2438    offset = 0;
2439  }
2440  CHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset));
2441  vldrd(reg, Address(base, offset), cond);
2442}
2443
2444
2445// Implementation note: this method must emit at most one instruction when
2446// Address::CanHoldStoreOffsetThumb.
2447void Thumb2Assembler::StoreToOffset(StoreOperandType type,
2448                                    Register reg,
2449                                    Register base,
2450                                    int32_t offset,
2451                                    Condition cond) {
2452  if (!Address::CanHoldStoreOffsetThumb(type, offset)) {
2453    CHECK(reg != IP);
2454    CHECK(base != IP);
2455    LoadImmediate(IP, offset, cond);
2456    add(IP, IP, ShifterOperand(base), cond);
2457    base = IP;
2458    offset = 0;
2459  }
2460  CHECK(Address::CanHoldStoreOffsetThumb(type, offset));
2461  switch (type) {
2462    case kStoreByte:
2463      strb(reg, Address(base, offset), cond);
2464      break;
2465    case kStoreHalfword:
2466      strh(reg, Address(base, offset), cond);
2467      break;
2468    case kStoreWord:
2469      str(reg, Address(base, offset), cond);
2470      break;
2471    case kStoreWordPair:
2472      strd(reg, Address(base, offset), cond);
2473      break;
2474    default:
2475      LOG(FATAL) << "UNREACHABLE";
2476  }
2477}
2478
2479
2480// Implementation note: this method must emit at most one instruction when
2481// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset.
2482void Thumb2Assembler::StoreSToOffset(SRegister reg,
2483                                     Register base,
2484                                     int32_t offset,
2485                                     Condition cond) {
2486  if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) {
2487    CHECK_NE(base, IP);
2488    LoadImmediate(IP, offset, cond);
2489    add(IP, IP, ShifterOperand(base), cond);
2490    base = IP;
2491    offset = 0;
2492  }
2493  CHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset));
2494  vstrs(reg, Address(base, offset), cond);
2495}
2496
2497
2498// Implementation note: this method must emit at most one instruction when
2499// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset.
2500void Thumb2Assembler::StoreDToOffset(DRegister reg,
2501                                     Register base,
2502                                     int32_t offset,
2503                                     Condition cond) {
2504  if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) {
2505    CHECK_NE(base, IP);
2506    LoadImmediate(IP, offset, cond);
2507    add(IP, IP, ShifterOperand(base), cond);
2508    base = IP;
2509    offset = 0;
2510  }
2511  CHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset));
2512  vstrd(reg, Address(base, offset), cond);
2513}
2514
2515
2516void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) {
2517  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
2518#if ANDROID_SMP != 0
2519  int32_t encoding = 0xf3bf8f5f;  // dmb in T1 encoding.
2520  Emit32(encoding);
2521#endif
2522}
2523
2524
2525void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
2526  if (force_32bit_branches_) {
2527    cmp(r, ShifterOperand(0));
2528    b(label, EQ);
2529  } else {
2530    cbz(r, label);
2531  }
2532}
2533
2534
2535void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
2536  if (force_32bit_branches_) {
2537    cmp(r, ShifterOperand(0));
2538    b(label, NE);
2539  } else {
2540    cbnz(r, label);
2541  }
2542}
2543}  // namespace arm
2544}  // namespace art
2545