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