blob: 0c44c088dde90c4957007f0c7ba91cca8b5b60de [file] [log] [blame]
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include <string.h>
4#include "src/assembler.h"
5#include "src/casts.h"
6#include "src/globals.h"
7#include "src/assembler.h"
8#include "src/memory_region.h"
9
Carl Shapiro6b6b5f02011-06-21 15:05:09 -070010namespace art {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070011
12class DirectCallRelocation : public AssemblerFixup {
13 public:
14 void Process(const MemoryRegion& region, int position) {
15 // Direct calls are relative to the following instruction on x86.
16 int32_t pointer = region.Load<int32_t>(position);
17 int32_t start = reinterpret_cast<int32_t>(region.start());
18 int32_t delta = start + position + sizeof(int32_t);
19 region.Store<int32_t>(position, pointer - delta);
20 }
21};
22
Elliott Hughes1f359b02011-07-17 14:27:17 -070023static const char* kRegisterNames[] = {
24 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
25};
26std::ostream& operator<<(std::ostream& os, const Register& rhs) {
27 if (rhs >= EAX && rhs <= EDI) {
28 os << kRegisterNames[rhs];
29 } else {
30 os << "Register[" << int(rhs) << "]";
31 }
32 return os;
33}
34
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070035
36void Assembler::InitializeMemoryWithBreakpoints(byte* data, size_t length) {
37 memset(reinterpret_cast<void*>(data), Instr::kBreakPointInstruction, length);
38}
39
40
41void Assembler::call(Register reg) {
42 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
43 EmitUint8(0xFF);
44 EmitRegisterOperand(2, reg);
45}
46
47
48void Assembler::call(const Address& address) {
49 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
50 EmitUint8(0xFF);
51 EmitOperand(2, address);
52}
53
54
55void Assembler::call(Label* label) {
56 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
57 EmitUint8(0xE8);
58 static const int kSize = 5;
59 EmitLabel(label, kSize);
60}
61
62
63void Assembler::pushl(Register reg) {
64 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
65 EmitUint8(0x50 + reg);
66}
67
68
69void Assembler::pushl(const Address& address) {
70 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
71 EmitUint8(0xFF);
72 EmitOperand(6, address);
73}
74
75
76void Assembler::pushl(const Immediate& imm) {
77 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
78 EmitUint8(0x68);
79 EmitImmediate(imm);
80}
81
82
83void Assembler::popl(Register reg) {
84 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
85 EmitUint8(0x58 + reg);
86}
87
88
89void Assembler::popl(const Address& address) {
90 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
91 EmitUint8(0x8F);
92 EmitOperand(0, address);
93}
94
95
96void Assembler::movl(Register dst, const Immediate& imm) {
97 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
98 EmitUint8(0xB8 + dst);
99 EmitImmediate(imm);
100}
101
102
103void Assembler::movl(Register dst, Register src) {
104 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
105 EmitUint8(0x89);
106 EmitRegisterOperand(src, dst);
107}
108
109
110void Assembler::movl(Register dst, const Address& src) {
111 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
112 EmitUint8(0x8B);
113 EmitOperand(dst, src);
114}
115
116
117void Assembler::movl(const Address& dst, Register src) {
118 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
119 EmitUint8(0x89);
120 EmitOperand(src, dst);
121}
122
123
124void Assembler::movl(const Address& dst, const Immediate& imm) {
125 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
126 EmitUint8(0xC7);
127 EmitOperand(0, dst);
128 EmitImmediate(imm);
129}
130
131
132void Assembler::movzxb(Register dst, ByteRegister src) {
133 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
134 EmitUint8(0x0F);
135 EmitUint8(0xB6);
136 EmitRegisterOperand(dst, src);
137}
138
139
140void Assembler::movzxb(Register dst, const Address& src) {
141 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
142 EmitUint8(0x0F);
143 EmitUint8(0xB6);
144 EmitOperand(dst, src);
145}
146
147
148void Assembler::movsxb(Register dst, ByteRegister src) {
149 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
150 EmitUint8(0x0F);
151 EmitUint8(0xBE);
152 EmitRegisterOperand(dst, src);
153}
154
155
156void Assembler::movsxb(Register dst, const Address& src) {
157 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
158 EmitUint8(0x0F);
159 EmitUint8(0xBE);
160 EmitOperand(dst, src);
161}
162
163
164void Assembler::movb(Register dst, const Address& src) {
165 LOG(FATAL) << "Use movzxb or movsxb instead.";
166}
167
168
169void Assembler::movb(const Address& dst, ByteRegister src) {
170 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
171 EmitUint8(0x88);
172 EmitOperand(src, dst);
173}
174
175
176void Assembler::movb(const Address& dst, const Immediate& imm) {
177 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
178 EmitUint8(0xC6);
179 EmitOperand(EAX, dst);
180 CHECK(imm.is_int8());
181 EmitUint8(imm.value() & 0xFF);
182}
183
184
185void Assembler::movzxw(Register dst, Register src) {
186 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
187 EmitUint8(0x0F);
188 EmitUint8(0xB7);
189 EmitRegisterOperand(dst, src);
190}
191
192
193void Assembler::movzxw(Register dst, const Address& src) {
194 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
195 EmitUint8(0x0F);
196 EmitUint8(0xB7);
197 EmitOperand(dst, src);
198}
199
200
201void Assembler::movsxw(Register dst, Register src) {
202 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
203 EmitUint8(0x0F);
204 EmitUint8(0xBF);
205 EmitRegisterOperand(dst, src);
206}
207
208
209void Assembler::movsxw(Register dst, const Address& src) {
210 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
211 EmitUint8(0x0F);
212 EmitUint8(0xBF);
213 EmitOperand(dst, src);
214}
215
216
217void Assembler::movw(Register dst, const Address& src) {
218 LOG(FATAL) << "Use movzxw or movsxw instead.";
219}
220
221
222void Assembler::movw(const Address& dst, Register src) {
223 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
224 EmitOperandSizeOverride();
225 EmitUint8(0x89);
226 EmitOperand(src, dst);
227}
228
229
230void Assembler::leal(Register dst, const Address& src) {
231 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
232 EmitUint8(0x8D);
233 EmitOperand(dst, src);
234}
235
236
237void Assembler::cmovs(Register dst, Register src) {
238 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
239 EmitUint8(0x0F);
240 EmitUint8(0x48);
241 EmitRegisterOperand(dst, src);
242}
243
244
245void Assembler::cmovns(Register dst, Register src) {
246 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
247 EmitUint8(0x0F);
248 EmitUint8(0x49);
249 EmitRegisterOperand(dst, src);
250}
251
252
253void Assembler::movss(XmmRegister dst, const Address& src) {
254 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
255 EmitUint8(0xF3);
256 EmitUint8(0x0F);
257 EmitUint8(0x10);
258 EmitOperand(dst, src);
259}
260
261
262void Assembler::movss(const Address& dst, XmmRegister src) {
263 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
264 EmitUint8(0xF3);
265 EmitUint8(0x0F);
266 EmitUint8(0x11);
267 EmitOperand(src, dst);
268}
269
270
271void Assembler::movss(XmmRegister dst, XmmRegister src) {
272 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
273 EmitUint8(0xF3);
274 EmitUint8(0x0F);
275 EmitUint8(0x11);
276 EmitXmmRegisterOperand(src, dst);
277}
278
279
280void Assembler::movd(XmmRegister dst, Register src) {
281 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
282 EmitUint8(0x66);
283 EmitUint8(0x0F);
284 EmitUint8(0x6E);
285 EmitOperand(dst, Operand(src));
286}
287
288
289void Assembler::movd(Register dst, XmmRegister src) {
290 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
291 EmitUint8(0x66);
292 EmitUint8(0x0F);
293 EmitUint8(0x7E);
294 EmitOperand(src, Operand(dst));
295}
296
297
298void Assembler::addss(XmmRegister dst, XmmRegister src) {
299 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
300 EmitUint8(0xF3);
301 EmitUint8(0x0F);
302 EmitUint8(0x58);
303 EmitXmmRegisterOperand(dst, src);
304}
305
306
307void Assembler::addss(XmmRegister dst, const Address& src) {
308 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
309 EmitUint8(0xF3);
310 EmitUint8(0x0F);
311 EmitUint8(0x58);
312 EmitOperand(dst, src);
313}
314
315
316void Assembler::subss(XmmRegister dst, XmmRegister src) {
317 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
318 EmitUint8(0xF3);
319 EmitUint8(0x0F);
320 EmitUint8(0x5C);
321 EmitXmmRegisterOperand(dst, src);
322}
323
324
325void Assembler::subss(XmmRegister dst, const Address& src) {
326 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
327 EmitUint8(0xF3);
328 EmitUint8(0x0F);
329 EmitUint8(0x5C);
330 EmitOperand(dst, src);
331}
332
333
334void Assembler::mulss(XmmRegister dst, XmmRegister src) {
335 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
336 EmitUint8(0xF3);
337 EmitUint8(0x0F);
338 EmitUint8(0x59);
339 EmitXmmRegisterOperand(dst, src);
340}
341
342
343void Assembler::mulss(XmmRegister dst, const Address& src) {
344 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
345 EmitUint8(0xF3);
346 EmitUint8(0x0F);
347 EmitUint8(0x59);
348 EmitOperand(dst, src);
349}
350
351
352void Assembler::divss(XmmRegister dst, XmmRegister src) {
353 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
354 EmitUint8(0xF3);
355 EmitUint8(0x0F);
356 EmitUint8(0x5E);
357 EmitXmmRegisterOperand(dst, src);
358}
359
360
361void Assembler::divss(XmmRegister dst, const Address& src) {
362 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
363 EmitUint8(0xF3);
364 EmitUint8(0x0F);
365 EmitUint8(0x5E);
366 EmitOperand(dst, src);
367}
368
369
370void Assembler::flds(const Address& src) {
371 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
372 EmitUint8(0xD9);
373 EmitOperand(0, src);
374}
375
376
377void Assembler::fstps(const Address& dst) {
378 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
379 EmitUint8(0xD9);
380 EmitOperand(3, dst);
381}
382
383
384void Assembler::movsd(XmmRegister dst, const Address& src) {
385 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
386 EmitUint8(0xF2);
387 EmitUint8(0x0F);
388 EmitUint8(0x10);
389 EmitOperand(dst, src);
390}
391
392
393void Assembler::movsd(const Address& dst, XmmRegister src) {
394 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
395 EmitUint8(0xF2);
396 EmitUint8(0x0F);
397 EmitUint8(0x11);
398 EmitOperand(src, dst);
399}
400
401
402void Assembler::movsd(XmmRegister dst, XmmRegister src) {
403 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
404 EmitUint8(0xF2);
405 EmitUint8(0x0F);
406 EmitUint8(0x11);
407 EmitXmmRegisterOperand(src, dst);
408}
409
410
411void Assembler::addsd(XmmRegister dst, XmmRegister src) {
412 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
413 EmitUint8(0xF2);
414 EmitUint8(0x0F);
415 EmitUint8(0x58);
416 EmitXmmRegisterOperand(dst, src);
417}
418
419
420void Assembler::addsd(XmmRegister dst, const Address& src) {
421 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
422 EmitUint8(0xF2);
423 EmitUint8(0x0F);
424 EmitUint8(0x58);
425 EmitOperand(dst, src);
426}
427
428
429void Assembler::subsd(XmmRegister dst, XmmRegister src) {
430 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
431 EmitUint8(0xF2);
432 EmitUint8(0x0F);
433 EmitUint8(0x5C);
434 EmitXmmRegisterOperand(dst, src);
435}
436
437
438void Assembler::subsd(XmmRegister dst, const Address& src) {
439 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
440 EmitUint8(0xF2);
441 EmitUint8(0x0F);
442 EmitUint8(0x5C);
443 EmitOperand(dst, src);
444}
445
446
447void Assembler::mulsd(XmmRegister dst, XmmRegister src) {
448 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
449 EmitUint8(0xF2);
450 EmitUint8(0x0F);
451 EmitUint8(0x59);
452 EmitXmmRegisterOperand(dst, src);
453}
454
455
456void Assembler::mulsd(XmmRegister dst, const Address& src) {
457 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
458 EmitUint8(0xF2);
459 EmitUint8(0x0F);
460 EmitUint8(0x59);
461 EmitOperand(dst, src);
462}
463
464
465void Assembler::divsd(XmmRegister dst, XmmRegister src) {
466 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
467 EmitUint8(0xF2);
468 EmitUint8(0x0F);
469 EmitUint8(0x5E);
470 EmitXmmRegisterOperand(dst, src);
471}
472
473
474void Assembler::divsd(XmmRegister dst, const Address& src) {
475 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
476 EmitUint8(0xF2);
477 EmitUint8(0x0F);
478 EmitUint8(0x5E);
479 EmitOperand(dst, src);
480}
481
482
483void Assembler::cvtsi2ss(XmmRegister dst, Register src) {
484 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
485 EmitUint8(0xF3);
486 EmitUint8(0x0F);
487 EmitUint8(0x2A);
488 EmitOperand(dst, Operand(src));
489}
490
491
492void Assembler::cvtsi2sd(XmmRegister dst, Register src) {
493 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
494 EmitUint8(0xF2);
495 EmitUint8(0x0F);
496 EmitUint8(0x2A);
497 EmitOperand(dst, Operand(src));
498}
499
500
501void Assembler::cvtss2si(Register dst, XmmRegister src) {
502 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
503 EmitUint8(0xF3);
504 EmitUint8(0x0F);
505 EmitUint8(0x2D);
506 EmitXmmRegisterOperand(dst, src);
507}
508
509
510void Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
511 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
512 EmitUint8(0xF3);
513 EmitUint8(0x0F);
514 EmitUint8(0x5A);
515 EmitXmmRegisterOperand(dst, src);
516}
517
518
519void Assembler::cvtsd2si(Register dst, XmmRegister src) {
520 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
521 EmitUint8(0xF2);
522 EmitUint8(0x0F);
523 EmitUint8(0x2D);
524 EmitXmmRegisterOperand(dst, src);
525}
526
527
528void Assembler::cvttss2si(Register dst, XmmRegister src) {
529 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
530 EmitUint8(0xF3);
531 EmitUint8(0x0F);
532 EmitUint8(0x2C);
533 EmitXmmRegisterOperand(dst, src);
534}
535
536
537void Assembler::cvttsd2si(Register dst, XmmRegister src) {
538 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
539 EmitUint8(0xF2);
540 EmitUint8(0x0F);
541 EmitUint8(0x2C);
542 EmitXmmRegisterOperand(dst, src);
543}
544
545
546void Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
547 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
548 EmitUint8(0xF2);
549 EmitUint8(0x0F);
550 EmitUint8(0x5A);
551 EmitXmmRegisterOperand(dst, src);
552}
553
554
555void Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
556 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
557 EmitUint8(0xF3);
558 EmitUint8(0x0F);
559 EmitUint8(0xE6);
560 EmitXmmRegisterOperand(dst, src);
561}
562
563
564void Assembler::comiss(XmmRegister a, XmmRegister b) {
565 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
566 EmitUint8(0x0F);
567 EmitUint8(0x2F);
568 EmitXmmRegisterOperand(a, b);
569}
570
571
572void Assembler::comisd(XmmRegister a, XmmRegister b) {
573 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
574 EmitUint8(0x66);
575 EmitUint8(0x0F);
576 EmitUint8(0x2F);
577 EmitXmmRegisterOperand(a, b);
578}
579
580
581void Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
582 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
583 EmitUint8(0xF2);
584 EmitUint8(0x0F);
585 EmitUint8(0x51);
586 EmitXmmRegisterOperand(dst, src);
587}
588
589
590void Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
591 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
592 EmitUint8(0xF3);
593 EmitUint8(0x0F);
594 EmitUint8(0x51);
595 EmitXmmRegisterOperand(dst, src);
596}
597
598
599void Assembler::xorpd(XmmRegister dst, const Address& src) {
600 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
601 EmitUint8(0x66);
602 EmitUint8(0x0F);
603 EmitUint8(0x57);
604 EmitOperand(dst, src);
605}
606
607
608void Assembler::xorpd(XmmRegister dst, XmmRegister src) {
609 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
610 EmitUint8(0x66);
611 EmitUint8(0x0F);
612 EmitUint8(0x57);
613 EmitXmmRegisterOperand(dst, src);
614}
615
616
617void Assembler::xorps(XmmRegister dst, const Address& src) {
618 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
619 EmitUint8(0x0F);
620 EmitUint8(0x57);
621 EmitOperand(dst, src);
622}
623
624
625void Assembler::xorps(XmmRegister dst, XmmRegister src) {
626 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
627 EmitUint8(0x0F);
628 EmitUint8(0x57);
629 EmitXmmRegisterOperand(dst, src);
630}
631
632
633void Assembler::andpd(XmmRegister dst, const Address& src) {
634 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
635 EmitUint8(0x66);
636 EmitUint8(0x0F);
637 EmitUint8(0x54);
638 EmitOperand(dst, src);
639}
640
641
642void Assembler::fldl(const Address& src) {
643 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
644 EmitUint8(0xDD);
645 EmitOperand(0, src);
646}
647
648
649void Assembler::fstpl(const Address& dst) {
650 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
651 EmitUint8(0xDD);
652 EmitOperand(3, dst);
653}
654
655
656void Assembler::fnstcw(const Address& dst) {
657 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
658 EmitUint8(0xD9);
659 EmitOperand(7, dst);
660}
661
662
663void Assembler::fldcw(const Address& src) {
664 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
665 EmitUint8(0xD9);
666 EmitOperand(5, src);
667}
668
669
670void Assembler::fistpl(const Address& dst) {
671 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
672 EmitUint8(0xDF);
673 EmitOperand(7, dst);
674}
675
676
677void Assembler::fistps(const Address& dst) {
678 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
679 EmitUint8(0xDB);
680 EmitOperand(3, dst);
681}
682
683
684void Assembler::fildl(const Address& src) {
685 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
686 EmitUint8(0xDF);
687 EmitOperand(5, src);
688}
689
690
691void Assembler::fincstp() {
692 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
693 EmitUint8(0xD9);
694 EmitUint8(0xF7);
695}
696
697
698void Assembler::ffree(const Immediate& index) {
699 CHECK_LT(index.value(), 7);
700 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
701 EmitUint8(0xDD);
702 EmitUint8(0xC0 + index.value());
703}
704
705
706void Assembler::fsin() {
707 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
708 EmitUint8(0xD9);
709 EmitUint8(0xFE);
710}
711
712
713void Assembler::fcos() {
714 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
715 EmitUint8(0xD9);
716 EmitUint8(0xFF);
717}
718
719
720void Assembler::fptan() {
721 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
722 EmitUint8(0xD9);
723 EmitUint8(0xF2);
724}
725
726
727void Assembler::xchgl(Register dst, Register src) {
728 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
729 EmitUint8(0x87);
730 EmitRegisterOperand(dst, src);
731}
732
733
734void Assembler::cmpl(Register reg, const Immediate& imm) {
735 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
736 EmitComplex(7, Operand(reg), imm);
737}
738
739
740void Assembler::cmpl(Register reg0, Register reg1) {
741 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
742 EmitUint8(0x3B);
743 EmitOperand(reg0, Operand(reg1));
744}
745
746
747void Assembler::cmpl(Register reg, const Address& address) {
748 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
749 EmitUint8(0x3B);
750 EmitOperand(reg, address);
751}
752
753
754void Assembler::addl(Register dst, Register src) {
755 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
756 EmitUint8(0x03);
757 EmitRegisterOperand(dst, src);
758}
759
760
761void Assembler::addl(Register reg, const Address& address) {
762 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
763 EmitUint8(0x03);
764 EmitOperand(reg, address);
765}
766
767
768void Assembler::cmpl(const Address& address, Register reg) {
769 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
770 EmitUint8(0x39);
771 EmitOperand(reg, address);
772}
773
774
775void Assembler::cmpl(const Address& address, const Immediate& imm) {
776 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
777 EmitComplex(7, address, imm);
778}
779
780
781void Assembler::testl(Register reg1, Register reg2) {
782 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
783 EmitUint8(0x85);
784 EmitRegisterOperand(reg1, reg2);
785}
786
787
788void Assembler::testl(Register reg, const Immediate& immediate) {
789 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
790 // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
791 // we only test the byte register to keep the encoding short.
792 if (immediate.is_uint8() && reg < 4) {
793 // Use zero-extended 8-bit immediate.
794 if (reg == EAX) {
795 EmitUint8(0xA8);
796 } else {
797 EmitUint8(0xF6);
798 EmitUint8(0xC0 + reg);
799 }
800 EmitUint8(immediate.value() & 0xFF);
801 } else if (reg == EAX) {
802 // Use short form if the destination is EAX.
803 EmitUint8(0xA9);
804 EmitImmediate(immediate);
805 } else {
806 EmitUint8(0xF7);
807 EmitOperand(0, Operand(reg));
808 EmitImmediate(immediate);
809 }
810}
811
812
813void Assembler::andl(Register dst, Register src) {
814 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
815 EmitUint8(0x23);
816 EmitOperand(dst, Operand(src));
817}
818
819
820void Assembler::andl(Register dst, const Immediate& imm) {
821 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
822 EmitComplex(4, Operand(dst), imm);
823}
824
825
826void Assembler::orl(Register dst, Register src) {
827 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
828 EmitUint8(0x0B);
829 EmitOperand(dst, Operand(src));
830}
831
832
833void Assembler::orl(Register dst, const Immediate& imm) {
834 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
835 EmitComplex(1, Operand(dst), imm);
836}
837
838
839void Assembler::xorl(Register dst, Register src) {
840 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
841 EmitUint8(0x33);
842 EmitOperand(dst, Operand(src));
843}
844
845
846void Assembler::addl(Register reg, const Immediate& imm) {
847 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
848 EmitComplex(0, Operand(reg), imm);
849}
850
851
852void Assembler::addl(const Address& address, Register reg) {
853 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
854 EmitUint8(0x01);
855 EmitOperand(reg, address);
856}
857
858
859void Assembler::addl(const Address& address, const Immediate& imm) {
860 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
861 EmitComplex(0, address, imm);
862}
863
864
865void Assembler::adcl(Register reg, const Immediate& imm) {
866 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
867 EmitComplex(2, Operand(reg), imm);
868}
869
870
871void Assembler::adcl(Register dst, Register src) {
872 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
873 EmitUint8(0x13);
874 EmitOperand(dst, Operand(src));
875}
876
877
878void Assembler::adcl(Register dst, const Address& address) {
879 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
880 EmitUint8(0x13);
881 EmitOperand(dst, address);
882}
883
884
885void Assembler::subl(Register dst, Register src) {
886 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
887 EmitUint8(0x2B);
888 EmitOperand(dst, Operand(src));
889}
890
891
892void Assembler::subl(Register reg, const Immediate& imm) {
893 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
894 EmitComplex(5, Operand(reg), imm);
895}
896
897
898void Assembler::subl(Register reg, const Address& address) {
899 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
900 EmitUint8(0x2B);
901 EmitOperand(reg, address);
902}
903
904
905void Assembler::cdq() {
906 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
907 EmitUint8(0x99);
908}
909
910
911void Assembler::idivl(Register reg) {
912 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
913 EmitUint8(0xF7);
914 EmitUint8(0xF8 | reg);
915}
916
917
918void Assembler::imull(Register dst, Register src) {
919 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
920 EmitUint8(0x0F);
921 EmitUint8(0xAF);
922 EmitOperand(dst, Operand(src));
923}
924
925
926void Assembler::imull(Register reg, const Immediate& imm) {
927 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
928 EmitUint8(0x69);
929 EmitOperand(reg, Operand(reg));
930 EmitImmediate(imm);
931}
932
933
934void Assembler::imull(Register reg, const Address& address) {
935 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
936 EmitUint8(0x0F);
937 EmitUint8(0xAF);
938 EmitOperand(reg, address);
939}
940
941
942void Assembler::imull(Register reg) {
943 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
944 EmitUint8(0xF7);
945 EmitOperand(5, Operand(reg));
946}
947
948
949void Assembler::imull(const Address& address) {
950 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
951 EmitUint8(0xF7);
952 EmitOperand(5, address);
953}
954
955
956void Assembler::mull(Register reg) {
957 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
958 EmitUint8(0xF7);
959 EmitOperand(4, Operand(reg));
960}
961
962
963void Assembler::mull(const Address& address) {
964 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
965 EmitUint8(0xF7);
966 EmitOperand(4, address);
967}
968
969
970void Assembler::sbbl(Register dst, Register src) {
971 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
972 EmitUint8(0x1B);
973 EmitOperand(dst, Operand(src));
974}
975
976
977void Assembler::sbbl(Register reg, const Immediate& imm) {
978 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
979 EmitComplex(3, Operand(reg), imm);
980}
981
982
983void Assembler::sbbl(Register dst, const Address& address) {
984 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
985 EmitUint8(0x1B);
986 EmitOperand(dst, address);
987}
988
989
990void Assembler::incl(Register reg) {
991 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
992 EmitUint8(0x40 + reg);
993}
994
995
996void Assembler::incl(const Address& address) {
997 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
998 EmitUint8(0xFF);
999 EmitOperand(0, address);
1000}
1001
1002
1003void Assembler::decl(Register reg) {
1004 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1005 EmitUint8(0x48 + reg);
1006}
1007
1008
1009void Assembler::decl(const Address& address) {
1010 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1011 EmitUint8(0xFF);
1012 EmitOperand(1, address);
1013}
1014
1015
1016void Assembler::shll(Register reg, const Immediate& imm) {
1017 EmitGenericShift(4, reg, imm);
1018}
1019
1020
1021void Assembler::shll(Register operand, Register shifter) {
1022 EmitGenericShift(4, operand, shifter);
1023}
1024
1025
1026void Assembler::shrl(Register reg, const Immediate& imm) {
1027 EmitGenericShift(5, reg, imm);
1028}
1029
1030
1031void Assembler::shrl(Register operand, Register shifter) {
1032 EmitGenericShift(5, operand, shifter);
1033}
1034
1035
1036void Assembler::sarl(Register reg, const Immediate& imm) {
1037 EmitGenericShift(7, reg, imm);
1038}
1039
1040
1041void Assembler::sarl(Register operand, Register shifter) {
1042 EmitGenericShift(7, operand, shifter);
1043}
1044
1045
1046void Assembler::shld(Register dst, Register src) {
1047 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1048 EmitUint8(0x0F);
1049 EmitUint8(0xA5);
1050 EmitRegisterOperand(src, dst);
1051}
1052
1053
1054void Assembler::negl(Register reg) {
1055 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1056 EmitUint8(0xF7);
1057 EmitOperand(3, Operand(reg));
1058}
1059
1060
1061void Assembler::notl(Register reg) {
1062 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1063 EmitUint8(0xF7);
1064 EmitUint8(0xD0 | reg);
1065}
1066
1067
1068void Assembler::enter(const Immediate& imm) {
1069 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1070 EmitUint8(0xC8);
1071 CHECK(imm.is_uint16());
1072 EmitUint8(imm.value() & 0xFF);
1073 EmitUint8((imm.value() >> 8) & 0xFF);
1074 EmitUint8(0x00);
1075}
1076
1077
1078void Assembler::leave() {
1079 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1080 EmitUint8(0xC9);
1081}
1082
1083
1084void Assembler::ret() {
1085 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1086 EmitUint8(0xC3);
1087}
1088
1089
1090void Assembler::ret(const Immediate& imm) {
1091 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1092 EmitUint8(0xC2);
1093 CHECK(imm.is_uint16());
1094 EmitUint8(imm.value() & 0xFF);
1095 EmitUint8((imm.value() >> 8) & 0xFF);
1096}
1097
1098
1099
1100void Assembler::nop() {
1101 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1102 EmitUint8(0x90);
1103}
1104
1105
1106void Assembler::int3() {
1107 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1108 EmitUint8(0xCC);
1109}
1110
1111
1112void Assembler::hlt() {
1113 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1114 EmitUint8(0xF4);
1115}
1116
1117
1118void Assembler::j(Condition condition, Label* label) {
1119 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1120 if (label->IsBound()) {
1121 static const int kShortSize = 2;
1122 static const int kLongSize = 6;
1123 int offset = label->Position() - buffer_.Size();
1124 CHECK_LE(offset, 0);
1125 if (IsInt(8, offset - kShortSize)) {
1126 EmitUint8(0x70 + condition);
1127 EmitUint8((offset - kShortSize) & 0xFF);
1128 } else {
1129 EmitUint8(0x0F);
1130 EmitUint8(0x80 + condition);
1131 EmitInt32(offset - kLongSize);
1132 }
1133 } else {
1134 EmitUint8(0x0F);
1135 EmitUint8(0x80 + condition);
1136 EmitLabelLink(label);
1137 }
1138}
1139
1140
1141void Assembler::jmp(Register reg) {
1142 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1143 EmitUint8(0xFF);
1144 EmitRegisterOperand(4, reg);
1145}
1146
1147
1148void Assembler::jmp(Label* label) {
1149 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1150 if (label->IsBound()) {
1151 static const int kShortSize = 2;
1152 static const int kLongSize = 5;
1153 int offset = label->Position() - buffer_.Size();
1154 CHECK_LE(offset, 0);
1155 if (IsInt(8, offset - kShortSize)) {
1156 EmitUint8(0xEB);
1157 EmitUint8((offset - kShortSize) & 0xFF);
1158 } else {
1159 EmitUint8(0xE9);
1160 EmitInt32(offset - kLongSize);
1161 }
1162 } else {
1163 EmitUint8(0xE9);
1164 EmitLabelLink(label);
1165 }
1166}
1167
1168
1169void Assembler::lock() {
1170 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1171 EmitUint8(0xF0);
1172}
1173
1174
1175void Assembler::cmpxchgl(const Address& address, Register reg) {
1176 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1177 EmitUint8(0x0F);
1178 EmitUint8(0xB1);
1179 EmitOperand(reg, address);
1180}
1181
1182
1183void Assembler::AddImmediate(Register reg, const Immediate& imm) {
1184 int value = imm.value();
1185 if (value > 0) {
1186 if (value == 1) {
1187 incl(reg);
1188 } else if (value != 0) {
1189 addl(reg, imm);
1190 }
1191 } else if (value < 0) {
1192 value = -value;
1193 if (value == 1) {
1194 decl(reg);
1195 } else if (value != 0) {
1196 subl(reg, Immediate(value));
1197 }
1198 }
1199}
1200
1201
1202void Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
1203 // TODO: Need to have a code constants table.
1204 int64_t constant = bit_cast<int64_t, double>(value);
1205 pushl(Immediate(High32Bits(constant)));
1206 pushl(Immediate(Low32Bits(constant)));
1207 movsd(dst, Address(ESP, 0));
1208 addl(ESP, Immediate(2 * kWordSize));
1209}
1210
1211
1212void Assembler::FloatNegate(XmmRegister f) {
1213 static const struct {
1214 uint32_t a;
1215 uint32_t b;
1216 uint32_t c;
1217 uint32_t d;
1218 } float_negate_constant __attribute__((aligned(16))) =
1219 { 0x80000000, 0x00000000, 0x80000000, 0x00000000 };
1220 xorps(f, Address::Absolute(reinterpret_cast<uword>(&float_negate_constant)));
1221}
1222
1223
1224void Assembler::DoubleNegate(XmmRegister d) {
1225 static const struct {
1226 uint64_t a;
1227 uint64_t b;
1228 } double_negate_constant __attribute__((aligned(16))) =
1229 {0x8000000000000000LL, 0x8000000000000000LL};
1230 xorpd(d, Address::Absolute(reinterpret_cast<uword>(&double_negate_constant)));
1231}
1232
1233
1234void Assembler::DoubleAbs(XmmRegister reg) {
1235 static const struct {
1236 uint64_t a;
1237 uint64_t b;
1238 } double_abs_constant __attribute__((aligned(16))) =
1239 {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
1240 andpd(reg, Address::Absolute(reinterpret_cast<uword>(&double_abs_constant)));
1241}
1242
1243
1244void Assembler::Align(int alignment, int offset) {
1245 CHECK(IsPowerOfTwo(alignment));
1246 // Emit nop instruction until the real position is aligned.
1247 while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
1248 nop();
1249 }
1250}
1251
1252
1253void Assembler::Bind(Label* label) {
1254 int bound = buffer_.Size();
1255 CHECK(!label->IsBound()); // Labels can only be bound once.
1256 while (label->IsLinked()) {
1257 int position = label->LinkPosition();
1258 int next = buffer_.Load<int32_t>(position);
1259 buffer_.Store<int32_t>(position, bound - (position + 4));
1260 label->position_ = next;
1261 }
1262 label->BindTo(bound);
1263}
1264
1265
1266void Assembler::Stop(const char* message) {
1267 // Emit the message address as immediate operand in the test rax instruction,
1268 // followed by the int3 instruction.
1269 // Execution can be resumed with the 'cont' command in gdb.
1270 testl(EAX, Immediate(reinterpret_cast<int32_t>(message)));
1271 int3();
1272}
1273
1274
1275void Assembler::EmitOperand(int rm, const Operand& operand) {
1276 CHECK_GE(rm, 0);
1277 CHECK_LT(rm, 8);
1278 const int length = operand.length_;
1279 CHECK_GT(length, 0);
1280 // Emit the ModRM byte updated with the given RM value.
1281 CHECK_EQ(operand.encoding_[0] & 0x38, 0);
1282 EmitUint8(operand.encoding_[0] + (rm << 3));
1283 // Emit the rest of the encoded operand.
1284 for (int i = 1; i < length; i++) {
1285 EmitUint8(operand.encoding_[i]);
1286 }
1287}
1288
1289
1290void Assembler::EmitImmediate(const Immediate& imm) {
1291 EmitInt32(imm.value());
1292}
1293
1294
1295void Assembler::EmitComplex(int rm,
1296 const Operand& operand,
1297 const Immediate& immediate) {
1298 CHECK_GE(rm, 0);
1299 CHECK_LT(rm, 8);
1300 if (immediate.is_int8()) {
1301 // Use sign-extended 8-bit immediate.
1302 EmitUint8(0x83);
1303 EmitOperand(rm, operand);
1304 EmitUint8(immediate.value() & 0xFF);
1305 } else if (operand.IsRegister(EAX)) {
1306 // Use short form if the destination is eax.
1307 EmitUint8(0x05 + (rm << 3));
1308 EmitImmediate(immediate);
1309 } else {
1310 EmitUint8(0x81);
1311 EmitOperand(rm, operand);
1312 EmitImmediate(immediate);
1313 }
1314}
1315
1316
1317void Assembler::EmitLabel(Label* label, int instruction_size) {
1318 if (label->IsBound()) {
1319 int offset = label->Position() - buffer_.Size();
1320 CHECK_LE(offset, 0);
1321 EmitInt32(offset - instruction_size);
1322 } else {
1323 EmitLabelLink(label);
1324 }
1325}
1326
1327
1328void Assembler::EmitLabelLink(Label* label) {
1329 CHECK(!label->IsBound());
1330 int position = buffer_.Size();
1331 EmitInt32(label->position_);
1332 label->LinkTo(position);
1333}
1334
1335
1336void Assembler::EmitGenericShift(int rm,
1337 Register reg,
1338 const Immediate& imm) {
1339 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1340 CHECK(imm.is_int8());
1341 if (imm.value() == 1) {
1342 EmitUint8(0xD1);
1343 EmitOperand(rm, Operand(reg));
1344 } else {
1345 EmitUint8(0xC1);
1346 EmitOperand(rm, Operand(reg));
1347 EmitUint8(imm.value() & 0xFF);
1348 }
1349}
1350
1351
1352void Assembler::EmitGenericShift(int rm,
1353 Register operand,
1354 Register shifter) {
1355 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
1356 CHECK_EQ(shifter, ECX);
1357 EmitUint8(0xD3);
1358 EmitOperand(rm, Operand(operand));
1359}
1360
Carl Shapiro6b6b5f02011-06-21 15:05:09 -07001361} // namespace art