blob: 3ce5199e4588d71e176b69a30e73d623167e5cc1 [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
Elliott Hughes1f359b02011-07-17 14:27:17 -070064static 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
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700111void 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);
Elliott Hughes1f359b02011-07-17 14:27:17 -0700201 CHECK_EQ(so.type(), 1U);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700202 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);
Elliott Hughes1f359b02011-07-17 14:27:17 -0700218 CHECK_EQ(so.type(), 0U);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700219 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
Carl Shapiro6b6b5f02011-06-21 15:05:09 -07001097} // namespace art