Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: src/x64/assembler-x64.cc

Issue 112066: Add test, neg, and not instructions to x64 assembler (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "macro-assembler.h" 30 #include "macro-assembler.h"
31 #include "serialize.h"
31 32
32 namespace v8 { 33 namespace v8 {
33 namespace internal { 34 namespace internal {
34 35
35 // ----------------------------------------------------------------------------- 36 // -----------------------------------------------------------------------------
36 // Implementation of Register 37 // Implementation of Register
37 38
38 Register rax = { 0 }; 39 Register rax = { 0 };
39 Register rcx = { 1 }; 40 Register rcx = { 1 };
40 Register rdx = { 2 }; 41 Register rdx = { 2 };
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 167 }
167 168
168 169
169 void Assembler::Align(int m) { 170 void Assembler::Align(int m) {
170 ASSERT(IsPowerOf2(m)); 171 ASSERT(IsPowerOf2(m));
171 while ((pc_offset() & (m - 1)) != 0) { 172 while ((pc_offset() & (m - 1)) != 0) {
172 nop(); 173 nop();
173 } 174 }
174 } 175 }
175 176
176 void Assembler::RecordComment(char const* a) {
177 UNIMPLEMENTED();
178 }
179
180 void Assembler::RecordPosition(int a) {
181 UNIMPLEMENTED();
182 }
183
184 void Assembler::RecordStatementPosition(int a) {
185 UNIMPLEMENTED();
186 }
187
188 177
189 void Assembler::bind_to(Label* L, int pos) { 178 void Assembler::bind_to(Label* L, int pos) {
190 ASSERT(!L->is_bound()); // Label may only be bound once. 179 ASSERT(!L->is_bound()); // Label may only be bound once.
191 last_pc_ = NULL; 180 last_pc_ = NULL;
192 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. 181 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid.
193 if (L->is_linked()) { 182 if (L->is_linked()) {
194 int current = L->pos(); 183 int current = L->pos();
195 int next = long_at(current); 184 int next = long_at(current);
196 while (next != current) { 185 while (next != current) {
197 // relative address, relative to point after address 186 // relative address, relative to point after address
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 emit_rex_64(dst, src); 301 emit_rex_64(dst, src);
313 emit(opcode); 302 emit(opcode);
314 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); 303 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
315 } 304 }
316 305
317 void Assembler::immediate_arithmetic_op(byte subcode, 306 void Assembler::immediate_arithmetic_op(byte subcode,
318 Register dst, 307 Register dst,
319 Immediate src) { 308 Immediate src) {
320 EnsureSpace ensure_space(this); 309 EnsureSpace ensure_space(this);
321 last_pc_ = pc_; 310 last_pc_ = pc_;
322 emit_rex_64(rax, dst); 311 emit_rex_64(dst);
323 if (is_int8(src.value_)) { 312 if (is_int8(src.value_)) {
324 emit(0x83); 313 emit(0x83);
325 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); 314 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
326 emit(src.value_); 315 emit(src.value_);
316 } else if (dst.is(rax)) {
317 emit(0x05 | (subcode << 3));
318 emitl(src.value_);
327 } else { 319 } else {
328 emit(0x81); 320 emit(0x81);
329 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); 321 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
330 emitl(src.value_); 322 emitl(src.value_);
331 } 323 }
332 } 324 }
333 325
334 void Assembler::immediate_arithmetic_op(byte subcode, 326 void Assembler::immediate_arithmetic_op(byte subcode,
335 const Operand& dst, 327 const Operand& dst,
336 Immediate src) { 328 Immediate src) {
337 EnsureSpace ensure_space(this); 329 EnsureSpace ensure_space(this);
338 last_pc_ = pc_; 330 last_pc_ = pc_;
339 emit_rex_64(rax, dst); 331 emit_rex_64(dst);
340 if (is_int8(src.value_)) { 332 if (is_int8(src.value_)) {
341 emit(0x83); 333 emit(0x83);
342 emit_operand(Register::toRegister(subcode), dst); 334 emit_operand(Register::toRegister(subcode), dst);
343 emit(src.value_); 335 emit(src.value_);
344 } else { 336 } else {
345 emit(0x81); 337 emit(0x81);
346 emit_operand(Register::toRegister(subcode), dst); 338 emit_operand(Register::toRegister(subcode), dst);
347 emitl(src.value_); 339 emitl(src.value_);
348 } 340 }
349 } 341 }
(...skipping 16 matching lines...) Expand all
366 int32_t current = pc_offset(); 358 int32_t current = pc_offset();
367 emitl(current); 359 emitl(current);
368 L->link_to(current); 360 L->link_to(current);
369 } 361 }
370 } 362 }
371 363
372 364
373 void Assembler::dec(Register dst) { 365 void Assembler::dec(Register dst) {
374 EnsureSpace ensure_space(this); 366 EnsureSpace ensure_space(this);
375 last_pc_ = pc_; 367 last_pc_ = pc_;
376 emit_rex_64(rcx, dst); 368 emit_rex_64(dst);
377 emit(0xFF); 369 emit(0xFF);
378 emit(0xC8 | (dst.code() & 0x7)); 370 emit(0xC8 | (dst.code() & 0x7));
379 } 371 }
380 372
381 373
382 void Assembler::dec(const Operand& dst) { 374 void Assembler::dec(const Operand& dst) {
383 EnsureSpace ensure_space(this); 375 EnsureSpace ensure_space(this);
384 last_pc_ = pc_; 376 last_pc_ = pc_;
385 emit_rex_64(rax, dst); 377 emit_rex_64(dst);
386 emit(0xFF); 378 emit(0xFF);
387 emit_operand(rcx, dst); 379 emit_operand(1, dst);
388 } 380 }
389 381
390 382
391 void Assembler::hlt() { 383 void Assembler::hlt() {
392 EnsureSpace ensure_space(this); 384 EnsureSpace ensure_space(this);
393 last_pc_ = pc_; 385 last_pc_ = pc_;
394 emit(0xF4); 386 emit(0xF4);
395 } 387 }
396 388
397 389
398 void Assembler::inc(Register dst) { 390 void Assembler::inc(Register dst) {
399 EnsureSpace ensure_space(this); 391 EnsureSpace ensure_space(this);
400 last_pc_ = pc_; 392 last_pc_ = pc_;
401 emit_rex_64(rax, dst); 393 emit_rex_64(dst);
402 emit(0xFF); 394 emit(0xFF);
403 emit(0xC0 | (dst.code() & 0x7)); 395 emit(0xC0 | (dst.code() & 0x7));
404 } 396 }
405 397
406 398
407 void Assembler::inc(const Operand& dst) { 399 void Assembler::inc(const Operand& dst) {
408 EnsureSpace ensure_space(this); 400 EnsureSpace ensure_space(this);
409 last_pc_ = pc_; 401 last_pc_ = pc_;
410 emit_rex_64(rax, dst); 402 emit_rex_64(dst);
411 emit(0xFF); 403 emit(0xFF);
412 emit_operand(rax, dst); 404 emit_operand(0, dst);
413 } 405 }
414 406
415 407
416 void Assembler::int3() { 408 void Assembler::int3() {
417 EnsureSpace ensure_space(this); 409 EnsureSpace ensure_space(this);
418 last_pc_ = pc_; 410 last_pc_ = pc_;
419 emit(0xCC); 411 emit(0xCC);
420 } 412 }
421 413
422 414
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 last_pc_ = pc_; 493 last_pc_ = pc_;
502 emit_rex_64(dst, src); 494 emit_rex_64(dst, src);
503 emit(0x8B); 495 emit(0x8B);
504 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); 496 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
505 } 497 }
506 498
507 499
508 void Assembler::movq(Register dst, Immediate value) { 500 void Assembler::movq(Register dst, Immediate value) {
509 EnsureSpace ensure_space(this); 501 EnsureSpace ensure_space(this);
510 last_pc_ = pc_; 502 last_pc_ = pc_;
511 emit_rex_64(rax, dst); 503 emit_rex_64(dst);
512 emit(0xC7); 504 emit(0xC7);
513 emit(0xC0 | (dst.code() & 0x7)); 505 emit(0xC0 | (dst.code() & 0x7));
514 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. 506 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
515 } 507 }
516 508
517 509
518 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { 510 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
519 EnsureSpace ensure_space(this); 511 EnsureSpace ensure_space(this);
520 last_pc_ = pc_; 512 last_pc_ = pc_;
521 emit_rex_64(rax, dst); 513 emit_rex_64(dst);
522 emit(0xB8 | (dst.code() & 0x7)); 514 emit(0xB8 | (dst.code() & 0x7));
523 emitq(value, rmode); 515 emitq(value, rmode);
524 } 516 }
525 517
526 518
519 void Assembler::neg(Register dst) {
520 EnsureSpace ensure_space(this);
521 last_pc_ = pc_;
522 emit_rex_64(dst);
523 emit(0xF7);
524 emit(0xC0 | (0x3 << 3) | (dst.code() & 0x7));
525 }
526
527
528 void Assembler::neg(const Operand& dst) {
529 EnsureSpace ensure_space(this);
530 last_pc_ = pc_;
531 emit_rex_64(dst);
532 emit(0xF7);
533 emit_operand(3, dst);
534 }
535
536
527 void Assembler::nop() { 537 void Assembler::nop() {
528 EnsureSpace ensure_space(this); 538 EnsureSpace ensure_space(this);
529 last_pc_ = pc_; 539 last_pc_ = pc_;
530 emit(0x90); 540 emit(0x90);
531 } 541 }
532 542
533 543
544 void Assembler::not_(Register dst) {
545 EnsureSpace ensure_space(this);
546 last_pc_ = pc_;
547 emit_rex_64(dst);
548 emit(0xF7);
549 emit(0xC0 | (0x2 << 3) | (dst.code() & 0x7));
550 }
551
552
553 void Assembler::not_(const Operand& dst) {
554 EnsureSpace ensure_space(this);
555 last_pc_ = pc_;
556 emit_rex_64(dst);
557 emit(0xF7);
558 emit_operand(2, dst);
559 }
560
561
534 void Assembler::pop(Register dst) { 562 void Assembler::pop(Register dst) {
535 EnsureSpace ensure_space(this); 563 EnsureSpace ensure_space(this);
536 last_pc_ = pc_; 564 last_pc_ = pc_;
537 if (dst.code() & 0x8) { 565 if (dst.code() & 0x8) {
538 emit_rex_64(rax, dst); 566 emit_rex_64(dst);
539 } 567 }
540 emit(0x58 | (dst.code() & 0x7)); 568 emit(0x58 | (dst.code() & 0x7));
541 } 569 }
542 570
543 571
544 void Assembler::pop(const Operand& dst) { 572 void Assembler::pop(const Operand& dst) {
545 EnsureSpace ensure_space(this); 573 EnsureSpace ensure_space(this);
546 last_pc_ = pc_; 574 last_pc_ = pc_;
547 emit_rex_64(rax, dst); // Could be omitted in some cases. 575 emit_rex_64(dst); // Could be omitted in some cases.
548 emit(0x8F); 576 emit(0x8F);
549 emit_operand(rax, dst); 577 emit_operand(0, dst);
550 } 578 }
551 579
552 580
553 void Assembler::push(Register src) { 581 void Assembler::push(Register src) {
554 EnsureSpace ensure_space(this); 582 EnsureSpace ensure_space(this);
555 last_pc_ = pc_; 583 last_pc_ = pc_;
556 if (src.code() & 0x8) { 584 if (src.code() & 0x8) {
557 emit_rex_64(rax, src); 585 emit_rex_64(src);
558 } 586 }
559 emit(0x50 | (src.code() & 0x7)); 587 emit(0x50 | (src.code() & 0x7));
560 } 588 }
561 589
562 590
563 void Assembler::push(const Operand& src) { 591 void Assembler::push(const Operand& src) {
564 EnsureSpace ensure_space(this); 592 EnsureSpace ensure_space(this);
565 last_pc_ = pc_; 593 last_pc_ = pc_;
566 emit_rex_64(rsi, src); // Could be omitted in some cases. 594 emit_rex_64(src); // Could be omitted in some cases.
567 emit(0xFF); 595 emit(0xFF);
568 emit_operand(rsi, src); 596 emit_operand(6, src);
569 } 597 }
570 598
571 599
572 void Assembler::ret(int imm16) { 600 void Assembler::ret(int imm16) {
573 EnsureSpace ensure_space(this); 601 EnsureSpace ensure_space(this);
574 last_pc_ = pc_; 602 last_pc_ = pc_;
575 ASSERT(is_uint16(imm16)); 603 ASSERT(is_uint16(imm16));
576 if (imm16 == 0) { 604 if (imm16 == 0) {
577 emit(0xC3); 605 emit(0xC3);
578 } else { 606 } else {
579 emit(0xC2); 607 emit(0xC2);
580 emit(imm16 & 0xFF); 608 emit(imm16 & 0xFF);
581 emit((imm16 >> 8) & 0xFF); 609 emit((imm16 >> 8) & 0xFF);
582 } 610 }
583 } 611 }
584 612
613
614 void Assembler::testb(Register reg, Immediate mask) {
615 EnsureSpace ensure_space(this);
616 last_pc_ = pc_;
617 if (reg.is(rax)) {
618 emit(0xA8);
619 emit(mask);
620 } else {
621 if (reg.code() & 0x8) {
622 emit_rex_32(rax, reg);
623 }
624 emit(0xF6);
625 emit(0xC0 | (reg.code() & 0x3));
626 emit(mask.value_); // Low byte emitted.
627 }
628 }
629
630
631 void Assembler::testb(const Operand& op, Immediate mask) {
632 EnsureSpace ensure_space(this);
633 last_pc_ = pc_;
634 emit_optional_rex_32(rax, op);
635 emit(0xF6);
636 emit_operand(rax, op); // Operation code 0
637 emit(mask.value_); // Low byte emitted.
638 }
639
640
641 void Assembler::testl(Register reg, Immediate mask) {
642 EnsureSpace ensure_space(this);
643 last_pc_ = pc_;
644 if (reg.is(rax)) {
645 emit(0xA9);
646 emit(mask);
647 } else {
648 emit_optional_rex_32(rax, reg);
649 emit(0xF7);
650 emit(0xC0 | (reg.code() & 0x3));
651 emit(mask);
652 }
653 }
654
655
656 void Assembler::testl(const Operand& op, Immediate mask) {
657 EnsureSpace ensure_space(this);
658 last_pc_ = pc_;
659 emit_optional_rex_32(rax, op);
660 emit(0xF7);
661 emit_operand(rax, op); // Operation code 0
662 emit(mask);
663 }
664
665
666 // Relocation information implementations
667
668 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
669 ASSERT(rmode != RelocInfo::NONE);
670 // Don't record external references unless the heap will be serialized.
671 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
672 !Serializer::enabled() &&
673 !FLAG_debug_code) {
674 return;
675 }
676 RelocInfo rinfo(pc_, rmode, data);
677 reloc_info_writer.Write(&rinfo);
678 }
679
680 void Assembler::RecordJSReturn() {
681 WriteRecordedPositions();
682 EnsureSpace ensure_space(this);
683 RecordRelocInfo(RelocInfo::JS_RETURN);
684 }
685
686
687 void Assembler::RecordComment(const char* msg) {
688 if (FLAG_debug_code) {
689 EnsureSpace ensure_space(this);
690 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
691 }
692 }
693
694
695 void Assembler::RecordPosition(int pos) {
696 ASSERT(pos != RelocInfo::kNoPosition);
697 ASSERT(pos >= 0);
698 current_position_ = pos;
699 }
700
701
702 void Assembler::RecordStatementPosition(int pos) {
703 ASSERT(pos != RelocInfo::kNoPosition);
704 ASSERT(pos >= 0);
705 current_statement_position_ = pos;
706 }
707
708
709 void Assembler::WriteRecordedPositions() {
710 // Write the statement position if it is different from what was written last
711 // time.
712 if (current_statement_position_ != written_statement_position_) {
713 EnsureSpace ensure_space(this);
714 RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
715 written_statement_position_ = current_statement_position_;
716 }
717
718 // Write the position if it is different from what was written last time and
719 // also different from the written statement position.
720 if (current_position_ != written_position_ &&
721 current_position_ != written_statement_position_) {
722 EnsureSpace ensure_space(this);
723 RecordRelocInfo(RelocInfo::POSITION, current_position_);
724 written_position_ = current_position_;
725 }
726 }
727
728
729 const int RelocInfo::kApplyMask =
730 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
731 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
732
733
585 } } // namespace v8::internal 734 } } // namespace v8::internal
586 735
587 736
588 // TODO(x64): Implement and move these to their correct cc-files: 737 // TODO(x64): Implement and move these to their correct cc-files:
589 #include "ast.h" 738 #include "ast.h"
590 #include "bootstrapper.h" 739 #include "bootstrapper.h"
591 #include "codegen-inl.h" 740 #include "codegen-inl.h"
592 #include "cpu.h" 741 #include "cpu.h"
593 #include "debug.h" 742 #include "debug.h"
594 #include "disasm.h" 743 #include "disasm.h"
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 return NULL; 874 return NULL;
726 } 875 }
727 876
728 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* a, 877 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* a,
729 JSObject* b, 878 JSObject* b,
730 String* c) { 879 String* c) {
731 UNIMPLEMENTED(); 880 UNIMPLEMENTED();
732 return NULL; 881 return NULL;
733 } 882 }
734 883
735 const int RelocInfo::kApplyMask = -1;
736
737 StackFrame::Type StackFrame::ComputeType(StackFrame::State* a) { 884 StackFrame::Type StackFrame::ComputeType(StackFrame::State* a) {
738 UNIMPLEMENTED(); 885 UNIMPLEMENTED();
739 return NONE; 886 return NONE;
740 } 887 }
741 888
742 Object* StoreStubCompiler::CompileStoreCallback(JSObject* a, 889 Object* StoreStubCompiler::CompileStoreCallback(JSObject* a,
743 AccessorInfo* b, 890 AccessorInfo* b,
744 String* c) { 891 String* c) {
745 UNIMPLEMENTED(); 892 UNIMPLEMENTED();
746 return NULL; 893 return NULL;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 UNIMPLEMENTED(); 1003 UNIMPLEMENTED();
857 return NULL; 1004 return NULL;
858 } 1005 }
859 1006
860 byte* JavaScriptFrame::GetCallerStackPointer() const { 1007 byte* JavaScriptFrame::GetCallerStackPointer() const {
861 UNIMPLEMENTED(); 1008 UNIMPLEMENTED();
862 return NULL; 1009 return NULL;
863 } 1010 }
864 1011
865 } } // namespace v8::internal 1012 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/assembler-x64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698