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

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

Issue 113997: Add miscellaneous operations 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 XMMRegister xmm12 = { 12 }; 70 XMMRegister xmm12 = { 12 };
71 XMMRegister xmm13 = { 13 }; 71 XMMRegister xmm13 = { 13 };
72 XMMRegister xmm14 = { 14 }; 72 XMMRegister xmm14 = { 14 };
73 XMMRegister xmm15 = { 15 }; 73 XMMRegister xmm15 = { 15 };
74 74
75 // Safe default is no features. 75 // Safe default is no features.
76 uint64_t CpuFeatures::supported_ = 0; 76 uint64_t CpuFeatures::supported_ = 0;
77 uint64_t CpuFeatures::enabled_ = 0; 77 uint64_t CpuFeatures::enabled_ = 0;
78 78
79 void CpuFeatures::Probe() { 79 void CpuFeatures::Probe() {
80 // TODO(X64): UNIMPLEMENTED 80 ASSERT(Heap::HasBeenSetup());
81 ASSERT(supported_ == 0);
82 if (Serializer::enabled()) return; // No features if we might serialize.
83
84 Assembler assm(NULL, 0);
85 Label cpuid, done;
86 #define __ assm.
87 // Save old esp, since we are going to modify the stack.
88 __ push(rbp);
89 __ pushfq();
90 __ push(rcx);
91 __ push(rbx);
92 __ movq(rbp, rsp);
93
94 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
95 __ pushfq();
96 __ pop(rax);
97 __ movq(rdx, rax);
98 __ xor_(rax, Immediate(0x200000)); // Flip bit 21.
99 __ push(rax);
100 __ popfq();
101 __ pushfq();
102 __ pop(rax);
103 __ xor_(rax, rdx); // Different if CPUID is supported.
104 __ j(not_zero, &cpuid);
105
106 // CPUID not supported. Clear the supported features in edx:eax.
107 __ xor_(rax, rax);
108 __ jmp(&done);
109
110 // Invoke CPUID with 1 in eax to get feature information in
111 // ecx:edx. Temporarily enable CPUID support because we know it's
112 // safe here.
113 __ bind(&cpuid);
114 __ movq(rax, Immediate(1));
115 supported_ = (1 << CPUID);
116 { Scope fscope(CPUID);
117 __ cpuid();
118 }
119 supported_ = 0;
120
121 // Move the result from ecx:edx to rax and make sure to mark the
122 // CPUID feature as supported.
123 __ movl(rax, rdx); // Zero-extended to 64 bits.
124 __ shl(rcx, Immediate(32));
125 __ or_(rax, rcx);
126 __ or_(rax, Immediate(1 << CPUID));
127
128 // Done.
129 __ bind(&done);
130 __ movq(rsp, rbp);
131 __ pop(rbx);
132 __ pop(rcx);
133 __ popfq();
134 __ pop(rbp);
135 __ ret(0);
136 #undef __
137
138 CodeDesc desc;
139 assm.GetCode(&desc);
140 Object* code =
141 Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL);
142 if (!code->IsCode()) return;
143 LOG(CodeCreateEvent("Builtin", Code::cast(code), "CpuFeatures::Probe"));
144 typedef uint64_t (*F0)();
145 F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
146 supported_ = probe();
81 } 147 }
82 148
83 // ----------------------------------------------------------------------------- 149 // -----------------------------------------------------------------------------
84 // Implementation of Assembler 150 // Implementation of Assembler
85 151
86 #ifdef GENERATED_CODE_COVERAGE 152 #ifdef GENERATED_CODE_COVERAGE
87 static void InitCoverageLog(); 153 static void InitCoverageLog();
88 #endif 154 #endif
89 155
90 byte* Assembler::spare_buffer_ = NULL; 156 byte* Assembler::spare_buffer_ = NULL;
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 427
362 void Assembler::shift(Register dst, int subcode) { 428 void Assembler::shift(Register dst, int subcode) {
363 EnsureSpace ensure_space(this); 429 EnsureSpace ensure_space(this);
364 last_pc_ = pc_; 430 last_pc_ = pc_;
365 emit_rex_64(dst); 431 emit_rex_64(dst);
366 emit(0xD3); 432 emit(0xD3);
367 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); 433 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7));
368 } 434 }
369 435
370 436
437 void Assembler::bt(const Operand& dst, Register src) {
438 EnsureSpace ensure_space(this);
439 last_pc_ = pc_;
440 emit_rex_64(src, dst);
441 emit(0x0F);
442 emit(0xA3);
443 emit_operand(src, dst);
444 }
445
446
447 void Assembler::bts(const Operand& dst, Register src) {
448 EnsureSpace ensure_space(this);
449 last_pc_ = pc_;
450 emit_rex_64(src, dst);
451 emit(0x0F);
452 emit(0xAB);
453 emit_operand(src, dst);
454 }
455
456
371 void Assembler::call(Label* L) { 457 void Assembler::call(Label* L) {
372 EnsureSpace ensure_space(this); 458 EnsureSpace ensure_space(this);
373 last_pc_ = pc_; 459 last_pc_ = pc_;
374 // 1110 1000 #32-bit disp 460 // 1110 1000 #32-bit disp
375 emit(0xE8); 461 emit(0xE8);
376 if (L->is_bound()) { 462 if (L->is_bound()) {
377 int offset = L->pos() - pc_offset() - sizeof(int32_t); 463 int offset = L->pos() - pc_offset() - sizeof(int32_t);
378 ASSERT(offset <= 0); 464 ASSERT(offset <= 0);
379 emitl(offset); 465 emitl(offset);
380 } else if (L->is_linked()) { 466 } else if (L->is_linked()) {
(...skipping 13 matching lines...) Expand all
394 last_pc_ = pc_; 480 last_pc_ = pc_;
395 // Opcode: FF /2 r64 481 // Opcode: FF /2 r64
396 if (!is_uint3(adr.code())) { 482 if (!is_uint3(adr.code())) {
397 emit_rex_64(adr); 483 emit_rex_64(adr);
398 } 484 }
399 emit(0xFF); 485 emit(0xFF);
400 emit(0xD0 | (adr.code() & 0x07)); 486 emit(0xD0 | (adr.code() & 0x07));
401 } 487 }
402 488
403 489
490 void Assembler::cpuid() {
491 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID));
492 EnsureSpace ensure_space(this);
493 last_pc_ = pc_;
494 emit(0x0F);
495 emit(0xA2);
496 }
497
498
499 void Assembler::cqo() {
500 EnsureSpace ensure_space(this);
501 last_pc_ = pc_;
502 emit_rex_64();
503 emit(0x99);
504 }
505
506
404 void Assembler::dec(Register dst) { 507 void Assembler::dec(Register dst) {
405 EnsureSpace ensure_space(this); 508 EnsureSpace ensure_space(this);
406 last_pc_ = pc_; 509 last_pc_ = pc_;
407 emit_rex_64(dst); 510 emit_rex_64(dst);
408 emit(0xFF); 511 emit(0xFF);
409 emit(0xC8 | (dst.code() & 0x7)); 512 emit(0xC8 | (dst.code() & 0x7));
410 } 513 }
411 514
412 515
413 void Assembler::dec(const Operand& dst) { 516 void Assembler::dec(const Operand& dst) {
414 EnsureSpace ensure_space(this); 517 EnsureSpace ensure_space(this);
415 last_pc_ = pc_; 518 last_pc_ = pc_;
416 emit_rex_64(dst); 519 emit_rex_64(dst);
417 emit(0xFF); 520 emit(0xFF);
418 emit_operand(1, dst); 521 emit_operand(1, dst);
419 } 522 }
420 523
421 524
525 void Assembler::enter(Immediate size) {
526 EnsureSpace ensure_space(this);
527 last_pc_ = pc_;
528 emit(0xC8);
529 emitw(size.value_); // 16 bit operand, always.
530 emit(0);
531 }
532
533
422 void Assembler::hlt() { 534 void Assembler::hlt() {
423 EnsureSpace ensure_space(this); 535 EnsureSpace ensure_space(this);
424 last_pc_ = pc_; 536 last_pc_ = pc_;
425 emit(0xF4); 537 emit(0xF4);
426 } 538 }
427 539
428 540
429 void Assembler::inc(Register dst) { 541 void Assembler::inc(Register dst) {
430 EnsureSpace ensure_space(this); 542 EnsureSpace ensure_space(this);
431 last_pc_ = pc_; 543 last_pc_ = pc_;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 last_pc_ = pc_; 635 last_pc_ = pc_;
524 // Opcode FF/4 r64 636 // Opcode FF/4 r64
525 if (!is_uint3(target.code())) { 637 if (!is_uint3(target.code())) {
526 emit_rex_64(target); 638 emit_rex_64(target);
527 } 639 }
528 emit(0xFF); 640 emit(0xFF);
529 emit(0xE0 | target.code() & 0x07); 641 emit(0xE0 | target.code() & 0x07);
530 } 642 }
531 643
532 644
645 void Assembler::lea(Register dst, const Operand& src) {
646 EnsureSpace ensure_space(this);
647 last_pc_ = pc_;
648 emit_rex_64(dst, src);
649 emit(0x8D);
650 emit_operand(dst, src);
651 }
652
653
654 void Assembler::leave() {
655 EnsureSpace ensure_space(this);
656 last_pc_ = pc_;
657 emit(0xC9);
658 }
659
660
661 void Assembler::movl(Register dst, const Operand& src) {
662 EnsureSpace ensure_space(this);
663 last_pc_ = pc_;
664 emit_optional_rex_32(dst, src);
665 emit(0x8B);
666 emit_operand(dst, src);
667 }
668
669
670 void Assembler::movl(Register dst, Register src) {
671 EnsureSpace ensure_space(this);
672 last_pc_ = pc_;
673 emit_optional_rex_32(dst, src);
674 emit(0x8B);
675 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
676 }
677
678
679 void Assembler::movl(const Operand& dst, Register src) {
680 EnsureSpace ensure_space(this);
681 last_pc_ = pc_;
682 emit_optional_rex_32(src, dst);
683 emit(0x89);
684 emit_operand(src, dst);
685 }
686
687
533 void Assembler::movq(Register dst, const Operand& src) { 688 void Assembler::movq(Register dst, const Operand& src) {
534 EnsureSpace ensure_space(this); 689 EnsureSpace ensure_space(this);
535 last_pc_ = pc_; 690 last_pc_ = pc_;
536 emit_rex_64(dst, src); 691 emit_rex_64(dst, src);
537 emit(0x8B); 692 emit(0x8B);
538 emit_operand(dst, src); 693 emit_operand(dst, src);
539 } 694 }
540 695
541 696
542 void Assembler::movq(Register dst, Register src) { 697 void Assembler::movq(Register dst, Register src) {
543 EnsureSpace ensure_space(this); 698 EnsureSpace ensure_space(this);
544 last_pc_ = pc_; 699 last_pc_ = pc_;
545 emit_rex_64(dst, src); 700 emit_rex_64(dst, src);
546 emit(0x8B); 701 emit(0x8B);
547 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); 702 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7));
548 } 703 }
549 704
550 705
706 void Assembler::movq(const Operand& dst, Register src) {
707 EnsureSpace ensure_space(this);
708 last_pc_ = pc_;
709 emit_rex_64(src, dst);
710 emit(0x89);
711 emit_operand(src, dst);
712 }
713
714
551 void Assembler::movq(Register dst, Immediate value) { 715 void Assembler::movq(Register dst, Immediate value) {
552 EnsureSpace ensure_space(this); 716 EnsureSpace ensure_space(this);
553 last_pc_ = pc_; 717 last_pc_ = pc_;
554 emit_rex_64(dst); 718 emit_rex_64(dst);
555 emit(0xC7); 719 emit(0xC7);
556 emit(0xC0 | (dst.code() & 0x7)); 720 emit(0xC0 | (dst.code() & 0x7));
557 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. 721 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
558 } 722 }
559 723
560 724
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 873
710 void Assembler::pop(const Operand& dst) { 874 void Assembler::pop(const Operand& dst) {
711 EnsureSpace ensure_space(this); 875 EnsureSpace ensure_space(this);
712 last_pc_ = pc_; 876 last_pc_ = pc_;
713 emit_rex_64(dst); // Could be omitted in some cases. 877 emit_rex_64(dst); // Could be omitted in some cases.
714 emit(0x8F); 878 emit(0x8F);
715 emit_operand(0, dst); 879 emit_operand(0, dst);
716 } 880 }
717 881
718 882
883 void Assembler::popfq() {
884 EnsureSpace ensure_space(this);
885 last_pc_ = pc_;
886 emit(0x9D);
887 }
888
889
719 void Assembler::push(Register src) { 890 void Assembler::push(Register src) {
720 EnsureSpace ensure_space(this); 891 EnsureSpace ensure_space(this);
721 last_pc_ = pc_; 892 last_pc_ = pc_;
722 if (src.code() & 0x8) { 893 if (src.code() & 0x8) {
723 emit_rex_64(src); 894 emit_rex_64(src);
724 } 895 }
725 emit(0x50 | (src.code() & 0x7)); 896 emit(0x50 | (src.code() & 0x7));
726 } 897 }
727 898
728 899
729 void Assembler::push(const Operand& src) { 900 void Assembler::push(const Operand& src) {
730 EnsureSpace ensure_space(this); 901 EnsureSpace ensure_space(this);
731 last_pc_ = pc_; 902 last_pc_ = pc_;
732 emit_rex_64(src); // Could be omitted in some cases. 903 emit_rex_64(src); // Could be omitted in some cases.
733 emit(0xFF); 904 emit(0xFF);
734 emit_operand(6, src); 905 emit_operand(6, src);
735 } 906 }
736 907
737 908
909 void Assembler::push(Immediate value) {
910 EnsureSpace ensure_space(this);
911 last_pc_ = pc_;
912 if (is_int8(value.value_)) {
913 emit(0x6A);
914 emit(value.value_); // Emit low byte of value.
915 } else {
916 emit(0x68);
917 emitl(value.value_);
918 }
919 }
920
921
922 void Assembler::pushfq() {
923 EnsureSpace ensure_space(this);
924 last_pc_ = pc_;
925 emit(0x9C);
926 }
927
928
929 void Assembler::rcl(Register dst, uint8_t imm8) {
930 EnsureSpace ensure_space(this);
931 last_pc_ = pc_;
932 ASSERT(is_uint6(imm8)); // illegal shift count
933 if (imm8 == 1) {
934 emit_rex_64(dst);
935 emit(0xD1);
936 emit(0xD0 | (dst.code() & 0x7));
937 } else {
938 emit_rex_64(dst);
939 emit(0xC1);
940 emit(0xD0 | (dst.code() & 0x7));
941 emit(imm8);
942 }
943 }
944
945
738 void Assembler::ret(int imm16) { 946 void Assembler::ret(int imm16) {
739 EnsureSpace ensure_space(this); 947 EnsureSpace ensure_space(this);
740 last_pc_ = pc_; 948 last_pc_ = pc_;
741 ASSERT(is_uint16(imm16)); 949 ASSERT(is_uint16(imm16));
742 if (imm16 == 0) { 950 if (imm16 == 0) {
743 emit(0xC3); 951 emit(0xC3);
744 } else { 952 } else {
745 emit(0xC2); 953 emit(0xC2);
746 emit(imm16 & 0xFF); 954 emit(imm16 & 0xFF);
747 emit((imm16 >> 8) & 0xFF); 955 emit((imm16 >> 8) & 0xFF);
748 } 956 }
749 } 957 }
750 958
751 959
960 void Assembler::xchg(Register dst, Register src) {
961 EnsureSpace ensure_space(this);
962 last_pc_ = pc_;
963 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
964 Register other = src.is(rax) ? dst : src;
965 emit_rex_64(other);
966 emit(0x90 | (other.code() & 0x7));
967 } else {
968 emit_rex_64(src, dst);
969 emit(0x87);
970 emit(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7));
971 }
972 }
973
974
752 void Assembler::testb(Register reg, Immediate mask) { 975 void Assembler::testb(Register reg, Immediate mask) {
753 EnsureSpace ensure_space(this); 976 EnsureSpace ensure_space(this);
754 last_pc_ = pc_; 977 last_pc_ = pc_;
755 if (reg.is(rax)) { 978 if (reg.is(rax)) {
756 emit(0xA8); 979 emit(0xA8);
757 emit(mask); 980 emit(mask);
758 } else { 981 } else {
759 if (reg.code() & 0x8) { 982 if (reg.code() & 0x8) {
760 emit_rex_32(rax, reg); 983 emit_rex_32(rax, reg);
761 } 984 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 UNIMPLEMENTED(); 1364 UNIMPLEMENTED();
1142 return NULL; 1365 return NULL;
1143 } 1366 }
1144 1367
1145 byte* JavaScriptFrame::GetCallerStackPointer() const { 1368 byte* JavaScriptFrame::GetCallerStackPointer() const {
1146 UNIMPLEMENTED(); 1369 UNIMPLEMENTED();
1147 return NULL; 1370 return NULL;
1148 } 1371 }
1149 1372
1150 } } // namespace v8::internal 1373 } } // 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