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

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

Issue 911623003: MIPS: Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove comment. Created 5 years, 10 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
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/constants-mips.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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 Instr instr = instr_at(pos); 666 Instr instr = instr_at(pos);
667 if ((instr & ~kImm16Mask) == 0) { 667 if ((instr & ~kImm16Mask) == 0) {
668 // Emitted label constant, not part of a branch. 668 // Emitted label constant, not part of a branch.
669 if (instr == 0) { 669 if (instr == 0) {
670 return kEndOfChain; 670 return kEndOfChain;
671 } else { 671 } else {
672 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 672 int32_t imm18 =((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
673 return (imm18 + pos); 673 return (imm18 + pos);
674 } 674 }
675 } 675 }
676 // Check we have a branch or jump instruction.
677 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
678 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming 676 // Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
679 // the compiler uses arithmectic shifts for signed integers. 677 // the compiler uses arithmectic shifts for signed integers.
680 if (IsBranch(instr)) { 678 if (IsBranch(instr)) {
681 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14; 679 int32_t imm18 = ((instr & static_cast<int32_t>(kImm16Mask)) << 16) >> 14;
682 680
683 if (imm18 == kEndOfChain) { 681 if (imm18 == kEndOfChain) {
684 // EndOfChain sentinel is returned directly, not relative to pc or pos. 682 // EndOfChain sentinel is returned directly, not relative to pc or pos.
685 return kEndOfChain; 683 return kEndOfChain;
686 } else { 684 } else {
687 return pos + kBranchPCOffset + imm18; 685 return pos + kBranchPCOffset + imm18;
688 } 686 }
689 } else if (IsLui(instr)) { 687 } else if (IsLui(instr)) {
690 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); 688 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
691 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); 689 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
692 DCHECK(IsOri(instr_ori)); 690 DCHECK(IsOri(instr_ori));
693 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 691 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
694 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); 692 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
695 693
696 if (imm == kEndOfJumpChain) { 694 if (imm == kEndOfJumpChain) {
697 // EndOfChain sentinel is returned directly, not relative to pc or pos. 695 // EndOfChain sentinel is returned directly, not relative to pc or pos.
698 return kEndOfChain; 696 return kEndOfChain;
699 } else { 697 } else {
700 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 698 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
701 int32_t delta = instr_address - imm; 699 int32_t delta = instr_address - imm;
702 DCHECK(pos > delta); 700 DCHECK(pos > delta);
703 return pos - delta; 701 return pos - delta;
704 } 702 }
705 } else { 703 } else if (IsJ(instr)) {
706 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 704 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
707 if (imm28 == kEndOfJumpChain) { 705 if (imm28 == kEndOfJumpChain) {
708 // EndOfChain sentinel is returned directly, not relative to pc or pos. 706 // EndOfChain sentinel is returned directly, not relative to pc or pos.
709 return kEndOfChain; 707 return kEndOfChain;
710 } else { 708 } else {
711 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos); 709 uint32_t instr_address = reinterpret_cast<int32_t>(buffer_ + pos);
712 instr_address &= kImm28Mask; 710 instr_address &= kImm28Mask;
713 int32_t delta = instr_address - imm28; 711 int32_t delta = instr_address - imm28;
714 DCHECK(pos > delta); 712 DCHECK(pos > delta);
715 return pos - delta; 713 return pos - delta;
716 } 714 }
715 } else { // IsLabel(instr)
716 int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
717 if (imm28 == kEndOfJumpChain) {
718 // EndOfChain sentinel is returned directly, not relative to pc or pos.
719 return kEndOfChain;
720 } else {
721 return pos + imm28;
722 }
717 } 723 }
718 } 724 }
719 725
720 726
721 void Assembler::target_at_put(int32_t pos, int32_t target_pos) { 727 void Assembler::target_at_put(int32_t pos, int32_t target_pos) {
722 Instr instr = instr_at(pos); 728 Instr instr = instr_at(pos);
723 if ((instr & ~kImm16Mask) == 0) { 729 if ((instr & ~kImm16Mask) == 0) {
724 DCHECK(target_pos == kEndOfChain || target_pos >= 0); 730 DCHECK(target_pos == kEndOfChain || target_pos >= 0);
725 // Emitted label constant, not part of a branch. 731 // Emitted label constant, not part of a branch.
726 // Make label relative to Code* of generated Code object. 732 // Make label relative to Code* of generated Code object.
727 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag)); 733 instr_at_put(pos, target_pos + (Code::kHeaderSize - kHeapObjectTag));
728 return; 734 return;
729 } 735 }
730 736
731 DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
732 if (IsBranch(instr)) { 737 if (IsBranch(instr)) {
733 int32_t imm18 = target_pos - (pos + kBranchPCOffset); 738 int32_t imm18 = target_pos - (pos + kBranchPCOffset);
734 DCHECK((imm18 & 3) == 0); 739 DCHECK((imm18 & 3) == 0);
735 740
736 instr &= ~kImm16Mask; 741 instr &= ~kImm16Mask;
737 int32_t imm16 = imm18 >> 2; 742 int32_t imm16 = imm18 >> 2;
738 DCHECK(is_int16(imm16)); 743 DCHECK(is_int16(imm16));
739 744
740 instr_at_put(pos, instr | (imm16 & kImm16Mask)); 745 instr_at_put(pos, instr | (imm16 & kImm16Mask));
741 } else if (IsLui(instr)) { 746 } else if (IsLui(instr)) {
742 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize); 747 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
743 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize); 748 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
744 DCHECK(IsOri(instr_ori)); 749 DCHECK(IsOri(instr_ori));
745 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos; 750 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
746 DCHECK((imm & 3) == 0); 751 DCHECK((imm & 3) == 0);
747 752
748 instr_lui &= ~kImm16Mask; 753 instr_lui &= ~kImm16Mask;
749 instr_ori &= ~kImm16Mask; 754 instr_ori &= ~kImm16Mask;
750 755
751 instr_at_put(pos + 0 * Assembler::kInstrSize, 756 instr_at_put(pos + 0 * Assembler::kInstrSize,
752 instr_lui | ((imm & kHiMask) >> kLuiShift)); 757 instr_lui | ((imm & kHiMask) >> kLuiShift));
753 instr_at_put(pos + 1 * Assembler::kInstrSize, 758 instr_at_put(pos + 1 * Assembler::kInstrSize,
754 instr_ori | (imm & kImm16Mask)); 759 instr_ori | (imm & kImm16Mask));
755 } else { 760 } else if (IsJ(instr)) {
756 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos; 761 uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos;
757 imm28 &= kImm28Mask; 762 imm28 &= kImm28Mask;
758 DCHECK((imm28 & 3) == 0); 763 DCHECK((imm28 & 3) == 0);
759 764
760 instr &= ~kImm26Mask; 765 instr &= ~kImm26Mask;
761 uint32_t imm26 = imm28 >> 2; 766 uint32_t imm26 = imm28 >> 2;
762 DCHECK(is_uint26(imm26)); 767 DCHECK(is_uint26(imm26));
763 768
764 instr_at_put(pos, instr | (imm26 & kImm26Mask)); 769 instr_at_put(pos, instr | (imm26 & kImm26Mask));
770 } else {
771 uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
772 instr_at_put(pos, imm);
765 } 773 }
766 } 774 }
767 775
768 776
769 void Assembler::print(Label* L) { 777 void Assembler::print(Label* L) {
770 if (L->is_unused()) { 778 if (L->is_unused()) {
771 PrintF("unused label\n"); 779 PrintF("unused label\n");
772 } else if (L->is_bound()) { 780 } else if (L->is_bound()) {
773 PrintF("bound label to %d\n", L->pos()); 781 PrintF("bound label to %d\n", L->pos());
774 } else if (L->is_linked()) { 782 } else if (L->is_linked()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 trampoline_pos = get_trampoline_entry(fixup_pos); 817 trampoline_pos = get_trampoline_entry(fixup_pos);
810 CHECK(trampoline_pos != kInvalidSlotPos); 818 CHECK(trampoline_pos != kInvalidSlotPos);
811 } 819 }
812 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset); 820 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
813 target_at_put(fixup_pos, trampoline_pos); 821 target_at_put(fixup_pos, trampoline_pos);
814 fixup_pos = trampoline_pos; 822 fixup_pos = trampoline_pos;
815 dist = pos - fixup_pos; 823 dist = pos - fixup_pos;
816 } 824 }
817 target_at_put(fixup_pos, pos); 825 target_at_put(fixup_pos, pos);
818 } else { 826 } else {
819 DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
820 target_at_put(fixup_pos, pos); 827 target_at_put(fixup_pos, pos);
821 } 828 }
822 } 829 }
823 L->bind_to(pos); 830 L->bind_to(pos);
824 831
825 // Keep track of the last bound label so we don't eliminate any instructions 832 // Keep track of the last bound label so we don't eliminate any instructions
826 // before a bound label. 833 // before a bound label.
827 if (pos > last_bound_pos_) 834 if (pos > last_bound_pos_)
828 last_bound_pos_ = pos; 835 last_bound_pos_ = pos;
829 } 836 }
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after
2351 if (FLAG_trace_deopt) { 2358 if (FLAG_trace_deopt) {
2352 EnsureSpace ensure_space(this); 2359 EnsureSpace ensure_space(this);
2353 RecordRelocInfo(RelocInfo::POSITION, raw_position); 2360 RecordRelocInfo(RelocInfo::POSITION, raw_position);
2354 RecordRelocInfo(RelocInfo::DEOPT_REASON, reason); 2361 RecordRelocInfo(RelocInfo::DEOPT_REASON, reason);
2355 } 2362 }
2356 } 2363 }
2357 2364
2358 2365
2359 int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) { 2366 int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
2360 Instr instr = instr_at(pc); 2367 Instr instr = instr_at(pc);
2361 DCHECK(IsJ(instr) || IsLui(instr));
2362 if (IsLui(instr)) { 2368 if (IsLui(instr)) {
2363 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize); 2369 Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
2364 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize); 2370 Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
2365 DCHECK(IsOri(instr_ori)); 2371 DCHECK(IsOri(instr_ori));
2366 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift; 2372 int32_t imm = (instr_lui & static_cast<int32_t>(kImm16Mask)) << kLuiShift;
2367 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask)); 2373 imm |= (instr_ori & static_cast<int32_t>(kImm16Mask));
2368 if (imm == kEndOfJumpChain) { 2374 if (imm == kEndOfJumpChain) {
2369 return 0; // Number of instructions patched. 2375 return 0; // Number of instructions patched.
2370 } 2376 }
2371 imm += pc_delta; 2377 imm += pc_delta;
2372 DCHECK((imm & 3) == 0); 2378 DCHECK((imm & 3) == 0);
2373 2379
2374 instr_lui &= ~kImm16Mask; 2380 instr_lui &= ~kImm16Mask;
2375 instr_ori &= ~kImm16Mask; 2381 instr_ori &= ~kImm16Mask;
2376 2382
2377 instr_at_put(pc + 0 * Assembler::kInstrSize, 2383 instr_at_put(pc + 0 * Assembler::kInstrSize,
2378 instr_lui | ((imm >> kLuiShift) & kImm16Mask)); 2384 instr_lui | ((imm >> kLuiShift) & kImm16Mask));
2379 instr_at_put(pc + 1 * Assembler::kInstrSize, 2385 instr_at_put(pc + 1 * Assembler::kInstrSize,
2380 instr_ori | (imm & kImm16Mask)); 2386 instr_ori | (imm & kImm16Mask));
2381 return 2; // Number of instructions patched. 2387 return 2; // Number of instructions patched.
2382 } else { 2388 } else if (IsJ(instr)) {
2383 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2; 2389 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2384 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) { 2390 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2385 return 0; // Number of instructions patched. 2391 return 0; // Number of instructions patched.
2386 } 2392 }
2387 imm28 += pc_delta; 2393 imm28 += pc_delta;
2388 imm28 &= kImm28Mask; 2394 imm28 &= kImm28Mask;
2389 DCHECK((imm28 & 3) == 0); 2395 DCHECK((imm28 & 3) == 0);
2390 2396
2391 instr &= ~kImm26Mask; 2397 instr &= ~kImm26Mask;
2392 uint32_t imm26 = imm28 >> 2; 2398 uint32_t imm26 = imm28 >> 2;
2393 DCHECK(is_uint26(imm26)); 2399 DCHECK(is_uint26(imm26));
2394 2400
2395 instr_at_put(pc, instr | (imm26 & kImm26Mask)); 2401 instr_at_put(pc, instr | (imm26 & kImm26Mask));
2396 return 1; // Number of instructions patched. 2402 return 1; // Number of instructions patched.
2403 } else { // IsLabel(instr)
2404 int32_t* p = reinterpret_cast<int32_t*>(pc);
2405 uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
2406 if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2407 return 0; // Number of instructions patched.
2408 }
2409 *p += pc_delta;
2410 return 1; // Number of instructions patched.
2397 } 2411 }
2398 } 2412 }
2399 2413
2400 2414
2401 void Assembler::GrowBuffer() { 2415 void Assembler::GrowBuffer() {
2402 if (!own_buffer_) FATAL("external code buffer is too small"); 2416 if (!own_buffer_) FATAL("external code buffer is too small");
2403 2417
2404 // Compute new buffer size. 2418 // Compute new buffer size.
2405 CodeDesc desc; // The new buffer. 2419 CodeDesc desc; // The new buffer.
2406 if (buffer_size_ < 1 * MB) { 2420 if (buffer_size_ < 1 * MB) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 } 2465 }
2452 2466
2453 2467
2454 void Assembler::dd(uint32_t data) { 2468 void Assembler::dd(uint32_t data) {
2455 CheckBuffer(); 2469 CheckBuffer();
2456 *reinterpret_cast<uint32_t*>(pc_) = data; 2470 *reinterpret_cast<uint32_t*>(pc_) = data;
2457 pc_ += sizeof(uint32_t); 2471 pc_ += sizeof(uint32_t);
2458 } 2472 }
2459 2473
2460 2474
2475 void Assembler::dd(Label* label) {
2476 CheckBuffer();
2477 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2478 if (label->is_bound()) {
2479 uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos());
2480 *reinterpret_cast<uint32_t*>(pc_) = data;
2481 pc_ += sizeof(uint32_t);
2482 } else {
2483 int target_pos;
2484 if (label->is_linked()) {
2485 // Point to previous instruction that uses the link.
2486 target_pos = label->pos();
2487 } else {
2488 // First entry of the link chain points to itself.
2489 target_pos = pc_offset();
2490 }
2491 label->link_to(pc_offset());
2492 // Encode internal reference to unbound label. We set the least significant
2493 // bit to distinguish unbound internal references in GrowBuffer() below.
2494 int diff = target_pos - pc_offset();
2495 DCHECK_EQ(0, diff & 3);
2496 int imm26 = diff >> 2;
2497 DCHECK(is_int26(imm26));
2498 // Emit special LABEL instruction.
2499 emit(LABEL | (imm26 & kImm26Mask));
2500 }
2501 }
2502
2503
2461 void Assembler::emit_code_stub_address(Code* stub) { 2504 void Assembler::emit_code_stub_address(Code* stub) {
2462 CheckBuffer(); 2505 CheckBuffer();
2463 *reinterpret_cast<uint32_t*>(pc_) = 2506 *reinterpret_cast<uint32_t*>(pc_) =
2464 reinterpret_cast<uint32_t>(stub->instruction_start()); 2507 reinterpret_cast<uint32_t>(stub->instruction_start());
2465 pc_ += sizeof(uint32_t); 2508 pc_ += sizeof(uint32_t);
2466 } 2509 }
2467 2510
2468 2511
2469 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2512 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2470 // We do not try to reuse pool constants. 2513 // We do not try to reuse pool constants.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2749 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) { 2792 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2750 // No out-of-line constant pool support. 2793 // No out-of-line constant pool support.
2751 DCHECK(!FLAG_enable_ool_constant_pool); 2794 DCHECK(!FLAG_enable_ool_constant_pool);
2752 return; 2795 return;
2753 } 2796 }
2754 2797
2755 2798
2756 } } // namespace v8::internal 2799 } } // namespace v8::internal
2757 2800
2758 #endif // V8_TARGET_ARCH_MIPS 2801 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698