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