| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ASSEMBLER_ARM64_H_ | 5 #ifndef VM_ASSEMBLER_ARM64_H_ |
| 6 #define VM_ASSEMBLER_ARM64_H_ | 6 #define VM_ASSEMBLER_ARM64_H_ |
| 7 | 7 |
| 8 #ifndef VM_ASSEMBLER_H_ | 8 #ifndef VM_ASSEMBLER_H_ |
| 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. | 9 #error Do not include assembler_arm64.h directly; use assembler.h instead. |
| 10 #endif | 10 #endif |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 friend class Assembler; | 319 friend class Assembler; |
| 320 }; | 320 }; |
| 321 | 321 |
| 322 | 322 |
| 323 class Assembler : public ValueObject { | 323 class Assembler : public ValueObject { |
| 324 public: | 324 public: |
| 325 explicit Assembler(bool use_far_branches = false); | 325 explicit Assembler(bool use_far_branches = false); |
| 326 ~Assembler() { } | 326 ~Assembler() { } |
| 327 | 327 |
| 328 void PopRegister(Register r) { | 328 void PopRegister(Register r) { |
| 329 UNIMPLEMENTED(); | 329 Pop(r); |
| 330 } | 330 } |
| 331 | 331 |
| 332 void Drop(intptr_t stack_elements) { | 332 void Drop(intptr_t stack_elements) { |
| 333 UNIMPLEMENTED(); | 333 add(SP, SP, Operand(stack_elements * kWordSize)); |
| 334 } | 334 } |
| 335 | 335 |
| 336 void Bind(Label* label); | 336 void Bind(Label* label); |
| 337 | 337 |
| 338 // Misc. functionality | 338 // Misc. functionality |
| 339 intptr_t CodeSize() const { return buffer_.Size(); } | 339 intptr_t CodeSize() const { return buffer_.Size(); } |
| 340 intptr_t prologue_offset() const { return prologue_offset_; } | 340 intptr_t prologue_offset() const { return prologue_offset_; } |
| 341 | 341 |
| 342 // Count the fixups that produce a pointer offset, without processing | 342 // Count the fixups that produce a pointer offset, without processing |
| 343 // the fixups. On ARM64 there are no pointers in code. | 343 // the fixups. On ARM64 there are no pointers in code. |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 545 void br(Register rn) { | 545 void br(Register rn) { |
| 546 EmitUnconditionalBranchRegOp(BR, rn); | 546 EmitUnconditionalBranchRegOp(BR, rn); |
| 547 } | 547 } |
| 548 void blr(Register rn) { | 548 void blr(Register rn) { |
| 549 EmitUnconditionalBranchRegOp(BLR, rn); | 549 EmitUnconditionalBranchRegOp(BLR, rn); |
| 550 } | 550 } |
| 551 void ret(Register rn = R30) { | 551 void ret(Register rn = R30) { |
| 552 EmitUnconditionalBranchRegOp(RET, rn); | 552 EmitUnconditionalBranchRegOp(RET, rn); |
| 553 } | 553 } |
| 554 | 554 |
| 555 // Exceptions. |
| 556 void hlt(uint16_t imm) { |
| 557 EmitExceptionGenOp(HLT, imm); |
| 558 } |
| 559 |
| 555 // Aliases. | 560 // Aliases. |
| 556 void mov(Register rd, Register rn) { | 561 void mov(Register rd, Register rn) { |
| 557 if ((rd == SP) || (rn == SP)) { | 562 if ((rd == SP) || (rn == SP)) { |
| 558 add(rd, rn, Operand(0)); | 563 add(rd, rn, Operand(0)); |
| 559 } else { | 564 } else { |
| 560 orr(rd, ZR, Operand(rn)); | 565 orr(rd, ZR, Operand(rn)); |
| 561 } | 566 } |
| 562 } | 567 } |
| 563 void mvn(Register rd, Register rm) { | 568 void mvn(Register rd, Register rm) { |
| 564 orr(rd, ZR, Operand(rm)); | 569 orr(rd, ZR, Operand(rm)); |
| 565 } | 570 } |
| 566 void neg(Register rd, Register rm) { | 571 void neg(Register rd, Register rm) { |
| 567 sub(rd, ZR, Operand(rm)); | 572 sub(rd, ZR, Operand(rm)); |
| 568 } | 573 } |
| 569 void negs(Register rd, Register rm) { | 574 void negs(Register rd, Register rm) { |
| 570 subs(rd, ZR, Operand(rm)); | 575 subs(rd, ZR, Operand(rm)); |
| 571 } | 576 } |
| 572 void mul(Register rd, Register rn, Register rm) { | 577 void mul(Register rd, Register rn, Register rm) { |
| 573 madd(rd, rn, rm, ZR); | 578 madd(rd, rn, rm, ZR); |
| 574 } | 579 } |
| 575 void Push(Register reg) { | 580 void Push(Register reg) { |
| 576 str(reg, Address(SP, -1 * kWordSize, Address::PreIndex)); | 581 str(reg, Address(SP, -1 * kWordSize, Address::PreIndex)); |
| 577 } | 582 } |
| 578 void Pop(Register reg) { | 583 void Pop(Register reg) { |
| 579 ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex)); | 584 ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex)); |
| 580 } | 585 } |
| 586 void tst(Register rn, Operand o) { |
| 587 ands(ZR, rn, o); |
| 588 } |
| 589 void tsti(Register rn, uint64_t imm) { |
| 590 andis(ZR, rn, imm); |
| 591 } |
| 581 | 592 |
| 582 // Object pool, loading from pool, etc. | 593 // Object pool, loading from pool, etc. |
| 583 void LoadPoolPointer(Register pp) { | 594 void LoadPoolPointer(Register pp) { |
| 584 const intptr_t object_pool_pc_dist = | 595 const intptr_t object_pool_pc_dist = |
| 585 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 596 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 586 CodeSize(); | 597 CodeSize(); |
| 587 // PP <- Read(PC - object_pool_pc_dist). | 598 // PP <- Read(PC - object_pool_pc_dist). |
| 588 ldr(pp, Address::PC(-object_pool_pc_dist)); | 599 ldr(pp, Address::PC(-object_pool_pc_dist)); |
| 589 } | 600 } |
| 590 | 601 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 label->LinkTo(position); | 816 label->LinkTo(position); |
| 806 } | 817 } |
| 807 } | 818 } |
| 808 | 819 |
| 809 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) { | 820 void EmitUnconditionalBranchRegOp(UnconditionalBranchRegOp op, Register rn) { |
| 810 const int32_t encoding = | 821 const int32_t encoding = |
| 811 op | (static_cast<int32_t>(rn) << kRnShift); | 822 op | (static_cast<int32_t>(rn) << kRnShift); |
| 812 Emit(encoding); | 823 Emit(encoding); |
| 813 } | 824 } |
| 814 | 825 |
| 826 void EmitExceptionGenOp(ExceptionGenOp op, uint16_t imm) { |
| 827 const int32_t encoding = |
| 828 op | (static_cast<int32_t>(imm) << kImm16Shift); |
| 829 Emit(encoding); |
| 830 } |
| 831 |
| 815 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, | 832 void EmitMoveWideOp(MoveWideOp op, Register rd, uint16_t imm, int hw_idx, |
| 816 OperandSize sz) { | 833 OperandSize sz) { |
| 817 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); | 834 ASSERT((hw_idx >= 0) && (hw_idx <= 3)); |
| 818 ASSERT((sz == kDoubleWord) || (sz == kWord)); | 835 ASSERT((sz == kDoubleWord) || (sz == kWord)); |
| 819 const int32_t size = (sz == kDoubleWord) ? B31 : 0; | 836 const int32_t size = (sz == kDoubleWord) ? B31 : 0; |
| 820 const int32_t encoding = | 837 const int32_t encoding = |
| 821 op | size | | 838 op | size | |
| 822 (static_cast<int32_t>(rd) << kRdShift) | | 839 (static_cast<int32_t>(rd) << kRdShift) | |
| 823 (static_cast<int32_t>(hw_idx) << kHWShift) | | 840 (static_cast<int32_t>(hw_idx) << kHWShift) | |
| 824 (static_cast<int32_t>(imm) << kImm16Shift); | 841 (static_cast<int32_t>(imm) << kImm16Shift); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 Emit(encoding); | 909 Emit(encoding); |
| 893 } | 910 } |
| 894 | 911 |
| 895 DISALLOW_ALLOCATION(); | 912 DISALLOW_ALLOCATION(); |
| 896 DISALLOW_COPY_AND_ASSIGN(Assembler); | 913 DISALLOW_COPY_AND_ASSIGN(Assembler); |
| 897 }; | 914 }; |
| 898 | 915 |
| 899 } // namespace dart | 916 } // namespace dart |
| 900 | 917 |
| 901 #endif // VM_ASSEMBLER_ARM64_H_ | 918 #endif // VM_ASSEMBLER_ARM64_H_ |
| OLD | NEW |