assembler_arm32.cc revision 2c4257be8191c5eefde744e8965fcefc80a0a97d
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_arm32.h"
18
19#include "base/logging.h"
20#include "entrypoints/quick/quick_entrypoints.h"
21#include "offsets.h"
22#include "thread.h"
23#include "utils.h"
24
25namespace art {
26namespace arm {
27
28void Arm32Assembler::and_(Register rd, Register rn, const ShifterOperand& so,
29                        Condition cond) {
30  EmitType01(cond, so.type(), AND, 0, rn, rd, so);
31}
32
33
34void Arm32Assembler::eor(Register rd, Register rn, const ShifterOperand& so,
35                       Condition cond) {
36  EmitType01(cond, so.type(), EOR, 0, rn, rd, so);
37}
38
39
40void Arm32Assembler::sub(Register rd, Register rn, const ShifterOperand& so,
41                       Condition cond) {
42  EmitType01(cond, so.type(), SUB, 0, rn, rd, so);
43}
44
45void Arm32Assembler::rsb(Register rd, Register rn, const ShifterOperand& so,
46                       Condition cond) {
47  EmitType01(cond, so.type(), RSB, 0, rn, rd, so);
48}
49
50void Arm32Assembler::rsbs(Register rd, Register rn, const ShifterOperand& so,
51                        Condition cond) {
52  EmitType01(cond, so.type(), RSB, 1, rn, rd, so);
53}
54
55
56void Arm32Assembler::add(Register rd, Register rn, const ShifterOperand& so,
57                       Condition cond) {
58  EmitType01(cond, so.type(), ADD, 0, rn, rd, so);
59}
60
61
62void Arm32Assembler::adds(Register rd, Register rn, const ShifterOperand& so,
63                        Condition cond) {
64  EmitType01(cond, so.type(), ADD, 1, rn, rd, so);
65}
66
67
68void Arm32Assembler::subs(Register rd, Register rn, const ShifterOperand& so,
69                        Condition cond) {
70  EmitType01(cond, so.type(), SUB, 1, rn, rd, so);
71}
72
73
74void Arm32Assembler::adc(Register rd, Register rn, const ShifterOperand& so,
75                       Condition cond) {
76  EmitType01(cond, so.type(), ADC, 0, rn, rd, so);
77}
78
79
80void Arm32Assembler::sbc(Register rd, Register rn, const ShifterOperand& so,
81                       Condition cond) {
82  EmitType01(cond, so.type(), SBC, 0, rn, rd, so);
83}
84
85
86void Arm32Assembler::rsc(Register rd, Register rn, const ShifterOperand& so,
87                       Condition cond) {
88  EmitType01(cond, so.type(), RSC, 0, rn, rd, so);
89}
90
91
92void Arm32Assembler::tst(Register rn, const ShifterOperand& so, Condition cond) {
93  CHECK_NE(rn, PC);  // Reserve tst pc instruction for exception handler marker.
94  EmitType01(cond, so.type(), TST, 1, rn, R0, so);
95}
96
97
98void Arm32Assembler::teq(Register rn, const ShifterOperand& so, Condition cond) {
99  CHECK_NE(rn, PC);  // Reserve teq pc instruction for exception handler marker.
100  EmitType01(cond, so.type(), TEQ, 1, rn, R0, so);
101}
102
103
104void Arm32Assembler::cmp(Register rn, const ShifterOperand& so, Condition cond) {
105  EmitType01(cond, so.type(), CMP, 1, rn, R0, so);
106}
107
108
109void Arm32Assembler::cmn(Register rn, const ShifterOperand& so, Condition cond) {
110  EmitType01(cond, so.type(), CMN, 1, rn, R0, so);
111}
112
113
114void Arm32Assembler::orr(Register rd, Register rn,
115                    const ShifterOperand& so, Condition cond) {
116  EmitType01(cond, so.type(), ORR, 0, rn, rd, so);
117}
118
119
120void Arm32Assembler::orrs(Register rd, Register rn,
121                        const ShifterOperand& so, Condition cond) {
122  EmitType01(cond, so.type(), ORR, 1, rn, rd, so);
123}
124
125
126void Arm32Assembler::mov(Register rd, const ShifterOperand& so, Condition cond) {
127  EmitType01(cond, so.type(), MOV, 0, R0, rd, so);
128}
129
130
131void Arm32Assembler::movs(Register rd, const ShifterOperand& so, Condition cond) {
132  EmitType01(cond, so.type(), MOV, 1, R0, rd, so);
133}
134
135
136void Arm32Assembler::bic(Register rd, Register rn, const ShifterOperand& so,
137                       Condition cond) {
138  EmitType01(cond, so.type(), BIC, 0, rn, rd, so);
139}
140
141
142void Arm32Assembler::mvn(Register rd, const ShifterOperand& so, Condition cond) {
143  EmitType01(cond, so.type(), MVN, 0, R0, rd, so);
144}
145
146
147void Arm32Assembler::mvns(Register rd, const ShifterOperand& so, Condition cond) {
148  EmitType01(cond, so.type(), MVN, 1, R0, rd, so);
149}
150
151
152void Arm32Assembler::mul(Register rd, Register rn, Register rm, Condition cond) {
153  // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
154  EmitMulOp(cond, 0, R0, rd, rn, rm);
155}
156
157
158void Arm32Assembler::mla(Register rd, Register rn, Register rm, Register ra,
159                         Condition cond) {
160  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
161  EmitMulOp(cond, B21, ra, rd, rn, rm);
162}
163
164
165void Arm32Assembler::mls(Register rd, Register rn, Register rm, Register ra,
166                         Condition cond) {
167  // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
168  EmitMulOp(cond, B22 | B21, ra, rd, rn, rm);
169}
170
171
172void Arm32Assembler::umull(Register rd_lo, Register rd_hi, Register rn,
173                           Register rm, Condition cond) {
174  // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs.
175  EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm);
176}
177
178
179void Arm32Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) {
180  CHECK_NE(rd, kNoRegister);
181  CHECK_NE(rn, kNoRegister);
182  CHECK_NE(rm, kNoRegister);
183  CHECK_NE(cond, kNoCondition);
184  int32_t encoding = B26 | B25 | B24 | B20 |
185      B15 | B14 | B13 | B12 |
186      (static_cast<int32_t>(cond) << kConditionShift) |
187      (static_cast<int32_t>(rn) << 0) |
188      (static_cast<int32_t>(rd) << 16) |
189      (static_cast<int32_t>(rm) << 8) |
190      B4;
191  Emit(encoding);
192}
193
194
195void Arm32Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) {
196  CHECK_NE(rd, kNoRegister);
197  CHECK_NE(rn, kNoRegister);
198  CHECK_NE(rm, kNoRegister);
199  CHECK_NE(cond, kNoCondition);
200  int32_t encoding = B26 | B25 | B24 | B21 | B20 |
201      B15 | B14 | B13 | B12 |
202      (static_cast<int32_t>(cond) << kConditionShift) |
203      (static_cast<int32_t>(rn) << 0) |
204      (static_cast<int32_t>(rd) << 16) |
205      (static_cast<int32_t>(rm) << 8) |
206      B4;
207  Emit(encoding);
208}
209
210
211void Arm32Assembler::ldr(Register rd, const Address& ad, Condition cond) {
212  EmitMemOp(cond, true, false, rd, ad);
213}
214
215
216void Arm32Assembler::str(Register rd, const Address& ad, Condition cond) {
217  EmitMemOp(cond, false, false, rd, ad);
218}
219
220
221void Arm32Assembler::ldrb(Register rd, const Address& ad, Condition cond) {
222  EmitMemOp(cond, true, true, rd, ad);
223}
224
225
226void Arm32Assembler::strb(Register rd, const Address& ad, Condition cond) {
227  EmitMemOp(cond, false, true, rd, ad);
228}
229
230
231void Arm32Assembler::ldrh(Register rd, const Address& ad, Condition cond) {
232  EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad);
233}
234
235
236void Arm32Assembler::strh(Register rd, const Address& ad, Condition cond) {
237  EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad);
238}
239
240
241void Arm32Assembler::ldrsb(Register rd, const Address& ad, Condition cond) {
242  EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad);
243}
244
245
246void Arm32Assembler::ldrsh(Register rd, const Address& ad, Condition cond) {
247  EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad);
248}
249
250
251void Arm32Assembler::ldrd(Register rd, const Address& ad, Condition cond) {
252  CHECK_EQ(rd % 2, 0);
253  EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad);
254}
255
256
257void Arm32Assembler::strd(Register rd, const Address& ad, Condition cond) {
258  CHECK_EQ(rd % 2, 0);
259  EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad);
260}
261
262
263void Arm32Assembler::ldm(BlockAddressMode am,
264                       Register base,
265                       RegList regs,
266                       Condition cond) {
267  EmitMultiMemOp(cond, am, true, base, regs);
268}
269
270
271void Arm32Assembler::stm(BlockAddressMode am,
272                       Register base,
273                       RegList regs,
274                       Condition cond) {
275  EmitMultiMemOp(cond, am, false, base, regs);
276}
277
278
279void Arm32Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) {
280  EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm);
281}
282
283
284void Arm32Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) {
285  EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm);
286}
287
288
289bool Arm32Assembler::vmovs(SRegister sd, float s_imm, Condition cond) {
290  uint32_t imm32 = bit_cast<uint32_t, float>(s_imm);
291  if (((imm32 & ((1 << 19) - 1)) == 0) &&
292      ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) ||
293       (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) {
294    uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) |
295        ((imm32 >> 19) & ((1 << 6) -1));
296    EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf),
297               sd, S0, S0);
298    return true;
299  }
300  return false;
301}
302
303
304bool Arm32Assembler::vmovd(DRegister dd, double d_imm, Condition cond) {
305  uint64_t imm64 = bit_cast<uint64_t, double>(d_imm);
306  if (((imm64 & ((1LL << 48) - 1)) == 0) &&
307      ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) ||
308       (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) {
309    uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) |
310        ((imm64 >> 48) & ((1 << 6) -1));
311    EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf),
312               dd, D0, D0);
313    return true;
314  }
315  return false;
316}
317
318
319void Arm32Assembler::vadds(SRegister sd, SRegister sn, SRegister sm,
320                           Condition cond) {
321  EmitVFPsss(cond, B21 | B20, sd, sn, sm);
322}
323
324
325void Arm32Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm,
326                           Condition cond) {
327  EmitVFPddd(cond, B21 | B20, dd, dn, dm);
328}
329
330
331void Arm32Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm,
332                           Condition cond) {
333  EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm);
334}
335
336
337void Arm32Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm,
338                           Condition cond) {
339  EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm);
340}
341
342
343void Arm32Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm,
344                           Condition cond) {
345  EmitVFPsss(cond, B21, sd, sn, sm);
346}
347
348
349void Arm32Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm,
350                           Condition cond) {
351  EmitVFPddd(cond, B21, dd, dn, dm);
352}
353
354
355void Arm32Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm,
356                           Condition cond) {
357  EmitVFPsss(cond, 0, sd, sn, sm);
358}
359
360
361void Arm32Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm,
362                           Condition cond) {
363  EmitVFPddd(cond, 0, dd, dn, dm);
364}
365
366
367void Arm32Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm,
368                           Condition cond) {
369  EmitVFPsss(cond, B6, sd, sn, sm);
370}
371
372
373void Arm32Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm,
374                           Condition cond) {
375  EmitVFPddd(cond, B6, dd, dn, dm);
376}
377
378
379void Arm32Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm,
380                           Condition cond) {
381  EmitVFPsss(cond, B23, sd, sn, sm);
382}
383
384
385void Arm32Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm,
386                           Condition cond) {
387  EmitVFPddd(cond, B23, dd, dn, dm);
388}
389
390
391void Arm32Assembler::vabss(SRegister sd, SRegister sm, Condition cond) {
392  EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm);
393}
394
395
396void Arm32Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) {
397  EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm);
398}
399
400
401void Arm32Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) {
402  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm);
403}
404
405
406void Arm32Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) {
407  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm);
408}
409
410
411void Arm32Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) {
412  EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm);
413}
414
415void Arm32Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) {
416  EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm);
417}
418
419
420void Arm32Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) {
421  EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm);
422}
423
424
425void Arm32Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) {
426  EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm);
427}
428
429
430void Arm32Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) {
431  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm);
432}
433
434
435void Arm32Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) {
436  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm);
437}
438
439
440void Arm32Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) {
441  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm);
442}
443
444
445void Arm32Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) {
446  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm);
447}
448
449
450void Arm32Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) {
451  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm);
452}
453
454
455void Arm32Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) {
456  EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm);
457}
458
459
460void Arm32Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) {
461  EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm);
462}
463
464
465void Arm32Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) {
466  EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm);
467}
468
469
470void Arm32Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) {
471  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm);
472}
473
474
475void Arm32Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) {
476  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm);
477}
478
479
480void Arm32Assembler::vcmpsz(SRegister sd, Condition cond) {
481  EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0);
482}
483
484
485void Arm32Assembler::vcmpdz(DRegister dd, Condition cond) {
486  EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0);
487}
488
489void Arm32Assembler::b(Label* label, Condition cond) {
490  EmitBranch(cond, label, false);
491}
492
493
494void Arm32Assembler::bl(Label* label, Condition cond) {
495  EmitBranch(cond, label, true);
496}
497
498
499void Arm32Assembler::MarkExceptionHandler(Label* label) {
500  EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
501  Label l;
502  b(&l);
503  EmitBranch(AL, label, false);
504  Bind(&l);
505}
506
507
508void Arm32Assembler::Emit(int32_t value) {
509  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
510  buffer_.Emit<int32_t>(value);
511}
512
513
514void Arm32Assembler::EmitType01(Condition cond,
515                                int type,
516                                Opcode opcode,
517                                int set_cc,
518                                Register rn,
519                                Register rd,
520                                const ShifterOperand& so) {
521  CHECK_NE(rd, kNoRegister);
522  CHECK_NE(cond, kNoCondition);
523  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
524                     type << kTypeShift |
525                     static_cast<int32_t>(opcode) << kOpcodeShift |
526                     set_cc << kSShift |
527                     static_cast<int32_t>(rn) << kRnShift |
528                     static_cast<int32_t>(rd) << kRdShift |
529                     so.encodingArm();
530  Emit(encoding);
531}
532
533
534void Arm32Assembler::EmitType5(Condition cond, int offset, bool link) {
535  CHECK_NE(cond, kNoCondition);
536  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
537                     5 << kTypeShift |
538                     (link ? 1 : 0) << kLinkShift;
539  Emit(Arm32Assembler::EncodeBranchOffset(offset, encoding));
540}
541
542
543void Arm32Assembler::EmitMemOp(Condition cond,
544                               bool load,
545                               bool byte,
546                               Register rd,
547                               const Address& ad) {
548  CHECK_NE(rd, kNoRegister);
549  CHECK_NE(cond, kNoCondition);
550  const Address& addr = static_cast<const Address&>(ad);
551
552  int32_t encoding = 0;
553  if (!ad.IsImmediate() && ad.GetRegisterOffset() == PC) {
554    // PC relative LDR(literal)
555    int32_t offset = ad.GetOffset();
556    int32_t u = B23;
557    if (offset < 0) {
558      offset = -offset;
559      u = 0;
560    }
561    CHECK_LT(offset, (1 << 12));
562    encoding = (static_cast<int32_t>(cond) << kConditionShift) |
563         B26 | B24 | u | B20 |
564         (load ? L : 0) |
565         (byte ? B : 0) |
566         (static_cast<int32_t>(rd) << kRdShift) |
567         0xf << 16 |
568         (offset & 0xfff);
569
570  } else {
571    encoding = (static_cast<int32_t>(cond) << kConditionShift) |
572        B26 |
573        (load ? L : 0) |
574        (byte ? B : 0) |
575        (static_cast<int32_t>(rd) << kRdShift) |
576        addr.encodingArm();
577  }
578  Emit(encoding);
579}
580
581
582void Arm32Assembler::EmitMemOpAddressMode3(Condition cond,
583                                           int32_t mode,
584                                           Register rd,
585                                           const Address& ad) {
586  CHECK_NE(rd, kNoRegister);
587  CHECK_NE(cond, kNoCondition);
588  const Address& addr = static_cast<const Address&>(ad);
589  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
590                     B22  |
591                     mode |
592                     (static_cast<int32_t>(rd) << kRdShift) |
593                     addr.encoding3();
594  Emit(encoding);
595}
596
597
598void Arm32Assembler::EmitMultiMemOp(Condition cond,
599                                    BlockAddressMode am,
600                                    bool load,
601                                    Register base,
602                                    RegList regs) {
603  CHECK_NE(base, kNoRegister);
604  CHECK_NE(cond, kNoCondition);
605  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
606                     B27 |
607                     am |
608                     (load ? L : 0) |
609                     (static_cast<int32_t>(base) << kRnShift) |
610                     regs;
611  Emit(encoding);
612}
613
614
615void Arm32Assembler::EmitShiftImmediate(Condition cond,
616                                        Shift opcode,
617                                        Register rd,
618                                        Register rm,
619                                        const ShifterOperand& so) {
620  CHECK_NE(cond, kNoCondition);
621  CHECK(so.IsImmediate());
622  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
623                     static_cast<int32_t>(MOV) << kOpcodeShift |
624                     static_cast<int32_t>(rd) << kRdShift |
625                     so.encodingArm() << kShiftImmShift |
626                     static_cast<int32_t>(opcode) << kShiftShift |
627                     static_cast<int32_t>(rm);
628  Emit(encoding);
629}
630
631
632void Arm32Assembler::EmitShiftRegister(Condition cond,
633                                       Shift opcode,
634                                       Register rd,
635                                       Register rm,
636                                       const ShifterOperand& so) {
637  CHECK_NE(cond, kNoCondition);
638  CHECK(so.IsRegister());
639  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
640                     static_cast<int32_t>(MOV) << kOpcodeShift |
641                     static_cast<int32_t>(rd) << kRdShift |
642                     so.encodingArm() << kShiftRegisterShift |
643                     static_cast<int32_t>(opcode) << kShiftShift |
644                     B4 |
645                     static_cast<int32_t>(rm);
646  Emit(encoding);
647}
648
649
650void Arm32Assembler::EmitBranch(Condition cond, Label* label, bool link) {
651  if (label->IsBound()) {
652    EmitType5(cond, label->Position() - buffer_.Size(), link);
653  } else {
654    int position = buffer_.Size();
655    // Use the offset field of the branch instruction for linking the sites.
656    EmitType5(cond, label->position_, link);
657    label->LinkTo(position);
658  }
659}
660
661
662void Arm32Assembler::clz(Register rd, Register rm, Condition cond) {
663  CHECK_NE(rd, kNoRegister);
664  CHECK_NE(rm, kNoRegister);
665  CHECK_NE(cond, kNoCondition);
666  CHECK_NE(rd, PC);
667  CHECK_NE(rm, PC);
668  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
669                     B24 | B22 | B21 | (0xf << 16) |
670                     (static_cast<int32_t>(rd) << kRdShift) |
671                     (0xf << 8) | B4 | static_cast<int32_t>(rm);
672  Emit(encoding);
673}
674
675
676void Arm32Assembler::movw(Register rd, uint16_t imm16, Condition cond) {
677  CHECK_NE(cond, kNoCondition);
678  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
679                     B25 | B24 | ((imm16 >> 12) << 16) |
680                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
681  Emit(encoding);
682}
683
684
685void Arm32Assembler::movt(Register rd, uint16_t imm16, Condition cond) {
686  CHECK_NE(cond, kNoCondition);
687  int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
688                     B25 | B24 | B22 | ((imm16 >> 12) << 16) |
689                     static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff);
690  Emit(encoding);
691}
692
693
694void Arm32Assembler::EmitMulOp(Condition cond, int32_t opcode,
695                               Register rd, Register rn,
696                               Register rm, Register rs) {
697  CHECK_NE(rd, kNoRegister);
698  CHECK_NE(rn, kNoRegister);
699  CHECK_NE(rm, kNoRegister);
700  CHECK_NE(rs, kNoRegister);
701  CHECK_NE(cond, kNoCondition);
702  int32_t encoding = opcode |
703      (static_cast<int32_t>(cond) << kConditionShift) |
704      (static_cast<int32_t>(rn) << kRnShift) |
705      (static_cast<int32_t>(rd) << kRdShift) |
706      (static_cast<int32_t>(rs) << kRsShift) |
707      B7 | B4 |
708      (static_cast<int32_t>(rm) << kRmShift);
709  Emit(encoding);
710}
711
712void Arm32Assembler::ldrex(Register rt, Register rn, Condition cond) {
713  CHECK_NE(rn, kNoRegister);
714  CHECK_NE(rt, kNoRegister);
715  CHECK_NE(cond, kNoCondition);
716  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
717                     B24 |
718                     B23 |
719                     L   |
720                     (static_cast<int32_t>(rn) << kLdExRnShift) |
721                     (static_cast<int32_t>(rt) << kLdExRtShift) |
722                     B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0;
723  Emit(encoding);
724}
725
726
727void Arm32Assembler::strex(Register rd,
728                           Register rt,
729                           Register rn,
730                           Condition cond) {
731  CHECK_NE(rn, kNoRegister);
732  CHECK_NE(rd, kNoRegister);
733  CHECK_NE(rt, kNoRegister);
734  CHECK_NE(cond, kNoCondition);
735  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
736                     B24 |
737                     B23 |
738                     (static_cast<int32_t>(rn) << kStrExRnShift) |
739                     (static_cast<int32_t>(rd) << kStrExRdShift) |
740                     B11 | B10 | B9 | B8 | B7 | B4 |
741                     (static_cast<int32_t>(rt) << kStrExRtShift);
742  Emit(encoding);
743}
744
745
746void Arm32Assembler::clrex(Condition cond) {
747  CHECK_EQ(cond, AL);   // This cannot be conditional on ARM.
748  int32_t encoding = (kSpecialCondition << kConditionShift) |
749                     B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf;
750  Emit(encoding);
751}
752
753
754void Arm32Assembler::nop(Condition cond) {
755  CHECK_NE(cond, kNoCondition);
756  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
757                     B25 | B24 | B21 | (0xf << 12);
758  Emit(encoding);
759}
760
761
762void Arm32Assembler::vmovsr(SRegister sn, Register rt, Condition cond) {
763  CHECK_NE(sn, kNoSRegister);
764  CHECK_NE(rt, kNoRegister);
765  CHECK_NE(rt, SP);
766  CHECK_NE(rt, PC);
767  CHECK_NE(cond, kNoCondition);
768  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
769                     B27 | B26 | B25 |
770                     ((static_cast<int32_t>(sn) >> 1)*B16) |
771                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
772                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
773  Emit(encoding);
774}
775
776
777void Arm32Assembler::vmovrs(Register rt, SRegister sn, Condition cond) {
778  CHECK_NE(sn, kNoSRegister);
779  CHECK_NE(rt, kNoRegister);
780  CHECK_NE(rt, SP);
781  CHECK_NE(rt, PC);
782  CHECK_NE(cond, kNoCondition);
783  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
784                     B27 | B26 | B25 | B20 |
785                     ((static_cast<int32_t>(sn) >> 1)*B16) |
786                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
787                     ((static_cast<int32_t>(sn) & 1)*B7) | B4;
788  Emit(encoding);
789}
790
791
792void Arm32Assembler::vmovsrr(SRegister sm, Register rt, Register rt2,
793                             Condition cond) {
794  CHECK_NE(sm, kNoSRegister);
795  CHECK_NE(sm, S31);
796  CHECK_NE(rt, kNoRegister);
797  CHECK_NE(rt, SP);
798  CHECK_NE(rt, PC);
799  CHECK_NE(rt2, kNoRegister);
800  CHECK_NE(rt2, SP);
801  CHECK_NE(rt2, PC);
802  CHECK_NE(cond, kNoCondition);
803  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
804                     B27 | B26 | B22 |
805                     (static_cast<int32_t>(rt2)*B16) |
806                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
807                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
808                     (static_cast<int32_t>(sm) >> 1);
809  Emit(encoding);
810}
811
812
813void Arm32Assembler::vmovrrs(Register rt, Register rt2, SRegister sm,
814                             Condition cond) {
815  CHECK_NE(sm, kNoSRegister);
816  CHECK_NE(sm, S31);
817  CHECK_NE(rt, kNoRegister);
818  CHECK_NE(rt, SP);
819  CHECK_NE(rt, PC);
820  CHECK_NE(rt2, kNoRegister);
821  CHECK_NE(rt2, SP);
822  CHECK_NE(rt2, PC);
823  CHECK_NE(rt, rt2);
824  CHECK_NE(cond, kNoCondition);
825  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
826                     B27 | B26 | B22 | B20 |
827                     (static_cast<int32_t>(rt2)*B16) |
828                     (static_cast<int32_t>(rt)*B12) | B11 | B9 |
829                     ((static_cast<int32_t>(sm) & 1)*B5) | B4 |
830                     (static_cast<int32_t>(sm) >> 1);
831  Emit(encoding);
832}
833
834
835void Arm32Assembler::vmovdrr(DRegister dm, Register rt, Register rt2,
836                             Condition cond) {
837  CHECK_NE(dm, kNoDRegister);
838  CHECK_NE(rt, kNoRegister);
839  CHECK_NE(rt, SP);
840  CHECK_NE(rt, PC);
841  CHECK_NE(rt2, kNoRegister);
842  CHECK_NE(rt2, SP);
843  CHECK_NE(rt2, PC);
844  CHECK_NE(cond, kNoCondition);
845  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
846                     B27 | B26 | B22 |
847                     (static_cast<int32_t>(rt2)*B16) |
848                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
849                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
850                     (static_cast<int32_t>(dm) & 0xf);
851  Emit(encoding);
852}
853
854
855void Arm32Assembler::vmovrrd(Register rt, Register rt2, DRegister dm,
856                             Condition cond) {
857  CHECK_NE(dm, kNoDRegister);
858  CHECK_NE(rt, kNoRegister);
859  CHECK_NE(rt, SP);
860  CHECK_NE(rt, PC);
861  CHECK_NE(rt2, kNoRegister);
862  CHECK_NE(rt2, SP);
863  CHECK_NE(rt2, PC);
864  CHECK_NE(rt, rt2);
865  CHECK_NE(cond, kNoCondition);
866  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
867                     B27 | B26 | B22 | B20 |
868                     (static_cast<int32_t>(rt2)*B16) |
869                     (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 |
870                     ((static_cast<int32_t>(dm) >> 4)*B5) | B4 |
871                     (static_cast<int32_t>(dm) & 0xf);
872  Emit(encoding);
873}
874
875
876void Arm32Assembler::vldrs(SRegister sd, const Address& ad, Condition cond) {
877  const Address& addr = static_cast<const Address&>(ad);
878  CHECK_NE(sd, kNoSRegister);
879  CHECK_NE(cond, kNoCondition);
880  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
881                     B27 | B26 | B24 | B20 |
882                     ((static_cast<int32_t>(sd) & 1)*B22) |
883                     ((static_cast<int32_t>(sd) >> 1)*B12) |
884                     B11 | B9 | addr.vencoding();
885  Emit(encoding);
886}
887
888
889void Arm32Assembler::vstrs(SRegister sd, const Address& ad, Condition cond) {
890  const Address& addr = static_cast<const Address&>(ad);
891  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
892  CHECK_NE(sd, kNoSRegister);
893  CHECK_NE(cond, kNoCondition);
894  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
895                     B27 | B26 | B24 |
896                     ((static_cast<int32_t>(sd) & 1)*B22) |
897                     ((static_cast<int32_t>(sd) >> 1)*B12) |
898                     B11 | B9 | addr.vencoding();
899  Emit(encoding);
900}
901
902
903void Arm32Assembler::vldrd(DRegister dd, const Address& ad, Condition cond) {
904  const Address& addr = static_cast<const Address&>(ad);
905  CHECK_NE(dd, kNoDRegister);
906  CHECK_NE(cond, kNoCondition);
907  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
908                     B27 | B26 | B24 | B20 |
909                     ((static_cast<int32_t>(dd) >> 4)*B22) |
910                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
911                     B11 | B9 | B8 | addr.vencoding();
912  Emit(encoding);
913}
914
915
916void Arm32Assembler::vstrd(DRegister dd, const Address& ad, Condition cond) {
917  const Address& addr = static_cast<const Address&>(ad);
918  CHECK_NE(static_cast<Register>(addr.encodingArm() & (0xf << kRnShift)), PC);
919  CHECK_NE(dd, kNoDRegister);
920  CHECK_NE(cond, kNoCondition);
921  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
922                     B27 | B26 | B24 |
923                     ((static_cast<int32_t>(dd) >> 4)*B22) |
924                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
925                     B11 | B9 | B8 | addr.vencoding();
926  Emit(encoding);
927}
928
929
930void Arm32Assembler::vpushs(SRegister reg, int nregs, Condition cond) {
931  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, false, cond);
932}
933
934
935void Arm32Assembler::vpushd(DRegister reg, int nregs, Condition cond) {
936  EmitVPushPop(static_cast<uint32_t>(reg), nregs, true, true, cond);
937}
938
939
940void Arm32Assembler::vpops(SRegister reg, int nregs, Condition cond) {
941  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, false, cond);
942}
943
944
945void Arm32Assembler::vpopd(DRegister reg, int nregs, Condition cond) {
946  EmitVPushPop(static_cast<uint32_t>(reg), nregs, false, true, cond);
947}
948
949
950void Arm32Assembler::EmitVPushPop(uint32_t reg, int nregs, bool push, bool dbl, Condition cond) {
951  CHECK_NE(cond, kNoCondition);
952  CHECK_GT(nregs, 0);
953  uint32_t D;
954  uint32_t Vd;
955  if (dbl) {
956    // Encoded as D:Vd.
957    D = (reg >> 4) & 1;
958    Vd = reg & 15U /* 0b1111 */;
959  } else {
960    // Encoded as Vd:D.
961    D = reg & 1;
962    Vd = (reg >> 1) & 15U /* 0b1111 */;
963  }
964  int32_t encoding = B27 | B26 | B21 | B19 | B18 | B16 |
965                    B11 | B9 |
966        (dbl ? B8 : 0) |
967        (push ? B24 : (B23 | B20)) |
968        static_cast<int32_t>(cond) << kConditionShift |
969        nregs << (dbl ? 1 : 0) |
970        D << 22 |
971        Vd << 12;
972  Emit(encoding);
973}
974
975
976void Arm32Assembler::EmitVFPsss(Condition cond, int32_t opcode,
977                                SRegister sd, SRegister sn, SRegister sm) {
978  CHECK_NE(sd, kNoSRegister);
979  CHECK_NE(sn, kNoSRegister);
980  CHECK_NE(sm, kNoSRegister);
981  CHECK_NE(cond, kNoCondition);
982  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
983                     B27 | B26 | B25 | B11 | B9 | opcode |
984                     ((static_cast<int32_t>(sd) & 1)*B22) |
985                     ((static_cast<int32_t>(sn) >> 1)*B16) |
986                     ((static_cast<int32_t>(sd) >> 1)*B12) |
987                     ((static_cast<int32_t>(sn) & 1)*B7) |
988                     ((static_cast<int32_t>(sm) & 1)*B5) |
989                     (static_cast<int32_t>(sm) >> 1);
990  Emit(encoding);
991}
992
993
994void Arm32Assembler::EmitVFPddd(Condition cond, int32_t opcode,
995                                DRegister dd, DRegister dn, DRegister dm) {
996  CHECK_NE(dd, kNoDRegister);
997  CHECK_NE(dn, kNoDRegister);
998  CHECK_NE(dm, kNoDRegister);
999  CHECK_NE(cond, kNoCondition);
1000  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1001                     B27 | B26 | B25 | B11 | B9 | B8 | opcode |
1002                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1003                     ((static_cast<int32_t>(dn) & 0xf)*B16) |
1004                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1005                     ((static_cast<int32_t>(dn) >> 4)*B7) |
1006                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1007                     (static_cast<int32_t>(dm) & 0xf);
1008  Emit(encoding);
1009}
1010
1011
1012void Arm32Assembler::EmitVFPsd(Condition cond, int32_t opcode,
1013                               SRegister sd, DRegister dm) {
1014  CHECK_NE(sd, kNoSRegister);
1015  CHECK_NE(dm, kNoDRegister);
1016  CHECK_NE(cond, kNoCondition);
1017  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1018                     B27 | B26 | B25 | B11 | B9 | opcode |
1019                     ((static_cast<int32_t>(sd) & 1)*B22) |
1020                     ((static_cast<int32_t>(sd) >> 1)*B12) |
1021                     ((static_cast<int32_t>(dm) >> 4)*B5) |
1022                     (static_cast<int32_t>(dm) & 0xf);
1023  Emit(encoding);
1024}
1025
1026
1027void Arm32Assembler::EmitVFPds(Condition cond, int32_t opcode,
1028                             DRegister dd, SRegister sm) {
1029  CHECK_NE(dd, kNoDRegister);
1030  CHECK_NE(sm, kNoSRegister);
1031  CHECK_NE(cond, kNoCondition);
1032  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1033                     B27 | B26 | B25 | B11 | B9 | opcode |
1034                     ((static_cast<int32_t>(dd) >> 4)*B22) |
1035                     ((static_cast<int32_t>(dd) & 0xf)*B12) |
1036                     ((static_cast<int32_t>(sm) & 1)*B5) |
1037                     (static_cast<int32_t>(sm) >> 1);
1038  Emit(encoding);
1039}
1040
1041
1042void Arm32Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm,
1043                         bool setcc, Condition cond) {
1044  CHECK_NE(shift_imm, 0u);  // Do not use Lsl if no shift is wanted.
1045  if (setcc) {
1046    movs(rd, ShifterOperand(rm, LSL, shift_imm), cond);
1047  } else {
1048    mov(rd, ShifterOperand(rm, LSL, shift_imm), cond);
1049  }
1050}
1051
1052
1053void Arm32Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm,
1054                         bool setcc, Condition cond) {
1055  CHECK_NE(shift_imm, 0u);  // Do not use Lsr if no shift is wanted.
1056  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
1057  if (setcc) {
1058    movs(rd, ShifterOperand(rm, LSR, shift_imm), cond);
1059  } else {
1060    mov(rd, ShifterOperand(rm, LSR, shift_imm), cond);
1061  }
1062}
1063
1064
1065void Arm32Assembler::Asr(Register rd, Register rm, uint32_t shift_imm,
1066                         bool setcc, Condition cond) {
1067  CHECK_NE(shift_imm, 0u);  // Do not use Asr if no shift is wanted.
1068  if (shift_imm == 32) shift_imm = 0;  // Comply to UAL syntax.
1069  if (setcc) {
1070    movs(rd, ShifterOperand(rm, ASR, shift_imm), cond);
1071  } else {
1072    mov(rd, ShifterOperand(rm, ASR, shift_imm), cond);
1073  }
1074}
1075
1076
1077void Arm32Assembler::Ror(Register rd, Register rm, uint32_t shift_imm,
1078                         bool setcc, Condition cond) {
1079  CHECK_NE(shift_imm, 0u);  // Use Rrx instruction.
1080  if (setcc) {
1081    movs(rd, ShifterOperand(rm, ROR, shift_imm), cond);
1082  } else {
1083    mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
1084  }
1085}
1086
1087void Arm32Assembler::Rrx(Register rd, Register rm, bool setcc, Condition cond) {
1088  if (setcc) {
1089    movs(rd, ShifterOperand(rm, ROR, 0), cond);
1090  } else {
1091    mov(rd, ShifterOperand(rm, ROR, 0), cond);
1092  }
1093}
1094
1095
1096void Arm32Assembler::Lsl(Register rd, Register rm, Register rn,
1097                         bool setcc, Condition cond) {
1098  if (setcc) {
1099    movs(rd, ShifterOperand(rm, LSL, rn), cond);
1100  } else {
1101    mov(rd, ShifterOperand(rm, LSL, rn), cond);
1102  }
1103}
1104
1105
1106void Arm32Assembler::Lsr(Register rd, Register rm, Register rn,
1107                         bool setcc, Condition cond) {
1108  if (setcc) {
1109    movs(rd, ShifterOperand(rm, LSR, rn), cond);
1110  } else {
1111    mov(rd, ShifterOperand(rm, LSR, rn), cond);
1112  }
1113}
1114
1115
1116void Arm32Assembler::Asr(Register rd, Register rm, Register rn,
1117                         bool setcc, Condition cond) {
1118  if (setcc) {
1119    movs(rd, ShifterOperand(rm, ASR, rn), cond);
1120  } else {
1121    mov(rd, ShifterOperand(rm, ASR, rn), cond);
1122  }
1123}
1124
1125
1126void Arm32Assembler::Ror(Register rd, Register rm, Register rn,
1127                         bool setcc, Condition cond) {
1128  if (setcc) {
1129    movs(rd, ShifterOperand(rm, ROR, rn), cond);
1130  } else {
1131    mov(rd, ShifterOperand(rm, ROR, rn), cond);
1132  }
1133}
1134
1135void Arm32Assembler::vmstat(Condition cond) {  // VMRS APSR_nzcv, FPSCR
1136  CHECK_NE(cond, kNoCondition);
1137  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1138      B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 |
1139      (static_cast<int32_t>(PC)*B12) |
1140      B11 | B9 | B4;
1141  Emit(encoding);
1142}
1143
1144
1145void Arm32Assembler::svc(uint32_t imm24) {
1146  CHECK(IsUint(24, imm24)) << imm24;
1147  int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24;
1148  Emit(encoding);
1149}
1150
1151
1152void Arm32Assembler::bkpt(uint16_t imm16) {
1153  int32_t encoding = (AL << kConditionShift) | B24 | B21 |
1154                     ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
1155  Emit(encoding);
1156}
1157
1158
1159void Arm32Assembler::blx(Register rm, Condition cond) {
1160  CHECK_NE(rm, kNoRegister);
1161  CHECK_NE(cond, kNoCondition);
1162  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1163                     B24 | B21 | (0xfff << 8) | B5 | B4 |
1164                     (static_cast<int32_t>(rm) << kRmShift);
1165  Emit(encoding);
1166}
1167
1168
1169void Arm32Assembler::bx(Register rm, Condition cond) {
1170  CHECK_NE(rm, kNoRegister);
1171  CHECK_NE(cond, kNoCondition);
1172  int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) |
1173                     B24 | B21 | (0xfff << 8) | B4 |
1174                     (static_cast<int32_t>(rm) << kRmShift);
1175  Emit(encoding);
1176}
1177
1178
1179void Arm32Assembler::Push(Register rd, Condition cond) {
1180  str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond);
1181}
1182
1183
1184void Arm32Assembler::Pop(Register rd, Condition cond) {
1185  ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond);
1186}
1187
1188
1189void Arm32Assembler::PushList(RegList regs, Condition cond) {
1190  stm(DB_W, SP, regs, cond);
1191}
1192
1193
1194void Arm32Assembler::PopList(RegList regs, Condition cond) {
1195  ldm(IA_W, SP, regs, cond);
1196}
1197
1198
1199void Arm32Assembler::Mov(Register rd, Register rm, Condition cond) {
1200  if (rd != rm) {
1201    mov(rd, ShifterOperand(rm), cond);
1202  }
1203}
1204
1205
1206void Arm32Assembler::Bind(Label* label) {
1207  CHECK(!label->IsBound());
1208  int bound_pc = buffer_.Size();
1209  while (label->IsLinked()) {
1210    int32_t position = label->Position();
1211    int32_t next = buffer_.Load<int32_t>(position);
1212    int32_t encoded = Arm32Assembler::EncodeBranchOffset(bound_pc - position, next);
1213    buffer_.Store<int32_t>(position, encoded);
1214    label->position_ = Arm32Assembler::DecodeBranchOffset(next);
1215  }
1216  label->BindTo(bound_pc);
1217}
1218
1219
1220int32_t Arm32Assembler::EncodeBranchOffset(int offset, int32_t inst) {
1221  // The offset is off by 8 due to the way the ARM CPUs read PC.
1222  offset -= 8;
1223  CHECK_ALIGNED(offset, 4);
1224  CHECK(IsInt(POPCOUNT(kBranchOffsetMask), offset)) << offset;
1225
1226  // Properly preserve only the bits supported in the instruction.
1227  offset >>= 2;
1228  offset &= kBranchOffsetMask;
1229  return (inst & ~kBranchOffsetMask) | offset;
1230}
1231
1232
1233int Arm32Assembler::DecodeBranchOffset(int32_t inst) {
1234  // Sign-extend, left-shift by 2, then add 8.
1235  return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1236}
1237
1238
1239void Arm32Assembler::AddConstant(Register rd, int32_t value, Condition cond) {
1240  AddConstant(rd, rd, value, cond);
1241}
1242
1243
1244void Arm32Assembler::AddConstant(Register rd, Register rn, int32_t value,
1245                                 Condition cond) {
1246  if (value == 0) {
1247    if (rd != rn) {
1248      mov(rd, ShifterOperand(rn), cond);
1249    }
1250    return;
1251  }
1252  // We prefer to select the shorter code sequence rather than selecting add for
1253  // positive values and sub for negatives ones, which would slightly improve
1254  // the readability of generated code for some constants.
1255  ShifterOperand shifter_op;
1256  if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1257    add(rd, rn, shifter_op, cond);
1258  } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) {
1259    sub(rd, rn, shifter_op, cond);
1260  } else {
1261    CHECK(rn != IP);
1262    if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1263      mvn(IP, shifter_op, cond);
1264      add(rd, rn, ShifterOperand(IP), cond);
1265    } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) {
1266      mvn(IP, shifter_op, cond);
1267      sub(rd, rn, ShifterOperand(IP), cond);
1268    } else {
1269      movw(IP, Low16Bits(value), cond);
1270      uint16_t value_high = High16Bits(value);
1271      if (value_high != 0) {
1272        movt(IP, value_high, cond);
1273      }
1274      add(rd, rn, ShifterOperand(IP), cond);
1275    }
1276  }
1277}
1278
1279
1280void Arm32Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value,
1281                                         Condition cond) {
1282  ShifterOperand shifter_op;
1283  if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1284    adds(rd, rn, shifter_op, cond);
1285  } else if (ShifterOperand::CanHoldArm(-value, &shifter_op)) {
1286    subs(rd, rn, shifter_op, cond);
1287  } else {
1288    CHECK(rn != IP);
1289    if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1290      mvn(IP, shifter_op, cond);
1291      adds(rd, rn, ShifterOperand(IP), cond);
1292    } else if (ShifterOperand::CanHoldArm(~(-value), &shifter_op)) {
1293      mvn(IP, shifter_op, cond);
1294      subs(rd, rn, ShifterOperand(IP), cond);
1295    } else {
1296      movw(IP, Low16Bits(value), cond);
1297      uint16_t value_high = High16Bits(value);
1298      if (value_high != 0) {
1299        movt(IP, value_high, cond);
1300      }
1301      adds(rd, rn, ShifterOperand(IP), cond);
1302    }
1303  }
1304}
1305
1306
1307void Arm32Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1308  ShifterOperand shifter_op;
1309  if (ShifterOperand::CanHoldArm(value, &shifter_op)) {
1310    mov(rd, shifter_op, cond);
1311  } else if (ShifterOperand::CanHoldArm(~value, &shifter_op)) {
1312    mvn(rd, shifter_op, cond);
1313  } else {
1314    movw(rd, Low16Bits(value), cond);
1315    uint16_t value_high = High16Bits(value);
1316    if (value_high != 0) {
1317      movt(rd, value_high, cond);
1318    }
1319  }
1320}
1321
1322
1323// Implementation note: this method must emit at most one instruction when
1324// Address::CanHoldLoadOffsetArm.
1325void Arm32Assembler::LoadFromOffset(LoadOperandType type,
1326                                    Register reg,
1327                                    Register base,
1328                                    int32_t offset,
1329                                    Condition cond) {
1330  if (!Address::CanHoldLoadOffsetArm(type, offset)) {
1331    CHECK(base != IP);
1332    LoadImmediate(IP, offset, cond);
1333    add(IP, IP, ShifterOperand(base), cond);
1334    base = IP;
1335    offset = 0;
1336  }
1337  CHECK(Address::CanHoldLoadOffsetArm(type, offset));
1338  switch (type) {
1339    case kLoadSignedByte:
1340      ldrsb(reg, Address(base, offset), cond);
1341      break;
1342    case kLoadUnsignedByte:
1343      ldrb(reg, Address(base, offset), cond);
1344      break;
1345    case kLoadSignedHalfword:
1346      ldrsh(reg, Address(base, offset), cond);
1347      break;
1348    case kLoadUnsignedHalfword:
1349      ldrh(reg, Address(base, offset), cond);
1350      break;
1351    case kLoadWord:
1352      ldr(reg, Address(base, offset), cond);
1353      break;
1354    case kLoadWordPair:
1355      ldrd(reg, Address(base, offset), cond);
1356      break;
1357    default:
1358      LOG(FATAL) << "UNREACHABLE";
1359      UNREACHABLE();
1360  }
1361}
1362
1363
1364// Implementation note: this method must emit at most one instruction when
1365// Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset.
1366void Arm32Assembler::LoadSFromOffset(SRegister reg,
1367                                     Register base,
1368                                     int32_t offset,
1369                                     Condition cond) {
1370  if (!Address::CanHoldLoadOffsetArm(kLoadSWord, offset)) {
1371    CHECK_NE(base, IP);
1372    LoadImmediate(IP, offset, cond);
1373    add(IP, IP, ShifterOperand(base), cond);
1374    base = IP;
1375    offset = 0;
1376  }
1377  CHECK(Address::CanHoldLoadOffsetArm(kLoadSWord, offset));
1378  vldrs(reg, Address(base, offset), cond);
1379}
1380
1381
1382// Implementation note: this method must emit at most one instruction when
1383// Address::CanHoldLoadOffsetArm, as expected by JIT::GuardedLoadFromOffset.
1384void Arm32Assembler::LoadDFromOffset(DRegister reg,
1385                                     Register base,
1386                                     int32_t offset,
1387                                     Condition cond) {
1388  if (!Address::CanHoldLoadOffsetArm(kLoadDWord, offset)) {
1389    CHECK_NE(base, IP);
1390    LoadImmediate(IP, offset, cond);
1391    add(IP, IP, ShifterOperand(base), cond);
1392    base = IP;
1393    offset = 0;
1394  }
1395  CHECK(Address::CanHoldLoadOffsetArm(kLoadDWord, offset));
1396  vldrd(reg, Address(base, offset), cond);
1397}
1398
1399
1400// Implementation note: this method must emit at most one instruction when
1401// Address::CanHoldStoreOffsetArm.
1402void Arm32Assembler::StoreToOffset(StoreOperandType type,
1403                                   Register reg,
1404                                   Register base,
1405                                   int32_t offset,
1406                                   Condition cond) {
1407  if (!Address::CanHoldStoreOffsetArm(type, offset)) {
1408    CHECK(reg != IP);
1409    CHECK(base != IP);
1410    LoadImmediate(IP, offset, cond);
1411    add(IP, IP, ShifterOperand(base), cond);
1412    base = IP;
1413    offset = 0;
1414  }
1415  CHECK(Address::CanHoldStoreOffsetArm(type, offset));
1416  switch (type) {
1417    case kStoreByte:
1418      strb(reg, Address(base, offset), cond);
1419      break;
1420    case kStoreHalfword:
1421      strh(reg, Address(base, offset), cond);
1422      break;
1423    case kStoreWord:
1424      str(reg, Address(base, offset), cond);
1425      break;
1426    case kStoreWordPair:
1427      strd(reg, Address(base, offset), cond);
1428      break;
1429    default:
1430      LOG(FATAL) << "UNREACHABLE";
1431      UNREACHABLE();
1432  }
1433}
1434
1435
1436// Implementation note: this method must emit at most one instruction when
1437// Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreToOffset.
1438void Arm32Assembler::StoreSToOffset(SRegister reg,
1439                                    Register base,
1440                                    int32_t offset,
1441                                    Condition cond) {
1442  if (!Address::CanHoldStoreOffsetArm(kStoreSWord, offset)) {
1443    CHECK_NE(base, IP);
1444    LoadImmediate(IP, offset, cond);
1445    add(IP, IP, ShifterOperand(base), cond);
1446    base = IP;
1447    offset = 0;
1448  }
1449  CHECK(Address::CanHoldStoreOffsetArm(kStoreSWord, offset));
1450  vstrs(reg, Address(base, offset), cond);
1451}
1452
1453
1454// Implementation note: this method must emit at most one instruction when
1455// Address::CanHoldStoreOffsetArm, as expected by JIT::GuardedStoreSToOffset.
1456void Arm32Assembler::StoreDToOffset(DRegister reg,
1457                                    Register base,
1458                                    int32_t offset,
1459                                    Condition cond) {
1460  if (!Address::CanHoldStoreOffsetArm(kStoreDWord, offset)) {
1461    CHECK_NE(base, IP);
1462    LoadImmediate(IP, offset, cond);
1463    add(IP, IP, ShifterOperand(base), cond);
1464    base = IP;
1465    offset = 0;
1466  }
1467  CHECK(Address::CanHoldStoreOffsetArm(kStoreDWord, offset));
1468  vstrd(reg, Address(base, offset), cond);
1469}
1470
1471
1472void Arm32Assembler::MemoryBarrier(ManagedRegister mscratch) {
1473  CHECK_EQ(mscratch.AsArm().AsCoreRegister(), R12);
1474#if ANDROID_SMP != 0
1475  int32_t encoding = 0xf57ff05f;  // dmb
1476  Emit(encoding);
1477#endif
1478}
1479
1480
1481void Arm32Assembler::cbz(Register rn, Label* target) {
1482  LOG(FATAL) << "cbz is not supported on ARM32";
1483}
1484
1485
1486void Arm32Assembler::cbnz(Register rn, Label* target) {
1487  LOG(FATAL) << "cbnz is not supported on ARM32";
1488}
1489
1490
1491void Arm32Assembler::CompareAndBranchIfZero(Register r, Label* label) {
1492  cmp(r, ShifterOperand(0));
1493  b(label, EQ);
1494}
1495
1496
1497void Arm32Assembler::CompareAndBranchIfNonZero(Register r, Label* label) {
1498  cmp(r, ShifterOperand(0));
1499  b(label, NE);
1500}
1501
1502
1503}  // namespace arm
1504}  // namespace art
1505