Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); | 364 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); |
| 365 num_prinfo_ = 0; | 365 num_prinfo_ = 0; |
| 366 next_buffer_check_ = 0; | 366 next_buffer_check_ = 0; |
| 367 no_const_pool_before_ = 0; | 367 no_const_pool_before_ = 0; |
| 368 last_const_pool_end_ = 0; | 368 last_const_pool_end_ = 0; |
| 369 last_bound_pos_ = 0; | 369 last_bound_pos_ = 0; |
| 370 current_statement_position_ = RelocInfo::kNoPosition; | 370 current_statement_position_ = RelocInfo::kNoPosition; |
| 371 current_position_ = RelocInfo::kNoPosition; | 371 current_position_ = RelocInfo::kNoPosition; |
| 372 written_statement_position_ = current_statement_position_; | 372 written_statement_position_ = current_statement_position_; |
| 373 written_position_ = current_position_; | 373 written_position_ = current_position_; |
| 374 thumb_mode_ = false; | |
| 374 } | 375 } |
| 375 | 376 |
| 376 | 377 |
| 377 Assembler::~Assembler() { | 378 Assembler::~Assembler() { |
| 378 if (own_buffer_) { | 379 if (own_buffer_) { |
| 379 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { | 380 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { |
| 380 spare_buffer_ = buffer_; | 381 spare_buffer_ = buffer_; |
| 381 } else { | 382 } else { |
| 382 DeleteArray(buffer_); | 383 DeleteArray(buffer_); |
| 383 } | 384 } |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 // L is empty, simply use appendix | 553 // L is empty, simply use appendix |
| 553 *L = *appendix; | 554 *L = *appendix; |
| 554 } | 555 } |
| 555 } | 556 } |
| 556 appendix->Unuse(); // appendix should not be used anymore | 557 appendix->Unuse(); // appendix should not be used anymore |
| 557 } | 558 } |
| 558 | 559 |
| 559 | 560 |
| 560 void Assembler::bind(Label* L) { | 561 void Assembler::bind(Label* L) { |
| 561 ASSERT(!L->is_bound()); // label can only be bound once | 562 ASSERT(!L->is_bound()); // label can only be bound once |
| 563 if (thumb_mode_) | |
|
Erik Corry
2009/12/17 14:05:50
I think we should assert here that we are not in a
| |
| 564 forceArmMode(); | |
| 562 bind_to(L, pc_offset()); | 565 bind_to(L, pc_offset()); |
| 563 } | 566 } |
| 564 | 567 |
| 565 | 568 |
| 566 void Assembler::next(Label* L) { | 569 void Assembler::next(Label* L) { |
| 567 ASSERT(L->is_linked()); | 570 ASSERT(L->is_linked()); |
| 568 int link = target_at(L->pos()); | 571 int link = target_at(L->pos()); |
| 569 if (link > 0) { | 572 if (link > 0) { |
| 570 L->link_to(link); | 573 L->link_to(link); |
| 571 } else { | 574 } else { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 609 #ifdef DEBUG | 612 #ifdef DEBUG |
| 610 if (!Serializer::enabled()) { | 613 if (!Serializer::enabled()) { |
| 611 Serializer::TooLateToEnableNow(); | 614 Serializer::TooLateToEnableNow(); |
| 612 } | 615 } |
| 613 #endif | 616 #endif |
| 614 return Serializer::enabled(); | 617 return Serializer::enabled(); |
| 615 } else if (rmode == RelocInfo::NONE) { | 618 } else if (rmode == RelocInfo::NONE) { |
| 616 return false; | 619 return false; |
| 617 } | 620 } |
| 618 return true; | 621 return true; |
| 619 } | 622 } |
|
Erik Corry
2009/12/17 14:05:50
Double blank lines between functions.
| |
| 620 | 623 |
| 624 void Assembler::forceThumbMode() { | |
|
Erik Corry
2009/12/17 14:05:50
Google style is to use CaptializedCamelCase for fu
| |
| 625 if (thumb_mode_) | |
| 626 return; | |
|
Erik Corry
2009/12/17 14:05:50
Multiline if.
| |
| 627 // PC is at the current instruction + 8 bytes in ARM mode, so we | |
| 628 // need to subtract 3 to get the next thumb instruction and enter | |
| 629 // thumb mode. We encoder this by hand, because the sub() | |
|
Erik Corry
2009/12/17 14:05:50
encoder -> encode
sub() -> sub
| |
| 630 // instruction should thumb | |
|
Erik Corry
2009/12/17 14:05:50
its nose?
| |
| 631 ASSERT((pc_offset() & 1) == 0); | |
| 632 emit(al | B25 | B22 | pc.code() * B16 | pc.code() * B12 | 3); | |
| 633 thumb_mode_ = true; | |
| 634 // The thumb instructions follow at once with no padding | |
|
Erik Corry
2009/12/17 14:05:50
Please use full stops at the end of comments.
| |
| 635 ASSERT((pc_offset() & 1) == 0); | |
| 636 } | |
| 637 | |
| 638 void Assembler::forceArmMode() { | |
|
Erik Corry
2009/12/17 14:05:50
CamelCase.
| |
| 639 if (!thumb_mode_) | |
|
Erik Corry
2009/12/17 14:05:50
Multiline if.
| |
| 640 return; | |
| 641 // PC is 4 bytes ahead of the current instruction, and the instruction | |
|
Erik Corry
2009/12/17 14:05:50
4 or 8?
| |
| 642 // we emit will always be 4 bytes. | |
| 643 ASSERT((pc_offset() & 1) == 0); | |
| 644 if (pc_offset() & 2) { | |
| 645 // ADD pc, pc, #1 | |
| 646 emitThumb(16*B12| 8 * B5 | pc.code()); | |
| 647 emitThumb(pc.code() * B8 | 1); | |
| 648 pc_ += 2; // Padding | |
| 649 } else { | |
| 650 // SUB pc, pc, #1 | |
| 651 emitThumb(16*B12| 13 * B5 | pc.code()); | |
| 652 emitThumb(pc.code() * B8 | 1); | |
| 653 } | |
| 654 thumb_mode_ = false; | |
| 655 ASSERT((pc_offset() & 3) == 0); | |
| 656 } | |
| 621 | 657 |
| 622 void Assembler::addrmod1(Instr instr, | 658 void Assembler::addrmod1(Instr instr, |
| 623 Register rn, | 659 Register rn, |
| 624 Register rd, | 660 Register rd, |
| 625 const Operand& x) { | 661 const Operand& x) { |
| 626 CheckBuffer(); | 662 CheckBuffer(); |
| 627 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); | 663 ASSERT((instr & ~(CondMask | OpCodeMask | S)) == 0); |
| 628 if (!x.rm_.is_valid()) { | 664 if (!x.rm_.is_valid()) { |
| 629 // immediate | 665 // immediate |
| 630 uint32_t rotate_imm; | 666 uint32_t rotate_imm; |
| 631 uint32_t immed_8; | 667 uint32_t immed_8; |
| 632 if (MustUseIp(x.rmode_) || | 668 if (MustUseIp(x.rmode_) || |
| 633 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { | 669 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { |
| 634 // The immediate operand cannot be encoded as a shifter operand, so load | 670 // The immediate operand cannot be encoded as a shifter operand, so load |
| 635 // it first to register ip and change the original instruction to use ip. | 671 // it first to register ip and change the original instruction to use ip. |
| 636 // However, if the original instruction is a 'mov rd, x' (not setting the | 672 // However, if the original instruction is a 'mov rd, x' (not setting the |
| 637 // condition code), then replace it with a 'ldr rd, [pc]' | 673 // condition code), then replace it with a 'ldr rd, [pc]' |
| 674 forceArmMode(); | |
|
Erik Corry
2009/12/17 14:05:50
Why do we need this here. It deserves a comment e
| |
| 638 RecordRelocInfo(x.rmode_, x.imm32_); | 675 RecordRelocInfo(x.rmode_, x.imm32_); |
| 639 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed | 676 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed |
| 640 Condition cond = static_cast<Condition>(instr & CondMask); | 677 Condition cond = static_cast<Condition>(instr & CondMask); |
| 641 if ((instr & ~CondMask) == 13*B21) { // mov, S not set | 678 if ((instr & ~CondMask) == 13*B21) { // mov, S not set |
| 642 ldr(rd, MemOperand(pc, 0), cond); | 679 ldr(rd, MemOperand(pc, 0), cond); |
| 643 } else { | 680 } else { |
| 644 ldr(ip, MemOperand(pc, 0), cond); | 681 ldr(ip, MemOperand(pc, 0), cond); |
| 645 addrmod1(instr, rn, rd, Operand(ip)); | 682 addrmod1(instr, rn, rd, Operand(ip)); |
| 646 } | 683 } |
| 647 return; | 684 return; |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 | 894 |
| 858 | 895 |
| 859 void Assembler::eor(Register dst, Register src1, const Operand& src2, | 896 void Assembler::eor(Register dst, Register src1, const Operand& src2, |
| 860 SBit s, Condition cond) { | 897 SBit s, Condition cond) { |
| 861 addrmod1(cond | 1*B21 | s, src1, dst, src2); | 898 addrmod1(cond | 1*B21 | s, src1, dst, src2); |
| 862 } | 899 } |
| 863 | 900 |
| 864 | 901 |
| 865 void Assembler::sub(Register dst, Register src1, const Operand& src2, | 902 void Assembler::sub(Register dst, Register src1, const Operand& src2, |
| 866 SBit s, Condition cond) { | 903 SBit s, Condition cond) { |
| 904 // For testing purposes, a gratuitous diversion into thumb | |
|
Erik Corry
2009/12/17 14:05:50
This isn't for testing, this is for real!
(But you
| |
| 905 if (no_const_pool_before_ < pc_offset()) | |
| 906 forceThumbMode(); | |
| 867 addrmod1(cond | 2*B21 | s, src1, dst, src2); | 907 addrmod1(cond | 2*B21 | s, src1, dst, src2); |
| 868 } | 908 } |
| 869 | 909 |
| 870 | 910 |
| 871 void Assembler::rsb(Register dst, Register src1, const Operand& src2, | 911 void Assembler::rsb(Register dst, Register src1, const Operand& src2, |
| 872 SBit s, Condition cond) { | 912 SBit s, Condition cond) { |
| 873 addrmod1(cond | 3*B21 | s, src1, dst, src2); | 913 addrmod1(cond | 3*B21 | s, src1, dst, src2); |
| 874 } | 914 } |
| 875 | 915 |
| 876 | 916 |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1812 bind(&after_pool); | 1852 bind(&after_pool); |
| 1813 } | 1853 } |
| 1814 | 1854 |
| 1815 // Since a constant pool was just emitted, move the check offset forward by | 1855 // Since a constant pool was just emitted, move the check offset forward by |
| 1816 // the standard interval. | 1856 // the standard interval. |
| 1817 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 1857 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
| 1818 } | 1858 } |
| 1819 | 1859 |
| 1820 | 1860 |
| 1821 } } // namespace v8::internal | 1861 } } // namespace v8::internal |
| OLD | NEW |