assembler_arm.cc revision 1f359b08f5ad33ae72e4073b86a9257fe1ed11e5
1// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "src/assembler.h"
4#include "src/logging.h"
5
6namespace art {
7
8// Instruction encoding bits.
9enum {
10  H   = 1 << 5,   // halfword (or byte)
11  L   = 1 << 20,  // load (or store)
12  S   = 1 << 20,  // set condition code (or leave unchanged)
13  W   = 1 << 21,  // writeback base register (or leave unchanged)
14  A   = 1 << 21,  // accumulate in multiply instruction (or not)
15  B   = 1 << 22,  // unsigned byte (or word)
16  N   = 1 << 22,  // long (or short)
17  U   = 1 << 23,  // positive (or negative) offset/index
18  P   = 1 << 24,  // offset/pre-indexed addressing (or post-indexed addressing)
19  I   = 1 << 25,  // immediate shifter operand (or not)
20
21  B0 = 1,
22  B1 = 1 << 1,
23  B2 = 1 << 2,
24  B3 = 1 << 3,
25  B4 = 1 << 4,
26  B5 = 1 << 5,
27  B6 = 1 << 6,
28  B7 = 1 << 7,
29  B8 = 1 << 8,
30  B9 = 1 << 9,
31  B10 = 1 << 10,
32  B11 = 1 << 11,
33  B12 = 1 << 12,
34  B16 = 1 << 16,
35  B17 = 1 << 17,
36  B18 = 1 << 18,
37  B19 = 1 << 19,
38  B20 = 1 << 20,
39  B21 = 1 << 21,
40  B22 = 1 << 22,
41  B23 = 1 << 23,
42  B24 = 1 << 24,
43  B25 = 1 << 25,
44  B26 = 1 << 26,
45  B27 = 1 << 27,
46
47  // Instruction bit masks.
48  RdMask = 15 << 12,  // in str instruction
49  CondMask = 15 << 28,
50  CoprocessorMask = 15 << 8,
51  OpCodeMask = 15 << 21,  // in data-processing instructions
52  Imm24Mask = (1 << 24) - 1,
53  Off12Mask = (1 << 12) - 1,
54
55  // ldrex/strex register field encodings.
56  kLdExRnShift = 16,
57  kLdExRtShift = 12,
58  kStrExRnShift = 16,
59  kStrExRdShift = 12,
60  kStrExRtShift = 0,
61};
62
63
64static const char* kRegisterNames[] = {
65  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
66  "fp", "ip", "sp", "lr", "pc"
67};
68std::ostream& operator<<(std::ostream& os, const Register& rhs) {
69  if (rhs >= R0 && rhs <= PC) {
70    os << kRegisterNames[rhs];
71  } else {
72     os << "Register[" << int(rhs) << "]";
73  }
74  return os;
75}
76
77
78std::ostream& operator<<(std::ostream& os, const SRegister& rhs) {
79  if (rhs >= S0 && rhs < kNumberOfSRegisters) {
80    os << "s" << int(rhs);
81  } else {
82    os << "SRegister[" << int(rhs) << "]";
83  }
84  return os;
85}
86
87
88std::ostream& operator<<(std::ostream& os, const DRegister& rhs) {
89  if (rhs >= D0 && rhs < kNumberOfDRegisters) {
90    os << "d" << int(rhs);
91  } else {
92    os << "DRegister[" << int(rhs) << "]";
93  }
94  return os;
95}
96
97
98static const char* kConditionNames[] = {
99  "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL",
100};
101std::ostream& operator<<(std::ostream& os, const Condition& rhs) {
102  if (rhs >= EQ && rhs <= AL) {
103    os << kConditionNames[rhs];
104  } else {
105    os << "Condition[" << int(rhs) << "]";
106  }
107  return os;
108}
109
110
111void Assembler::Emit(int32_t value) {
112  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
113  buffer_.Emit<int32_t>(value);
114}
115
116
117void Assembler::EmitType01(Condition cond,
118                           int type,
119                           Opcode opcode,
120                           int set_cc,
121                           Register rn,
122                           Register rd,
123                           ShifterOperand so) {
124  CHECK_NE(rd, kNoRegister);
125  CHECK_NE(cond, kNoCondition);
126  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
127                     type << kTypeShift |
128                     static_cast<int32_t>(opcode) << kOpcodeShift |
129                     set_cc << kSShift |
130                     static_cast<int32_t>(rn) << kRnShift |
131                     static_cast<int32_t>(rd) << kRdShift |
132                     so.encoding();
133  Emit(encoding);
134}
135
136
137void Assembler::EmitType5(Condition cond, int offset, bool link) {
138  CHECK_NE(cond, kNoCondition);
139  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
140                     5 << kTypeShift |
141                     (link ? 1 : 0) << kLinkShift;
142  Emit(Assembler::EncodeBranchOffset(offset, encoding));
143}
144
145
146void Assembler::EmitMemOp(Condition cond,
147                          bool load,
148                          bool byte,
149                          Register rd,
150                          Address ad) {
151  CHECK_NE(rd, kNoRegister);
152  CHECK_NE(cond, kNoCondition);
153  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
154                     B26 |
155                     (load ? L : 0) |
156                     (byte ? B : 0) |
157                     (static_cast<int32_t>(rd) << kRdShift) |
158                     ad.encoding();
159  Emit(encoding);
160}
161
162
163void Assembler::EmitMemOpAddressMode3(Condition cond,
164                                      int32_t mode,
165                                      Register rd,
166                                      Address ad) {
167  CHECK_NE(rd, kNoRegister);
168  CHECK_NE(cond, kNoCondition);
169  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
170                     B22  |
171                     mode |
172                     (static_cast<int32_t>(rd) << kRdShift) |
173                     ad.encoding3();
174  Emit(encoding);
175}
176
177
178void Assembler::EmitMultiMemOp(Condition cond,
179                               BlockAddressMode am,
180                               bool load,
181                               Register base,
182                               RegList regs) {
183  CHECK_NE(base, kNoRegister);
184  CHECK_NE(cond, kNoCondition);
185  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
186                     B27 |
187                     am |
188                     (load ? L : 0) |
189                     (static_cast<int32_t>(base) << kRnShift) |
190                     regs;
191  Emit(encoding);
192}
193
194
195void Assembler::EmitShiftImmediate(Condition cond,
196                                   Shift opcode,
197                                   Register rd,
198                                   Register rm,
199                                   ShifterOperand so) {
200  CHECK_NE(cond, kNoCondition);
201  CHECK_EQ(so.type(), 1U);
202  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
203                     static_cast<int32_t>(MOV) << kOpcodeShift |
204                     static_cast<int32_t>(rd) << kRdShift |
205                     so.encoding() << kShiftImmShift |
206                     static_cast<int32_t>(opcode) << kShiftShift |
207                     static_cast<int32_t>(rm);
208  Emit(encoding);
209}
210
211
212void Assembler::EmitShiftRegister(Condition cond,
213                                  Shift opcode,
214                                  Register rd,
215                                  Register rm,
216                                  ShifterOperand so) {
217  CHECK_NE(cond, kNoCondition);
218  CHECK_EQ(so.type(), 0U);
219  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
220                     static_cast<int32_t>(MOV) << kOpcodeShift |
221                     static_cast<int32_t>(rd) << kRdShift |
222                     so.encoding() << kShiftRegisterShift |
223                     static_cast<int32_t>(opcode) << kShiftShift |
224                     B4 |
225                     static_cast<int32_t>(rm);
226  Emit(encoding);
227}
228
229
230void Assembler::EmitBranch(Condition cond, Label* label, bool link) {
231  if (label->IsBound()) {
232    EmitType5(cond, label->Position() - buffer_.Size(), link);
233  } else {
234    int position = buffer_.Size();
235    // Use the offset field of the branch instruction for linking the sites.
236    EmitType5(cond, label->position_, link);
237    label->LinkTo(position);
238  }
239}
240
241
242void Assembler::and_(Register rd, Register rn, ShifterOperand so,
243                     Condition cond) {
244  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
245}
246
247
248void Assembler::eor(Register rd, Register rn, ShifterOperand so,
249                    Condition cond) {
250  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
251}
252
253
254void Assembler::sub(Register rd, Register rn, ShifterOperand so,
255                    Condition cond) {
256  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
257}
258
259void Assembler::rsb(Register rd, Register rn, ShifterOperand so,
260                    Condition cond) {
261  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
262}
263
264void Assembler::rsbs(Register rd, Register rn, ShifterOperand so,
265                     Condition cond) {
266  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
267}
268
269
270void Assembler::add(Register rd, Register rn, ShifterOperand so,
271                    Condition cond) {
272  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
273}
274
275
276void Assembler::adds(Register rd, Register rn, ShifterOperand so,
277                     Condition cond) {
278  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
279}
280
281
282void Assembler::subs(Register rd, Register rn, ShifterOperand so,
283                     Condition cond) {
284  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
285}
286
287
288void Assembler::adc(Register rd, Register rn, ShifterOperand so,
289                    Condition cond) {
290  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
291}
292
293
294void Assembler::sbc(Register rd, Register rn, ShifterOperand so,
295                    Condition cond) {
296  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
297}
298
299
300void Assembler::rsc(Register rd, Register rn, ShifterOperand so,
301                    Condition cond) {
302  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
303}
304
305
306void Assembler::tst(Register rn, ShifterOperand so, Condition cond) {
307  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
308  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
309}
310
311
312void Assembler::teq(Register rn, ShifterOperand so, Condition cond) {
313  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
314  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
315}
316
317
318void Assembler::cmp(Register rn, ShifterOperand so, Condition cond) {
319  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
320}
321
322
323void Assembler::cmn(Register rn, ShifterOperand so, Condition cond) {
324  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
325}
326
327
328void Assembler::orr(Register rd, Register rn,
329                    ShifterOperand so, Condition cond) {
330  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
331}
332
333
334void Assembler::orrs(Register rd, Register rn,
335                     ShifterOperand so, Condition cond) {
336  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
337}
338
339
340void Assembler::mov(Register rd, ShifterOperand so, Condition cond) {
341  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
342}
343
344
345void Assembler::movs(Register rd, ShifterOperand so, Condition cond) {
346  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
347}
348
349
350void Assembler::bic(Register rd, Register rn, ShifterOperand so,
351                    Condition cond) {
352  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
353}
354
355
356void Assembler::mvn(Register rd, ShifterOperand so, Condition cond) {
357  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
358}
359
360
361void Assembler::mvns(Register rd, ShifterOperand so, Condition cond) {
362  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
363}
364
365
366void Assembler::clz(Register rd, Register rm, Condition cond) {
367  CHECK_NE(rd, kNoRegister);
368  CHECK_NE(rm, kNoRegister);
369  CHECK_NE(cond, kNoCondition);
370  CHECK_NE(rd, PC);
371  CHECK_NE(rm, PC);
372  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
373                     B24 | B22 | B21 | (0xf << 16) |
374                     (static_cast<int32_t>(rd) << kRdShift) |
375                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
376  Emit(encoding);
377}
378
379
380void Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
381  CHECK_NE(cond, kNoCondition);
382  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
383                     B25 | B24 | ((imm16 >> 12) << 16) |
384                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
385  Emit(encoding);
386}
387
388
389void Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
390  CHECK_NE(cond, kNoCondition);
391  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
392                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
393                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
394  Emit(encoding);
395}
396
397
398void Assembler::EmitMulOp(Condition cond, int32_t opcode,
399                          Register rd, Register rn,
400                          Register rm, Register rs) {
401  CHECK_NE(rd, kNoRegister);
402  CHECK_NE(rn, kNoRegister);
403  CHECK_NE(rm, kNoRegister);
404  CHECK_NE(rs, kNoRegister);
405  CHECK_NE(cond, kNoCondition);
406  int32_t encoding = opcode |
407      (static_cast<int32_t>(cond) << kConditionShift) |
408      (static_cast<int32_t>(rn) << kRnShift) |
409      (static_cast<int32_t>(rd) << kRdShift) |
410      (static_cast<int32_t>(rs) << kRsShift) |
411      B7 | B4 |
412      (static_cast<int32_t>(rm) << kRmShift);
413  Emit(encoding);
414}
415
416
417void Assembler::mul(Register rd, Register rn,
418                    Register rm, Condition cond) {
419  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
420  EmitMulOp(cond, 0, R0, rd, rn, rm);
421}
422
423
424void Assembler::mla(Register rd, Register rn,
425                    Register rm, Register ra, Condition cond) {
426  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
427  EmitMulOp(cond, B21, ra, rd, rn, rm);
428}
429
430
431void Assembler::mls(Register rd, Register rn,
432                    Register rm, Register ra, Condition cond) {
433  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
434  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
435}
436
437
438void Assembler::umull(Register rd_lo, Register rd_hi,
439                      Register rn, Register rm, Condition cond) {
440  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
441  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
442}
443
444
445void Assembler::ldr(Register rd, Address ad, Condition cond) {
446  EmitMemOp(cond, true, false, rd, ad);
447}
448
449
450void Assembler::str(Register rd, Address ad, Condition cond) {
451  EmitMemOp(cond, false, false, rd, ad);
452}
453
454
455void Assembler::ldrb(Register rd, Address ad, Condition cond) {
456  EmitMemOp(cond, true, true, rd, ad);
457}
458
459
460void Assembler::strb(Register rd, Address ad, Condition cond) {
461  EmitMemOp(cond, false, true, rd, ad);
462}
463
464
465void Assembler::ldrh(Register rd, Address ad, Condition cond) {
466  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
467}
468
469
470void Assembler::strh(Register rd, Address ad, Condition cond) {
471  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
472}
473
474
475void Assembler::ldrsb(Register rd, Address ad, Condition cond) {
476  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
477}
478
479
480void Assembler::ldrsh(Register rd, Address ad, Condition cond) {
481  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
482}
483
484
485void Assembler::ldrd(Register rd, Address ad, Condition cond) {
486  CHECK_EQ(rd % 2, 0);
487  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
488}
489
490
491void Assembler::strd(Register rd, Address ad, Condition cond) {
492  CHECK_EQ(rd % 2, 0);
493  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
494}
495
496
497void Assembler::ldm(BlockAddressMode am,
498                    Register base,
499                    RegList regs,
500                    Condition cond) {
501  EmitMultiMemOp(cond, am, true, base, regs);
502}
503
504
505void Assembler::stm(BlockAddressMode am,
506                    Register base,
507                    RegList regs,
508                    Condition cond) {
509  EmitMultiMemOp(cond, am, false, base, regs);
510}
511
512
513void Assembler::ldrex(Register rt, Register rn, Condition cond) {
514  CHECK_NE(rn, kNoRegister);
515  CHECK_NE(rt, kNoRegister);
516  CHECK_NE(cond, kNoCondition);
517  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
518                     B24 |
519                     B23 |
520                     L   |
521                     (static_cast<int32_t>(rn) << kLdExRnShift) |
522                     (static_cast<int32_t>(rt) << kLdExRtShift) |
523                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
524  Emit(encoding);
525}
526
527
528void Assembler::strex(Register rd,
529                      Register rt,
530                      Register rn,
531                      Condition cond) {
532  CHECK_NE(rn, kNoRegister);
533  CHECK_NE(rd, kNoRegister);
534  CHECK_NE(rt, kNoRegister);
535  CHECK_NE(cond, kNoCondition);
536  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
537                     B24 |
538                     B23 |
539                     (static_cast<int32_t>(rn) << kStrExRnShift) |
540                     (static_cast<int32_t>(rd) << kStrExRdShift) |
541                     B11 | B10 | B9 | B8 | B7 | B4 |
542                     (static_cast<int32_t>(rt) << kStrExRtShift);
543  Emit(encoding);
544}
545
546
547void Assembler::clrex() {
548  int32_t encoding = (kSpecialCondition << kConditionShift) |
549                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
550  Emit(encoding);
551}
552
553
554void Assembler::nop(Condition cond) {
555  CHECK_NE(cond, kNoCondition);
556  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
557                     B25 | B24 | B21 | (0xf << 12);
558  Emit(encoding);
559}
560
561
562void Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
563  CHECK_NE(sn, kNoSRegister);
564  CHECK_NE(rt, kNoRegister);
565  CHECK_NE(rt, SP);
566  CHECK_NE(rt, PC);
567  CHECK_NE(cond, kNoCondition);
568  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
569                     B27 | B26 | B25 |
570                     ((static_cast<int32_t>(sn) >> 1)*B16) |
571                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
572                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
573  Emit(encoding);
574}
575
576
577void Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
578  CHECK_NE(sn, kNoSRegister);
579  CHECK_NE(rt, kNoRegister);
580  CHECK_NE(rt, SP);
581  CHECK_NE(rt, PC);
582  CHECK_NE(cond, kNoCondition);
583  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
584                     B27 | B26 | B25 | B20 |
585                     ((static_cast<int32_t>(sn) >> 1)*B16) |
586                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
587                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
588  Emit(encoding);
589}
590
591
592void Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
593                        Condition cond) {
594  CHECK_NE(sm, kNoSRegister);
595  CHECK_NE(sm, S31);
596  CHECK_NE(rt, kNoRegister);
597  CHECK_NE(rt, SP);
598  CHECK_NE(rt, PC);
599  CHECK_NE(rt2, kNoRegister);
600  CHECK_NE(rt2, SP);
601  CHECK_NE(rt2, PC);
602  CHECK_NE(cond, kNoCondition);
603  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
604                     B27 | B26 | B22 |
605                     (static_cast<int32_t>(rt2)*B16) |
606                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
607                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
608                     (static_cast<int32_t>(sm) >> 1);
609  Emit(encoding);
610}
611
612
613void Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
614                        Condition cond) {
615  CHECK_NE(sm, kNoSRegister);
616  CHECK_NE(sm, S31);
617  CHECK_NE(rt, kNoRegister);
618  CHECK_NE(rt, SP);
619  CHECK_NE(rt, PC);
620  CHECK_NE(rt2, kNoRegister);
621  CHECK_NE(rt2, SP);
622  CHECK_NE(rt2, PC);
623  CHECK_NE(rt, rt2);
624  CHECK_NE(cond, kNoCondition);
625  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
626                     B27 | B26 | B22 | B20 |
627                     (static_cast<int32_t>(rt2)*B16) |
628                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
629                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
630                     (static_cast<int32_t>(sm) >> 1);
631  Emit(encoding);
632}
633
634
635void Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
636                        Condition cond) {
637  CHECK_NE(dm, kNoDRegister);
638  CHECK_NE(rt, kNoRegister);
639  CHECK_NE(rt, SP);
640  CHECK_NE(rt, PC);
641  CHECK_NE(rt2, kNoRegister);
642  CHECK_NE(rt2, SP);
643  CHECK_NE(rt2, PC);
644  CHECK_NE(cond, kNoCondition);
645  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
646                     B27 | B26 | B22 |
647                     (static_cast<int32_t>(rt2)*B16) |
648                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
649                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
650                     (static_cast<int32_t>(dm) & 0xf);
651  Emit(encoding);
652}
653
654
655void Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
656                              Condition cond) {
657  CHECK_NE(dm, kNoDRegister);
658  CHECK_NE(rt, kNoRegister);
659  CHECK_NE(rt, SP);
660  CHECK_NE(rt, PC);
661  CHECK_NE(rt2, kNoRegister);
662  CHECK_NE(rt2, SP);
663  CHECK_NE(rt2, PC);
664  CHECK_NE(rt, rt2);
665  CHECK_NE(cond, kNoCondition);
666  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
667                     B27 | B26 | B22 | B20 |
668                     (static_cast<int32_t>(rt2)*B16) |
669                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
670                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
671                     (static_cast<int32_t>(dm) & 0xf);
672  Emit(encoding);
673}
674
675
676void Assembler::vldrs(SRegister sd, Address ad, Condition cond) {
677  CHECK_NE(sd, kNoSRegister);
678  CHECK_NE(cond, kNoCondition);
679  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
680                     B27 | B26 | B24 | B20 |
681                     ((static_cast<int32_t>(sd) & 1)*B22) |
682                     ((static_cast<int32_t>(sd) >> 1)*B12) |
683                     B11 | B9 | ad.vencoding();
684  Emit(encoding);
685}
686
687
688void Assembler::vstrs(SRegister sd, Address ad, Condition cond) {
689  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
690  CHECK_NE(sd, kNoSRegister);
691  CHECK_NE(cond, kNoCondition);
692  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
693                     B27 | B26 | B24 |
694                     ((static_cast<int32_t>(sd) & 1)*B22) |
695                     ((static_cast<int32_t>(sd) >> 1)*B12) |
696                     B11 | B9 | ad.vencoding();
697  Emit(encoding);
698}
699
700
701void Assembler::vldrd(DRegister dd, Address ad, Condition cond) {
702  CHECK_NE(dd, kNoDRegister);
703  CHECK_NE(cond, kNoCondition);
704  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
705                     B27 | B26 | B24 | B20 |
706                     ((static_cast<int32_t>(dd) >> 4)*B22) |
707                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
708                     B11 | B9 | B8 | ad.vencoding();
709  Emit(encoding);
710}
711
712
713void Assembler::vstrd(DRegister dd, Address ad, Condition cond) {
714  CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC);
715  CHECK_NE(dd, kNoDRegister);
716  CHECK_NE(cond, kNoCondition);
717  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
718                     B27 | B26 | B24 |
719                     ((static_cast<int32_t>(dd) >> 4)*B22) |
720                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
721                     B11 | B9 | B8 | ad.vencoding();
722  Emit(encoding);
723}
724
725
726void Assembler::EmitVFPsss(Condition cond, int32_t opcode,
727                           SRegister sd, SRegister sn, SRegister sm) {
728  CHECK_NE(sd, kNoSRegister);
729  CHECK_NE(sn, kNoSRegister);
730  CHECK_NE(sm, kNoSRegister);
731  CHECK_NE(cond, kNoCondition);
732  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
733                     B27 | B26 | B25 | B11 | B9 | opcode |
734                     ((static_cast<int32_t>(sd) & 1)*B22) |
735                     ((static_cast<int32_t>(sn) >> 1)*B16) |
736                     ((static_cast<int32_t>(sd) >> 1)*B12) |
737                     ((static_cast<int32_t>(sn) & 1)*B7) |
738                     ((static_cast<int32_t>(sm) & 1)*B5) |
739                     (static_cast<int32_t>(sm) >> 1);
740  Emit(encoding);
741}
742
743
744void Assembler::EmitVFPddd(Condition cond, int32_t opcode,
745                           DRegister dd, DRegister dn, DRegister dm) {
746  CHECK_NE(dd, kNoDRegister);
747  CHECK_NE(dn, kNoDRegister);
748  CHECK_NE(dm, kNoDRegister);
749  CHECK_NE(cond, kNoCondition);
750  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
751                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
752                     ((static_cast<int32_t>(dd) >> 4)*B22) |
753                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
754                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
755                     ((static_cast<int32_t>(dn) >> 4)*B7) |
756                     ((static_cast<int32_t>(dm) >> 4)*B5) |
757                     (static_cast<int32_t>(dm) & 0xf);
758  Emit(encoding);
759}
760
761
762void Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
763  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
764}
765
766
767void Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
768  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
769}
770
771
772bool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
773  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
774  if (((imm32 & ((1 << 19) - 1)) == 0) &&
775      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
776       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
777    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
778        ((imm32 >> 19) & ((1 << 6) -1));
779    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
780               sd, S0, S0);
781    return true;
782  }
783  return false;
784}
785
786
787bool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
788  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
789  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
790      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
791       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
792    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
793        ((imm64 >> 48) & ((1 << 6) -1));
794    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
795               dd, D0, D0);
796    return true;
797  }
798  return false;
799}
800
801
802void Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
803                      Condition cond) {
804  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
805}
806
807
808void Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
809                      Condition cond) {
810  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
811}
812
813
814void Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
815                      Condition cond) {
816  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
817}
818
819
820void Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
821                      Condition cond) {
822  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
823}
824
825
826void Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
827                      Condition cond) {
828  EmitVFPsss(cond, B21, sd, sn, sm);
829}
830
831
832void Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
833                      Condition cond) {
834  EmitVFPddd(cond, B21, dd, dn, dm);
835}
836
837
838void Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
839                      Condition cond) {
840  EmitVFPsss(cond, 0, sd, sn, sm);
841}
842
843
844void Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
845                      Condition cond) {
846  EmitVFPddd(cond, 0, dd, dn, dm);
847}
848
849
850void Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
851                      Condition cond) {
852  EmitVFPsss(cond, B6, sd, sn, sm);
853}
854
855
856void Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
857                      Condition cond) {
858  EmitVFPddd(cond, B6, dd, dn, dm);
859}
860
861
862void Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
863                      Condition cond) {
864  EmitVFPsss(cond, B23, sd, sn, sm);
865}
866
867
868void Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
869                      Condition cond) {
870  EmitVFPddd(cond, B23, dd, dn, dm);
871}
872
873
874void Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
875  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
876}
877
878
879void Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
880  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
881}
882
883
884void Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
885  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
886}
887
888
889void Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
890  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
891}
892
893
894void Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
895  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
896}
897
898void Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
899  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
900}
901
902
903void Assembler::EmitVFPsd(Condition cond, int32_t opcode,
904                          SRegister sd, DRegister dm) {
905  CHECK_NE(sd, kNoSRegister);
906  CHECK_NE(dm, kNoDRegister);
907  CHECK_NE(cond, kNoCondition);
908  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
909                     B27 | B26 | B25 | B11 | B9 | opcode |
910                     ((static_cast<int32_t>(sd) & 1)*B22) |
911                     ((static_cast<int32_t>(sd) >> 1)*B12) |
912                     ((static_cast<int32_t>(dm) >> 4)*B5) |
913                     (static_cast<int32_t>(dm) & 0xf);
914  Emit(encoding);
915}
916
917
918void Assembler::EmitVFPds(Condition cond, int32_t opcode,
919                          DRegister dd, SRegister sm) {
920  CHECK_NE(dd, kNoDRegister);
921  CHECK_NE(sm, kNoSRegister);
922  CHECK_NE(cond, kNoCondition);
923  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
924                     B27 | B26 | B25 | B11 | B9 | opcode |
925                     ((static_cast<int32_t>(dd) >> 4)*B22) |
926                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
927                     ((static_cast<int32_t>(sm) & 1)*B5) |
928                     (static_cast<int32_t>(sm) >> 1);
929  Emit(encoding);
930}
931
932
933void Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
934  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
935}
936
937
938void Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
939  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
940}
941
942
943void Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
944  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
945}
946
947
948void Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
949  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
950}
951
952
953void Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
954  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
955}
956
957
958void Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
959  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
960}
961
962
963void Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
964  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
965}
966
967
968void Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
969  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
970}
971
972
973void Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
974  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
975}
976
977
978void Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
979  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
980}
981
982
983void Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
984  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
985}
986
987
988void Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
989  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
990}
991
992
993void Assembler::vcmpsz(SRegister sd, Condition cond) {
994  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
995}
996
997
998void Assembler::vcmpdz(DRegister dd, Condition cond) {
999  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
1000}
1001
1002
1003void Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
1004  CHECK_NE(cond, kNoCondition);
1005  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1006                     B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1007                     (static_cast<int32_t>(PC)*B12) |
1008                     B11 | B9 | B4;
1009  Emit(encoding);
1010}
1011
1012
1013void Assembler::svc(uint32_t imm24) {
1014  CHECK(IsUint(24, imm24));
1015  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1016  Emit(encoding);
1017}
1018
1019
1020void Assembler::bkpt(uint16_t imm16) {
1021  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1022                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1023  Emit(encoding);
1024}
1025
1026
1027void Assembler::b(Label* label, Condition cond) {
1028  EmitBranch(cond, label, false);
1029}
1030
1031
1032void Assembler::bl(Label* label, Condition cond) {
1033  EmitBranch(cond, label, true);
1034}
1035
1036
1037void Assembler::blx(Register rm, Condition cond) {
1038  CHECK_NE(rm, kNoRegister);
1039  CHECK_NE(cond, kNoCondition);
1040  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1041                     B24 | B21 | (0xfff << 8) | B5 | B4 |
1042                     (static_cast<int32_t>(rm) << kRmShift);
1043  Emit(encoding);
1044}
1045
1046
1047void Assembler::MarkExceptionHandler(Label* label) {
1048  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
1049  Label l;
1050  b(&l);
1051  EmitBranch(AL, label, false);
1052  Bind(&l);
1053}
1054
1055
1056void Assembler::Bind(Label* label) {
1057  CHECK(!label->IsBound());
1058  int bound_pc = buffer_.Size();
1059  while (label->IsLinked()) {
1060    int32_t position = label->Position();
1061    int32_t next = buffer_.Load<int32_t>(position);
1062    int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next);
1063    buffer_.Store<int32_t>(position, encoded);
1064    label->position_ = Assembler::DecodeBranchOffset(next);
1065  }
1066  label->BindTo(bound_pc);
1067}
1068
1069
1070void Assembler::EncodeUint32InTstInstructions(uint32_t data) {
1071  // TODO: Consider using movw ip, <16 bits>.
1072  while (!IsUint(8, data)) {
1073    tst(R0, ShifterOperand(data & 0xFF), VS);
1074    data >>= 8;
1075  }
1076  tst(R0, ShifterOperand(data), MI);
1077}
1078
1079int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) {
1080  // The offset is off by 8 due to the way the ARM CPUs read PC.
1081  offset -= 8;
1082  CHECK(IsAligned(offset, 4));
1083  CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset));
1084
1085  // Properly preserve only the bits supported in the instruction.
1086  offset >>= 2;
1087  offset &= kBranchOffsetMask;
1088  return (inst & ~kBranchOffsetMask) | offset;
1089}
1090
1091
1092int Assembler::DecodeBranchOffset(int32_t inst) {
1093  // Sign-extend, left-shift by 2, then add 8.
1094  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1095}
1096
1097}  // namespace art
1098