assembler_thumb2.cc revision 20dfc797dc631bf8d655dcf123f46f13332d3074
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 == IA_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 == DB || am == DB_W);
356    Address::Mode strmode = am == DB_W ? 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           return false;      // 16 bit good.
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) && rn == SP) {
762      // There are special ADD/SUB rd, SP, #imm12 instructions.
763      if (opcode == SUB) {
764        thumb_opcode = 0b0101;
765      } else {
766        thumb_opcode = 0;
767      }
768      uint32_t imm = so.GetImmediate();
769      CHECK_LT(imm, (1u << 12));
770
771      uint32_t i = (imm >> 11) & 1;
772      uint32_t imm3 = (imm >> 8) & 0b111;
773      uint32_t imm8 = imm & 0xff;
774
775      encoding = B31 | B30 | B29 | B28 | B25 |
776           B19 | B18 | B16 |
777           thumb_opcode << 21 |
778           rd << 8 |
779           i << 26 |
780           imm3 << 12 |
781           imm8;
782    } else {
783      // Modified immediate.
784      uint32_t imm = ModifiedImmediate(so.encodingThumb(2));
785      if (imm == kInvalidModifiedImmediate) {
786        LOG(FATAL) << "Immediate value cannot fit in thumb2 modified immediate";
787      }
788      encoding = B31 | B30 | B29 | B28 |
789          thumb_opcode << 21 |
790          set_cc << 20 |
791          rn << 16 |
792          rd << 8 |
793          imm;
794    }
795  } else if (so.IsRegister()) {
796     // Register (possibly shifted)
797     encoding = B31 | B30 | B29 | B27 | B25 |
798         thumb_opcode << 21 |
799         set_cc << 20 |
800         rn << 16 |
801         rd << 8 |
802         so.encodingThumb(2);
803  }
804  Emit32(encoding);
805}
806
807
808void Thumb2Assembler::Emit16BitDataProcessing(Condition cond,
809                                              Opcode opcode,
810                                              int set_cc,
811                                              Register rn,
812                                              Register rd,
813                                              const ShifterOperand& so) {
814  if (opcode == ADD || opcode == SUB) {
815    Emit16BitAddSub(cond, opcode, set_cc, rn, rd, so);
816    return;
817  }
818  uint8_t thumb_opcode = 0b11111111;
819  // Thumb1.
820  uint8_t dp_opcode = 0b01;
821  uint8_t opcode_shift = 6;
822  uint8_t rd_shift = 0;
823  uint8_t rn_shift = 3;
824  uint8_t immediate_shift = 0;
825  bool use_immediate = false;
826  uint8_t immediate = 0;
827
828  if (opcode == MOV && so.IsRegister() && so.IsShift()) {
829    // Convert shifted mov operand2 into 16 bit opcodes.
830    dp_opcode = 0;
831    opcode_shift = 11;
832
833    use_immediate = true;
834    immediate = so.GetImmediate();
835    immediate_shift = 6;
836
837    rn = so.GetRegister();
838
839    switch (so.GetShift()) {
840    case LSL: thumb_opcode = 0b00; break;
841    case LSR: thumb_opcode = 0b01; break;
842    case ASR: thumb_opcode = 0b10; break;
843    case ROR:
844      // ROR doesn't allow immediates.
845      thumb_opcode = 0b111;
846      dp_opcode = 0b01;
847      opcode_shift = 6;
848      use_immediate = false;
849      break;
850    case RRX: break;
851    default:
852     break;
853    }
854  } else {
855    if (so.IsImmediate()) {
856      use_immediate = true;
857      immediate = so.GetImmediate();
858    }
859
860    switch (opcode) {
861      case AND: thumb_opcode = 0b0000; break;
862      case EOR: thumb_opcode = 0b0001; break;
863      case SUB: break;
864      case RSB: thumb_opcode = 0b1001; break;
865      case ADD: break;
866      case ADC: thumb_opcode = 0b0101; break;
867      case SBC: thumb_opcode = 0b0110; break;
868      case RSC: break;
869      case TST: thumb_opcode = 0b1000; rn = so.GetRegister(); break;
870      case TEQ: break;
871      case CMP:
872        if (use_immediate) {
873          // T2 encoding.
874           dp_opcode = 0;
875           opcode_shift = 11;
876           thumb_opcode = 0b101;
877           rd_shift = 8;
878           rn_shift = 8;
879        } else {
880          thumb_opcode = 0b1010;
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
1084
1085void Thumb2Assembler::Branch::Emit(AssemblerBuffer* buffer) const {
1086  bool link = type_ == kUnconditionalLinkX || type_ == kUnconditionalLink;
1087  bool x = type_ == kUnconditionalX || type_ == kUnconditionalLinkX;
1088  int32_t offset = target_ - location_;
1089
1090  if (size_ == k32Bit) {
1091    int32_t encoding = B31 | B30 | B29 | B28 | B15;
1092    if (link) {
1093      // BL or BLX immediate.
1094      encoding |= B14;
1095      if (!x) {
1096        encoding |= B12;
1097      } else {
1098        // Bottom bit of offset must be 0.
1099        CHECK_EQ((offset & 1), 0);
1100      }
1101    } else {
1102      if (x) {
1103        LOG(FATAL) << "Invalid use of BX";
1104      } else {
1105        if (cond_ == AL) {
1106          // Can use the T4 encoding allowing a 24 bit offset.
1107          if (!x) {
1108            encoding |= B12;
1109          }
1110        } else {
1111          // Must be T3 encoding with a 20 bit offset.
1112          encoding |= cond_ << 22;
1113        }
1114      }
1115    }
1116    encoding = Thumb2Assembler::EncodeBranchOffset(offset, encoding);
1117    buffer->Store<int16_t>(location_, static_cast<int16_t>(encoding >> 16));
1118    buffer->Store<int16_t>(location_+2, static_cast<int16_t>(encoding & 0xffff));
1119  } else {
1120    if (IsCompareAndBranch()) {
1121      offset -= 4;
1122      uint16_t i = (offset >> 6) & 1;
1123      uint16_t imm5 = (offset >> 1) & 0b11111;
1124      int16_t encoding = B15 | B13 | B12 |
1125            (type_ ==  kCompareAndBranchNonZero ? B11 : 0) |
1126            static_cast<uint32_t>(rn_) |
1127            B8 |
1128            i << 9 |
1129            imm5 << 3;
1130      buffer->Store<int16_t>(location_, encoding);
1131    } else {
1132      offset -= 4;    // Account for PC offset.
1133      int16_t encoding;
1134      // 16 bit.
1135      if (cond_ == AL) {
1136        encoding = B15 | B14 | B13 |
1137            ((offset >> 1) & 0x7ff);
1138      } else {
1139        encoding = B15 | B14 | B12 |
1140            cond_ << 8 | ((offset >> 1) & 0xff);
1141      }
1142      buffer->Store<int16_t>(location_, encoding);
1143    }
1144  }
1145}
1146
1147
1148uint16_t Thumb2Assembler::EmitCompareAndBranch(Register rn, uint16_t prev, bool n) {
1149  uint32_t location = buffer_.Size();
1150
1151  // This is always unresolved as it must be a forward branch.
1152  Emit16(prev);      // Previous link.
1153  return AddBranch(n ? Branch::kCompareAndBranchNonZero : Branch::kCompareAndBranchZero,
1154      location, rn);
1155}
1156
1157
1158// NOTE: this only support immediate offsets, not [rx,ry].
1159// TODO: support [rx,ry] instructions.
1160void Thumb2Assembler::EmitLoadStore(Condition cond,
1161                                    bool load,
1162                                    bool byte,
1163                                    bool half,
1164                                    bool is_signed,
1165                                    Register rd,
1166                                    const Address& ad) {
1167  CHECK_NE(rd, kNoRegister);
1168  CheckCondition(cond);
1169  bool must_be_32bit = force_32bit_;
1170  if (IsHighRegister(rd)) {
1171    must_be_32bit = true;
1172  }
1173
1174  Register rn = ad.GetRegister();
1175  if (IsHighRegister(rn) && rn != SP) {
1176    must_be_32bit = true;
1177  }
1178
1179  if (is_signed || ad.GetOffset() < 0 || ad.GetMode() != Address::Offset) {
1180    must_be_32bit = true;
1181  }
1182
1183  int32_t offset = ad.GetOffset();
1184
1185  // The 16 bit SP relative instruction can only have a 10 bit offset.
1186  if (rn == SP && offset > 1024) {
1187    must_be_32bit = true;
1188  }
1189
1190  if (byte) {
1191    // 5 bit offset, no shift.
1192    if (offset > 32) {
1193      must_be_32bit = true;
1194    }
1195  } else if (half) {
1196    // 6 bit offset, shifted by 1.
1197    if (offset > 64) {
1198      must_be_32bit = true;
1199    }
1200  } else {
1201    // 7 bit offset, shifted by 2.
1202    if (offset > 128) {
1203       must_be_32bit = true;
1204     }
1205  }
1206
1207  if (must_be_32bit) {
1208    int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1209                  (load ? B20 : 0) |
1210                  (is_signed ? B24 : 0) |
1211                  static_cast<uint32_t>(rd) << 12 |
1212                  ad.encodingThumb(2) |
1213                  (byte ? 0 : half ? B21 : B22);
1214    Emit32(encoding);
1215  } else {
1216    // 16 bit thumb1.
1217    uint8_t opA = 0;
1218    bool sp_relative = false;
1219
1220    if (byte) {
1221      opA = 0b0111;
1222    } else if (half) {
1223      opA = 0b1000;
1224    } else {
1225      if (rn == SP) {
1226        opA = 0b1001;
1227        sp_relative = true;
1228      } else {
1229        opA = 0b0110;
1230      }
1231    }
1232    int16_t encoding = opA << 12 |
1233                (load ? B11 : 0);
1234
1235    CHECK_GE(offset, 0);
1236    if (sp_relative) {
1237      // SP relative, 10 bit offset.
1238      CHECK_LT(offset, 1024);
1239      CHECK_EQ((offset & 0b11), 0);
1240      encoding |= rd << 8 | offset >> 2;
1241    } else {
1242      // No SP relative.  The offset is shifted right depending on
1243      // the size of the load/store.
1244      encoding |= static_cast<uint32_t>(rd);
1245
1246      if (byte) {
1247        // 5 bit offset, no shift.
1248        CHECK_LT(offset, 32);
1249      } else if (half) {
1250        // 6 bit offset, shifted by 1.
1251        CHECK_LT(offset, 64);
1252        CHECK_EQ((offset & 0b1), 0);
1253        offset >>= 1;
1254      } else {
1255        // 7 bit offset, shifted by 2.
1256        CHECK_LT(offset, 128);
1257        CHECK_EQ((offset & 0b11), 0);
1258        offset >>= 2;
1259      }
1260      encoding |= rn << 3 | offset  << 6;
1261    }
1262
1263    Emit16(encoding);
1264  }
1265}
1266
1267
1268void Thumb2Assembler::EmitMultiMemOp(Condition cond,
1269                                     BlockAddressMode am,
1270                                     bool load,
1271                                     Register base,
1272                                     RegList regs) {
1273  CHECK_NE(base, kNoRegister);
1274  CheckCondition(cond);
1275  bool must_be_32bit = force_32bit_;
1276
1277  if ((regs & 0xff00) != 0) {
1278    must_be_32bit = true;
1279  }
1280
1281  uint32_t w_bit = am == IA_W || am == DB_W || am == DA_W || am == IB_W;
1282  // 16 bit always uses writeback.
1283  if (!w_bit) {
1284    must_be_32bit = true;
1285  }
1286
1287  if (must_be_32bit) {
1288    uint32_t op = 0;
1289    switch (am) {
1290      case IA:
1291      case IA_W:
1292        op = 0b01;
1293        break;
1294      case DB:
1295      case DB_W:
1296        op = 0b10;
1297        break;
1298      case DA:
1299      case IB:
1300      case DA_W:
1301      case IB_W:
1302        LOG(FATAL) << "LDM/STM mode not supported on thumb: " << am;
1303    }
1304    if (load) {
1305      // Cannot have SP in the list.
1306      CHECK_EQ((regs & (1 << SP)), 0);
1307    } else {
1308      // Cannot have PC or SP in the list.
1309      CHECK_EQ((regs & (1 << PC | 1 << SP)), 0);
1310    }
1311    int32_t encoding = B31 | B30 | B29 | B27 |
1312                    (op << 23) |
1313                    (load ? B20 : 0) |
1314                    base << 16 |
1315                    regs |
1316                    (w_bit << 21);
1317    Emit32(encoding);
1318  } else {
1319    int16_t encoding = B15 | B14 |
1320                    (load ? B11 : 0) |
1321                    base << 8 |
1322                    regs;
1323    Emit16(encoding);
1324  }
1325}
1326
1327
1328void Thumb2Assembler::EmitBranch(Condition cond, Label* label, bool link, bool x) {
1329  uint32_t pc = buffer_.Size();
1330  Branch::Type branch_type;
1331  if (cond == AL) {
1332    if (link) {
1333      if (x) {
1334        branch_type = Branch::kUnconditionalLinkX;      // BLX.
1335      } else {
1336        branch_type = Branch::kUnconditionalLink;       // BX.
1337      }
1338    } else {
1339      branch_type = Branch::kUnconditional;             // B.
1340    }
1341  } else {
1342    branch_type = Branch::kConditional;                 // B<cond>.
1343  }
1344
1345  if (label->IsBound()) {
1346    Branch::Size size = AddBranch(branch_type, pc, label->Position(), cond);  // Resolved branch.
1347
1348    // The branch is to a bound label which means that it's a backwards branch.  We know the
1349    // current size of it so we can emit the appropriate space.  Note that if it's a 16 bit
1350    // branch the size may change if it so happens that other branches change size that change
1351    // the distance to the target and that distance puts this branch over the limit for 16 bits.
1352    if (size == Branch::k16Bit) {
1353      Emit16(0);          // Space for a 16 bit branch.
1354    } else {
1355      Emit32(0);            // Space for a 32 bit branch.
1356    }
1357  } else {
1358    // Branch is to an unbound label.  Emit space for it.
1359    uint16_t branch_id = AddBranch(branch_type, pc, cond);    // Unresolved branch.
1360    if (force_32bit_) {
1361      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1362      Emit16(0);                   // another 16 bits.
1363    } else {
1364      Emit16(static_cast<uint16_t>(label->position_));    // Emit current label link.
1365    }
1366    label->LinkTo(branch_id);           // Link to the branch ID.
1367  }
1368}
1369
1370
1371void Thumb2Assembler::clz(Register rd, Register rm, Condition cond) {
1372  CHECK_NE(rd, kNoRegister);
1373  CHECK_NE(rm, kNoRegister);
1374  CheckCondition(cond);
1375  CHECK_NE(rd, PC);
1376  CHECK_NE(rm, PC);
1377  int32_t encoding = B31 | B30 | B29 | B28 | B27 |
1378      B25 | B23 | B21 | B20 |
1379      static_cast<uint32_t>(rm) << 16 |
1380      0xf << 12 |
1381      static_cast<uint32_t>(rd) << 8 |
1382      B7 |
1383      static_cast<uint32_t>(rm);
1384  Emit32(encoding);
1385}
1386
1387
1388void Thumb2Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
1389  CheckCondition(cond);
1390  bool must_be_32bit = force_32bit_;
1391  if (IsHighRegister(rd)|| imm16 >= 256u) {
1392    must_be_32bit = true;
1393  }
1394
1395  if (must_be_32bit) {
1396    // Use encoding T3.
1397    uint32_t imm4 = (imm16 >> 12) & 0b1111;
1398    uint32_t i = (imm16 >> 11) & 0b1;
1399    uint32_t imm3 = (imm16 >> 8) & 0b111;
1400    uint32_t imm8 = imm16 & 0xff;
1401    int32_t encoding = B31 | B30 | B29 | B28 |
1402                    B25 | B22 |
1403                    static_cast<uint32_t>(rd) << 8 |
1404                    i << 26 |
1405                    imm4 << 16 |
1406                    imm3 << 12 |
1407                    imm8;
1408    Emit32(encoding);
1409  } else {
1410    int16_t encoding = B13 | static_cast<uint16_t>(rd) << 8 |
1411                imm16;
1412    Emit16(encoding);
1413  }
1414}
1415
1416
1417void Thumb2Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
1418  CheckCondition(cond);
1419  // Always 32 bits.
1420  uint32_t imm4 = (imm16 >> 12) & 0b1111;
1421  uint32_t i = (imm16 >> 11) & 0b1;
1422  uint32_t imm3 = (imm16 >> 8) & 0b111;
1423  uint32_t imm8 = imm16 & 0xff;
1424  int32_t encoding = B31 | B30 | B29 | B28 |
1425                  B25 | B23 | B22 |
1426                  static_cast<uint32_t>(rd) << 8 |
1427                  i << 26 |
1428                  imm4 << 16 |
1429                  imm3 << 12 |
1430                  imm8;
1431  Emit32(encoding);
1432}
1433
1434
1435void Thumb2Assembler::ldrex(Register rt, Register rn, uint16_t imm, Condition cond) {
1436  CHECK_NE(rn, kNoRegister);
1437  CHECK_NE(rt, kNoRegister);
1438  CheckCondition(cond);
1439  CHECK_NE(rn, kNoRegister);
1440  CHECK_NE(rt, kNoRegister);
1441  CheckCondition(cond);
1442  CHECK_LT(imm, (1u << 10));
1443
1444  int32_t encoding = B31 | B30 | B29 | B27 | B22 | B20 |
1445      static_cast<uint32_t>(rn) << 16 |
1446      static_cast<uint32_t>(rt) << 12 |
1447      0xf << 8 |
1448      imm >> 2;
1449  Emit32(encoding);
1450}
1451
1452
1453void Thumb2Assembler::ldrex(Register rt, Register rn, Condition cond) {
1454  ldrex(rt, rn, 0, cond);
1455}
1456
1457
1458void Thumb2Assembler::strex(Register rd,
1459                            Register rt,
1460                            Register rn,
1461                            uint16_t imm,
1462                            Condition cond) {
1463  CHECK_NE(rn, kNoRegister);
1464  CHECK_NE(rd, kNoRegister);
1465  CHECK_NE(rt, kNoRegister);
1466  CheckCondition(cond);
1467  CHECK_LT(imm, (1u << 10));
1468
1469  int32_t encoding = B31 | B30 | B29 | B27 | B22 |
1470      static_cast<uint32_t>(rn) << 16 |
1471      static_cast<uint32_t>(rt) << 12 |
1472      static_cast<uint32_t>(rd) << 8 |
1473      imm >> 2;
1474  Emit32(encoding);
1475}
1476
1477
1478void Thumb2Assembler::strex(Register rd,
1479                            Register rt,
1480                            Register rn,
1481                            Condition cond) {
1482  strex(rd, rt, rn, 0, cond);
1483}
1484
1485
1486void Thumb2Assembler::clrex(Condition cond) {
1487  CheckCondition(cond);
1488  int32_t encoding = B31 | B30 | B29 | B27 | B28 | B25 | B24 | B23 |
1489      B21 | B20 |
1490      0xf << 16 |
1491      B15 |
1492      0xf << 8 |
1493      B5 |
1494      0xf;
1495  Emit32(encoding);
1496}
1497
1498
1499void Thumb2Assembler::nop(Condition cond) {
1500  CheckCondition(cond);
1501  int16_t encoding = B15 | B13 | B12 |
1502      B11 | B10 | B9 | B8;
1503  Emit16(encoding);
1504}
1505
1506
1507void Thumb2Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
1508  CHECK_NE(sn, kNoSRegister);
1509  CHECK_NE(rt, kNoRegister);
1510  CHECK_NE(rt, SP);
1511  CHECK_NE(rt, PC);
1512  CheckCondition(cond);
1513  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1514                     B27 | B26 | B25 |
1515                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1516                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1517                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1518  Emit32(encoding);
1519}
1520
1521
1522void Thumb2Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
1523  CHECK_NE(sn, kNoSRegister);
1524  CHECK_NE(rt, kNoRegister);
1525  CHECK_NE(rt, SP);
1526  CHECK_NE(rt, PC);
1527  CheckCondition(cond);
1528  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1529                     B27 | B26 | B25 | B20 |
1530                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1531                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1532                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
1533  Emit32(encoding);
1534}
1535
1536
1537void Thumb2Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
1538                              Condition cond) {
1539  CHECK_NE(sm, kNoSRegister);
1540  CHECK_NE(sm, S31);
1541  CHECK_NE(rt, kNoRegister);
1542  CHECK_NE(rt, SP);
1543  CHECK_NE(rt, PC);
1544  CHECK_NE(rt2, kNoRegister);
1545  CHECK_NE(rt2, SP);
1546  CHECK_NE(rt2, PC);
1547  CheckCondition(cond);
1548  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1549                     B27 | B26 | B22 |
1550                     (static_cast<int32_t>(rt2)*B16) |
1551                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1552                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1553                     (static_cast<int32_t>(sm) >> 1);
1554  Emit32(encoding);
1555}
1556
1557
1558void Thumb2Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
1559                              Condition cond) {
1560  CHECK_NE(sm, kNoSRegister);
1561  CHECK_NE(sm, S31);
1562  CHECK_NE(rt, kNoRegister);
1563  CHECK_NE(rt, SP);
1564  CHECK_NE(rt, PC);
1565  CHECK_NE(rt2, kNoRegister);
1566  CHECK_NE(rt2, SP);
1567  CHECK_NE(rt2, PC);
1568  CHECK_NE(rt, rt2);
1569  CheckCondition(cond);
1570  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1571                     B27 | B26 | B22 | B20 |
1572                     (static_cast<int32_t>(rt2)*B16) |
1573                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
1574                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
1575                     (static_cast<int32_t>(sm) >> 1);
1576  Emit32(encoding);
1577}
1578
1579
1580void Thumb2Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
1581                              Condition cond) {
1582  CHECK_NE(dm, kNoDRegister);
1583  CHECK_NE(rt, kNoRegister);
1584  CHECK_NE(rt, SP);
1585  CHECK_NE(rt, PC);
1586  CHECK_NE(rt2, kNoRegister);
1587  CHECK_NE(rt2, SP);
1588  CHECK_NE(rt2, PC);
1589  CheckCondition(cond);
1590  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1591                     B27 | B26 | B22 |
1592                     (static_cast<int32_t>(rt2)*B16) |
1593                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1594                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1595                     (static_cast<int32_t>(dm) & 0xf);
1596  Emit32(encoding);
1597}
1598
1599
1600void Thumb2Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
1601                              Condition cond) {
1602  CHECK_NE(dm, kNoDRegister);
1603  CHECK_NE(rt, kNoRegister);
1604  CHECK_NE(rt, SP);
1605  CHECK_NE(rt, PC);
1606  CHECK_NE(rt2, kNoRegister);
1607  CHECK_NE(rt2, SP);
1608  CHECK_NE(rt2, PC);
1609  CHECK_NE(rt, rt2);
1610  CheckCondition(cond);
1611  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1612                     B27 | B26 | B22 | B20 |
1613                     (static_cast<int32_t>(rt2)*B16) |
1614                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
1615                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
1616                     (static_cast<int32_t>(dm) & 0xf);
1617  Emit32(encoding);
1618}
1619
1620
1621void Thumb2Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
1622  const Address& addr = static_cast<const Address&>(ad);
1623  CHECK_NE(sd, kNoSRegister);
1624  CheckCondition(cond);
1625  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1626                     B27 | B26 | B24 | B20 |
1627                     ((static_cast<int32_t>(sd) & 1)*B22) |
1628                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1629                     B11 | B9 | addr.vencoding();
1630  Emit32(encoding);
1631}
1632
1633
1634void Thumb2Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
1635  const Address& addr = static_cast<const Address&>(ad);
1636  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1637  CHECK_NE(sd, kNoSRegister);
1638  CheckCondition(cond);
1639  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1640                     B27 | B26 | B24 |
1641                     ((static_cast<int32_t>(sd) & 1)*B22) |
1642                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1643                     B11 | B9 | addr.vencoding();
1644  Emit32(encoding);
1645}
1646
1647
1648void Thumb2Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
1649  const Address& addr = static_cast<const Address&>(ad);
1650  CHECK_NE(dd, kNoDRegister);
1651  CheckCondition(cond);
1652  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1653                     B27 | B26 | B24 | B20 |
1654                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1655                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1656                     B11 | B9 | B8 | addr.vencoding();
1657  Emit32(encoding);
1658}
1659
1660
1661void Thumb2Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
1662  const Address& addr = static_cast<const Address&>(ad);
1663  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
1664  CHECK_NE(dd, kNoDRegister);
1665  CheckCondition(cond);
1666  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1667                     B27 | B26 | B24 |
1668                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1669                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1670                     B11 | B9 | B8 | addr.vencoding();
1671  Emit32(encoding);
1672}
1673
1674
1675void Thumb2Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
1676  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
1677}
1678
1679
1680void Thumb2Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
1681  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
1682}
1683
1684
1685void Thumb2Assembler::vpops(SRegister reg, int nregs, Condition cond) {
1686  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
1687}
1688
1689
1690void Thumb2Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
1691  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
1692}
1693
1694
1695void Thumb2Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
1696  CheckCondition(cond);
1697
1698  uint32_t D;
1699  uint32_t Vd;
1700  if (dbl) {
1701    // Encoded as D:Vd.
1702    D = (reg >> 4) & 1;
1703    Vd = reg & 0b1111;
1704  } else {
1705    // Encoded as Vd:D.
1706    D = reg & 1;
1707    Vd = (reg >> 1) & 0b1111;
1708  }
1709  int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
1710                    B11 | B9 |
1711        (dbl ? B8 : 0) |
1712        (push ? B24 : (B23 | B20)) |
1713        0b1110 << 28 |
1714        nregs << (dbl ? 1 : 0) |
1715        D << 22 |
1716        Vd << 12;
1717  Emit32(encoding);
1718}
1719
1720
1721void Thumb2Assembler::EmitVFPsss(Condition cond, int32_t opcode,
1722                                 SRegister sd, SRegister sn, SRegister sm) {
1723  CHECK_NE(sd, kNoSRegister);
1724  CHECK_NE(sn, kNoSRegister);
1725  CHECK_NE(sm, kNoSRegister);
1726  CheckCondition(cond);
1727  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1728                     B27 | B26 | B25 | B11 | B9 | opcode |
1729                     ((static_cast<int32_t>(sd) & 1)*B22) |
1730                     ((static_cast<int32_t>(sn) >> 1)*B16) |
1731                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1732                     ((static_cast<int32_t>(sn) & 1)*B7) |
1733                     ((static_cast<int32_t>(sm) & 1)*B5) |
1734                     (static_cast<int32_t>(sm) >> 1);
1735  Emit32(encoding);
1736}
1737
1738
1739void Thumb2Assembler::EmitVFPddd(Condition cond, int32_t opcode,
1740                                 DRegister dd, DRegister dn, DRegister dm) {
1741  CHECK_NE(dd, kNoDRegister);
1742  CHECK_NE(dn, kNoDRegister);
1743  CHECK_NE(dm, kNoDRegister);
1744  CheckCondition(cond);
1745  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1746                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1747                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1748                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
1749                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1750                     ((static_cast<int32_t>(dn) >> 4)*B7) |
1751                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1752                     (static_cast<int32_t>(dm) & 0xf);
1753  Emit32(encoding);
1754}
1755
1756
1757void Thumb2Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1758                                SRegister sd, DRegister dm) {
1759  CHECK_NE(sd, kNoSRegister);
1760  CHECK_NE(dm, kNoDRegister);
1761  CheckCondition(cond);
1762  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1763                     B27 | B26 | B25 | B11 | B9 | opcode |
1764                     ((static_cast<int32_t>(sd) & 1)*B22) |
1765                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1766                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1767                     (static_cast<int32_t>(dm) & 0xf);
1768  Emit32(encoding);
1769}
1770
1771
1772void Thumb2Assembler::EmitVFPds(Condition cond, int32_t opcode,
1773                                DRegister dd, SRegister sm) {
1774  CHECK_NE(dd, kNoDRegister);
1775  CHECK_NE(sm, kNoSRegister);
1776  CheckCondition(cond);
1777  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1778                     B27 | B26 | B25 | B11 | B9 | opcode |
1779                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1780                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1781                     ((static_cast<int32_t>(sm) & 1)*B5) |
1782                     (static_cast<int32_t>(sm) >> 1);
1783  Emit32(encoding);
1784}
1785
1786
1787void Thumb2Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR.
1788  CheckCondition(cond);
1789  UNIMPLEMENTED(FATAL) << "Unimplemented thumb instruction";
1790}
1791
1792
1793void Thumb2Assembler::svc(uint32_t imm8) {
1794  CHECK(IsUint(8, imm8)) << imm8;
1795  int16_t encoding = B15 | B14 | B12 |
1796       B11 | B10 | B9 | B8 |
1797       imm8;
1798  Emit16(encoding);
1799}
1800
1801
1802void Thumb2Assembler::bkpt(uint16_t imm8) {
1803  CHECK(IsUint(8, imm8)) << imm8;
1804  int16_t encoding = B15 | B13 | B12 |
1805      B11 | B10 | B9 |
1806      imm8;
1807  Emit16(encoding);
1808}
1809
1810// Convert the given IT state to a mask bit given bit 0 of the first
1811// condition and a shift position.
1812static uint8_t ToItMask(ItState s, uint8_t firstcond0, uint8_t shift) {
1813  switch (s) {
1814  case kItOmitted: return 1 << shift;
1815  case kItThen: return firstcond0 << shift;
1816  case kItElse: return !firstcond0 << shift;
1817  }
1818  return 0;
1819}
1820
1821
1822// Set the IT condition in the given position for the given state.  This is used
1823// to check that conditional instructions match the preceding IT statement.
1824void Thumb2Assembler::SetItCondition(ItState s, Condition cond, uint8_t index) {
1825  switch (s) {
1826  case kItOmitted: it_conditions_[index] = AL; break;
1827  case kItThen: it_conditions_[index] = cond; break;
1828  case kItElse:
1829    it_conditions_[index] = static_cast<Condition>(static_cast<uint8_t>(cond) ^ 1);
1830    break;
1831  }
1832}
1833
1834
1835void Thumb2Assembler::it(Condition firstcond, ItState i1, ItState i2, ItState i3) {
1836  CheckCondition(AL);       // Not allowed in IT block.
1837  uint8_t firstcond0 = static_cast<uint8_t>(firstcond) & 1;
1838
1839  // All conditions to AL.
1840  for (uint8_t i = 0; i < 4; ++i) {
1841    it_conditions_[i] = AL;
1842  }
1843
1844  SetItCondition(kItThen, firstcond, 0);
1845  uint8_t mask = ToItMask(i1, firstcond0, 3);
1846  SetItCondition(i1, firstcond, 1);
1847
1848  if (i1 != kItOmitted) {
1849    mask |= ToItMask(i2, firstcond0, 2);
1850    SetItCondition(i2, firstcond, 2);
1851    if (i2 != kItOmitted) {
1852      mask |= ToItMask(i3, firstcond0, 1);
1853      SetItCondition(i3, firstcond, 3);
1854      if (i3 != kItOmitted) {
1855        mask |= 0b0001;
1856      }
1857    }
1858  }
1859
1860  // Start at first condition.
1861  it_cond_index_ = 0;
1862  next_condition_ = it_conditions_[0];
1863  uint16_t encoding = B15 | B13 | B12 |
1864        B11 | B10 | B9 | B8 |
1865        firstcond << 4 |
1866        mask;
1867  Emit16(encoding);
1868}
1869
1870
1871void Thumb2Assembler::cbz(Register rn, Label* label) {
1872  CheckCondition(AL);
1873  if (label->IsBound()) {
1874    LOG(FATAL) << "cbz can only be used to branch forwards";
1875  } else {
1876    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), false);
1877    label->LinkTo(branchid);
1878  }
1879}
1880
1881
1882void Thumb2Assembler::cbnz(Register rn, Label* label) {
1883  CheckCondition(AL);
1884  if (label->IsBound()) {
1885    LOG(FATAL) << "cbnz can only be used to branch forwards";
1886  } else {
1887    uint16_t branchid = EmitCompareAndBranch(rn, static_cast<uint16_t>(label->position_), true);
1888    label->LinkTo(branchid);
1889  }
1890}
1891
1892
1893void Thumb2Assembler::blx(Register rm, Condition cond) {
1894  CHECK_NE(rm, kNoRegister);
1895  CheckCondition(cond);
1896  int16_t encoding = B14 | B10 | B9 | B8 | B7 | static_cast<int16_t>(rm) << 3;
1897  Emit16(encoding);
1898}
1899
1900
1901void Thumb2Assembler::bx(Register rm, Condition cond) {
1902  CHECK_NE(rm, kNoRegister);
1903  CheckCondition(cond);
1904  int16_t encoding = B14 | B10 | B9 | B8 | static_cast<int16_t>(rm) << 3;
1905  Emit16(encoding);
1906}
1907
1908
1909void Thumb2Assembler::Push(Register rd, Condition cond) {
1910  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
1911}
1912
1913
1914void Thumb2Assembler::Pop(Register rd, Condition cond) {
1915  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
1916}
1917
1918
1919void Thumb2Assembler::PushList(RegList regs, Condition cond) {
1920  stm(DB_W, SP, regs, cond);
1921}
1922
1923
1924void Thumb2Assembler::PopList(RegList regs, Condition cond) {
1925  ldm(IA_W, SP, regs, cond);
1926}
1927
1928
1929void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
1930  if (cond != AL || rd != rm) {
1931    mov(rd, ShifterOperand(rm), cond);
1932  }
1933}
1934
1935
1936// A branch has changed size.  Make a hole for it.
1937void Thumb2Assembler::MakeHoleForBranch(uint32_t location, uint32_t delta) {
1938  // Move the contents of the buffer using: Move(newposition, oldposition)
1939  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1940  buffer_.Move(location + delta, location);
1941}
1942
1943
1944void Thumb2Assembler::Bind(Label* label) {
1945  CHECK(!label->IsBound());
1946  uint32_t bound_pc = buffer_.Size();
1947  std::vector<Branch*> changed_branches;
1948
1949  while (label->IsLinked()) {
1950    uint16_t position = label->Position();                  // Branch id for linked branch.
1951    Branch* branch = GetBranch(position);                   // Get the branch at this id.
1952    bool changed = branch->Resolve(bound_pc);               // Branch can be resolved now.
1953    uint32_t branch_location = branch->GetLocation();
1954    uint16_t next = buffer_.Load<uint16_t>(branch_location);       // Get next in chain.
1955    if (changed) {
1956      MakeHoleForBranch(branch->GetLocation(), 2);
1957      if (branch->IsCompareAndBranch()) {
1958        // A cbz/cbnz instruction has changed size.  There is no valid encoding for
1959        // a 32 bit cbz/cbnz so we need to change this to an instruction pair:
1960        // cmp rn, #0
1961        // b<eq|ne> target
1962        bool n = branch->GetType() == Branch::kCompareAndBranchNonZero;
1963        Condition cond = n ? NE : EQ;
1964        branch->Move(2);      // Move the branch forward by 2 bytes.
1965        branch->ResetTypeAndCondition(Branch::kConditional, cond);
1966        branch->ResetSize(Branch::k16Bit);
1967
1968        // Now add a compare instruction in the place the branch was.
1969        int16_t cmp = B13 | B11 | static_cast<int16_t>(branch->GetRegister()) << 8;
1970        buffer_.Store<int16_t>(branch_location, cmp);
1971
1972        // Since have moved made a hole in the code we need to reload the
1973        // current pc.
1974        bound_pc = buffer_.Size();
1975
1976        // Now resolve the newly added branch.
1977        changed = branch->Resolve(bound_pc);
1978        if (changed) {
1979          MakeHoleForBranch(branch->GetLocation(), 2);
1980          changed_branches.push_back(branch);
1981        }
1982      } else {
1983        changed_branches.push_back(branch);
1984      }
1985    }
1986    label->position_ = next;                                // Move to next.
1987  }
1988  label->BindTo(bound_pc);
1989
1990  // Now relocate any changed branches.  Do this until there are no more changes.
1991  std::vector<Branch*> branches_to_process = changed_branches;
1992  while (branches_to_process.size() != 0) {
1993    changed_branches.clear();
1994    for (auto& changed_branch : branches_to_process) {
1995      for (auto& branch : branches_) {
1996        bool changed = branch->Relocate(changed_branch->GetLocation(), 2);
1997        if (changed) {
1998          changed_branches.push_back(branch);
1999        }
2000      }
2001      branches_to_process = changed_branches;
2002    }
2003  }
2004}
2005
2006
2007void Thumb2Assembler::EmitBranches() {
2008  for (auto& branch : branches_) {
2009    branch->Emit(&buffer_);
2010  }
2011}
2012
2013
2014void Thumb2Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
2015                          Condition cond) {
2016  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
2017  mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
2018}
2019
2020
2021void Thumb2Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
2022                          Condition cond) {
2023  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
2024  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2025  mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
2026}
2027
2028
2029void Thumb2Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
2030                          Condition cond) {
2031  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
2032  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
2033  mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
2034}
2035
2036
2037void Thumb2Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
2038                          Condition cond) {
2039  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
2040  mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
2041}
2042
2043
2044void Thumb2Assembler::Rrx(Register rd, Register rm, Condition cond) {
2045  mov(rd, ShifterOperand(rm, ROR, 0), cond);
2046}
2047
2048
2049int32_t Thumb2Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
2050  // The offset is off by 4 due to the way the ARM CPUs read PC.
2051  offset -= 4;
2052  offset >>= 1;
2053
2054  uint32_t value = 0;
2055  // There are two different encodings depending on the value of bit 12.  In one case
2056  // intermediate values are calculated using the sign bit.
2057  if ((inst & B12) == B12) {
2058    // 25 bits of offset.
2059    uint32_t signbit = (offset >> 31) & 0x1;
2060    uint32_t i1 = (offset >> 22) & 0x1;
2061    uint32_t i2 = (offset >> 21) & 0x1;
2062    uint32_t imm10 = (offset >> 11) & 0x03ff;
2063    uint32_t imm11 = offset & 0x07ff;
2064    uint32_t j1 = (i1 ^ signbit) ? 0 : 1;
2065    uint32_t j2 = (i2 ^ signbit) ? 0 : 1;
2066    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm10 << 16) |
2067                      imm11;
2068    // Remove the offset from the current encoding.
2069    inst &= ~(0x3ff << 16 | 0x7ff);
2070  } else {
2071    uint32_t signbit = (offset >> 31) & 0x1;
2072    uint32_t imm6 = (offset >> 11) & 0x03f;
2073    uint32_t imm11 = offset & 0x07ff;
2074    uint32_t j1 = (offset >> 19) & 1;
2075    uint32_t j2 = (offset >> 17) & 1;
2076    value = (signbit << 26) | (j1 << 13) | (j2 << 11) | (imm6 << 16) |
2077        imm11;
2078    // Remove the offset from the current encoding.
2079    inst &= ~(0x3f << 16 | 0x7ff);
2080  }
2081  // Mask out offset bits in current instruction.
2082  inst &= ~(B26 | B13 | B11);
2083  inst |= value;
2084  return inst;
2085}
2086
2087
2088int Thumb2Assembler::DecodeBranchOffset(int32_t instr) {
2089  int32_t imm32;
2090  if ((instr & B12) == B12) {
2091    uint32_t S = (instr >> 26) & 1;
2092    uint32_t J2 = (instr >> 11) & 1;
2093    uint32_t J1 = (instr >> 13) & 1;
2094    uint32_t imm10 = (instr >> 16) & 0x3FF;
2095    uint32_t imm11 = instr & 0x7FF;
2096
2097    uint32_t I1 = ~(J1 ^ S) & 1;
2098    uint32_t I2 = ~(J2 ^ S) & 1;
2099    imm32 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2100    imm32 = (imm32 << 8) >> 8;  // sign extend 24 bit immediate.
2101  } else {
2102    uint32_t S = (instr >> 26) & 1;
2103    uint32_t J2 = (instr >> 11) & 1;
2104    uint32_t J1 = (instr >> 13) & 1;
2105    uint32_t imm6 = (instr >> 16) & 0x3F;
2106    uint32_t imm11 = instr & 0x7FF;
2107
2108    imm32 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2109    imm32 = (imm32 << 11) >> 11;  // sign extend 21 bit immediate.
2110  }
2111  imm32 += 4;
2112  return imm32;
2113}
2114
2115
2116void Thumb2Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
2117  AddConstant(rd, rd, value, cond);
2118}
2119
2120
2121void Thumb2Assembler::AddConstant(Register rd, Register rn, int32_t value,
2122                                  Condition cond) {
2123  if (value == 0) {
2124    if (rd != rn) {
2125      mov(rd, ShifterOperand(rn), cond);
2126    }
2127    return;
2128  }
2129  // We prefer to select the shorter code sequence rather than selecting add for
2130  // positive values and sub for negatives ones, which would slightly improve
2131  // the readability of generated code for some constants.
2132  ShifterOperand shifter_op;
2133  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2134    add(rd, rn, shifter_op, cond);
2135  } else if (ShifterOperand::CanHoldThumb(rd, rn, SUB, -value, &shifter_op)) {
2136    sub(rd, rn, shifter_op, cond);
2137  } else {
2138    CHECK(rn != IP);
2139    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2140      mvn(IP, shifter_op, cond);
2141      add(rd, rn, ShifterOperand(IP), cond);
2142    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2143      mvn(IP, shifter_op, cond);
2144      sub(rd, rn, ShifterOperand(IP), cond);
2145    } else {
2146      movw(IP, Low16Bits(value), cond);
2147      uint16_t value_high = High16Bits(value);
2148      if (value_high != 0) {
2149        movt(IP, value_high, cond);
2150      }
2151      add(rd, rn, ShifterOperand(IP), cond);
2152    }
2153  }
2154}
2155
2156
2157void Thumb2Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
2158                                          Condition cond) {
2159  ShifterOperand shifter_op;
2160  if (ShifterOperand::CanHoldThumb(rd, rn, ADD, value, &shifter_op)) {
2161    adds(rd, rn, shifter_op, cond);
2162  } else if (ShifterOperand::CanHoldThumb(rd, rn, ADD, -value, &shifter_op)) {
2163    subs(rd, rn, shifter_op, cond);
2164  } else {
2165    CHECK(rn != IP);
2166    if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~value, &shifter_op)) {
2167      mvn(IP, shifter_op, cond);
2168      adds(rd, rn, ShifterOperand(IP), cond);
2169    } else if (ShifterOperand::CanHoldThumb(rd, rn, MVN, ~(-value), &shifter_op)) {
2170      mvn(IP, shifter_op, cond);
2171      subs(rd, rn, ShifterOperand(IP), cond);
2172    } else {
2173      movw(IP, Low16Bits(value), cond);
2174      uint16_t value_high = High16Bits(value);
2175      if (value_high != 0) {
2176        movt(IP, value_high, cond);
2177      }
2178      adds(rd, rn, ShifterOperand(IP), cond);
2179    }
2180  }
2181}
2182
2183
2184void Thumb2Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
2185  ShifterOperand shifter_op;
2186  if (ShifterOperand::CanHoldThumb(rd, R0, MOV, value, &shifter_op)) {
2187    mov(rd, shifter_op, cond);
2188  } else if (ShifterOperand::CanHoldThumb(rd, R0, MVN, ~value, &shifter_op)) {
2189    mvn(rd, shifter_op, cond);
2190  } else {
2191    movw(rd, Low16Bits(value), cond);
2192    uint16_t value_high = High16Bits(value);
2193    if (value_high != 0) {
2194      movt(rd, value_high, cond);
2195    }
2196  }
2197}
2198
2199// Implementation note: this method must emit at most one instruction when
2200// Address::CanHoldLoadOffsetThumb.
2201void Thumb2Assembler::LoadFromOffset(LoadOperandType type,
2202                                     Register reg,
2203                                     Register base,
2204                                     int32_t offset,
2205                                     Condition cond) {
2206  if (!Address::CanHoldLoadOffsetThumb(type, offset)) {
2207    CHECK(base != IP);
2208    LoadImmediate(IP, offset, cond);
2209    add(IP, IP, ShifterOperand(base), cond);
2210    base = IP;
2211    offset = 0;
2212  }
2213  CHECK(Address::CanHoldLoadOffsetThumb(type, offset));
2214  switch (type) {
2215    case kLoadSignedByte:
2216      ldrsb(reg, Address(base, offset), cond);
2217      break;
2218    case kLoadUnsignedByte:
2219      ldrb(reg, Address(base, offset), cond);
2220      break;
2221    case kLoadSignedHalfword:
2222      ldrsh(reg, Address(base, offset), cond);
2223      break;
2224    case kLoadUnsignedHalfword:
2225      ldrh(reg, Address(base, offset), cond);
2226      break;
2227    case kLoadWord:
2228      ldr(reg, Address(base, offset), cond);
2229      break;
2230    case kLoadWordPair:
2231      ldrd(reg, Address(base, offset), cond);
2232      break;
2233    default:
2234      LOG(FATAL) << "UNREACHABLE";
2235  }
2236}
2237
2238
2239// Implementation note: this method must emit at most one instruction when
2240// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2241void Thumb2Assembler::LoadSFromOffset(SRegister reg,
2242                                      Register base,
2243                                      int32_t offset,
2244                                      Condition cond) {
2245  if (!Address::CanHoldLoadOffsetThumb(kLoadSWord, offset)) {
2246    CHECK_NE(base, IP);
2247    LoadImmediate(IP, offset, cond);
2248    add(IP, IP, ShifterOperand(base), cond);
2249    base = IP;
2250    offset = 0;
2251  }
2252  CHECK(Address::CanHoldLoadOffsetThumb(kLoadSWord, offset));
2253  vldrs(reg, Address(base, offset), cond);
2254}
2255
2256
2257// Implementation note: this method must emit at most one instruction when
2258// Address::CanHoldLoadOffsetThumb, as expected by JIT::GuardedLoadFromOffset.
2259void Thumb2Assembler::LoadDFromOffset(DRegister reg,
2260                                      Register base,
2261                                      int32_t offset,
2262                                      Condition cond) {
2263  if (!Address::CanHoldLoadOffsetThumb(kLoadDWord, offset)) {
2264    CHECK_NE(base, IP);
2265    LoadImmediate(IP, offset, cond);
2266    add(IP, IP, ShifterOperand(base), cond);
2267    base = IP;
2268    offset = 0;
2269  }
2270  CHECK(Address::CanHoldLoadOffsetThumb(kLoadDWord, offset));
2271  vldrd(reg, Address(base, offset), cond);
2272}
2273
2274
2275// Implementation note: this method must emit at most one instruction when
2276// Address::CanHoldStoreOffsetThumb.
2277void Thumb2Assembler::StoreToOffset(StoreOperandType type,
2278                                    Register reg,
2279                                    Register base,
2280                                    int32_t offset,
2281                                    Condition cond) {
2282  if (!Address::CanHoldStoreOffsetThumb(type, offset)) {
2283    CHECK(reg != IP);
2284    CHECK(base != IP);
2285    LoadImmediate(IP, offset, cond);
2286    add(IP, IP, ShifterOperand(base), cond);
2287    base = IP;
2288    offset = 0;
2289  }
2290  CHECK(Address::CanHoldStoreOffsetThumb(type, offset));
2291  switch (type) {
2292    case kStoreByte:
2293      strb(reg, Address(base, offset), cond);
2294      break;
2295    case kStoreHalfword:
2296      strh(reg, Address(base, offset), cond);
2297      break;
2298    case kStoreWord:
2299      str(reg, Address(base, offset), cond);
2300      break;
2301    case kStoreWordPair:
2302      strd(reg, Address(base, offset), cond);
2303      break;
2304    default:
2305      LOG(FATAL) << "UNREACHABLE";
2306  }
2307}
2308
2309
2310// Implementation note: this method must emit at most one instruction when
2311// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreToOffset.
2312void Thumb2Assembler::StoreSToOffset(SRegister reg,
2313                                     Register base,
2314                                     int32_t offset,
2315                                     Condition cond) {
2316  if (!Address::CanHoldStoreOffsetThumb(kStoreSWord, offset)) {
2317    CHECK_NE(base, IP);
2318    LoadImmediate(IP, offset, cond);
2319    add(IP, IP, ShifterOperand(base), cond);
2320    base = IP;
2321    offset = 0;
2322  }
2323  CHECK(Address::CanHoldStoreOffsetThumb(kStoreSWord, offset));
2324  vstrs(reg, Address(base, offset), cond);
2325}
2326
2327
2328// Implementation note: this method must emit at most one instruction when
2329// Address::CanHoldStoreOffsetThumb, as expected by JIT::GuardedStoreSToOffset.
2330void Thumb2Assembler::StoreDToOffset(DRegister reg,
2331                                     Register base,
2332                                     int32_t offset,
2333                                     Condition cond) {
2334  if (!Address::CanHoldStoreOffsetThumb(kStoreDWord, offset)) {
2335    CHECK_NE(base, IP);
2336    LoadImmediate(IP, offset, cond);
2337    add(IP, IP, ShifterOperand(base), cond);
2338    base = IP;
2339    offset = 0;
2340  }
2341  CHECK(Address::CanHoldStoreOffsetThumb(kStoreDWord, offset));
2342  vstrd(reg, Address(base, offset), cond);
2343}
2344
2345
2346void Thumb2Assembler::MemoryBarrier(ManagedRegister mscratch) {
2347  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
2348#if ANDROID_SMP != 0
2349  int32_t encoding = 0xf3bf8f5f;  // dmb in T1 encoding.
2350  Emit32(encoding);
2351#endif
2352}
2353
2354
2355void Thumb2Assembler::CompareAndBranchIfZero(Register r, Label* label) {
2356  cbz(r, label);
2357}
2358
2359
2360void Thumb2Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
2361  cbnz(r, label);
2362}
2363}  // namespace arm
2364}  // namespace art
2365