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

Side by Side Diff: runtime/vm/assembler_mips.h

Issue 13483018: Introduces a second temporary register for MIPS assembler macros. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 | « no previous file | runtime/vm/assembler_mips.cc » ('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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_MIPS_H_ 5 #ifndef VM_ASSEMBLER_MIPS_H_
6 #define VM_ASSEMBLER_MIPS_H_ 6 #define VM_ASSEMBLER_MIPS_H_
7 7
8 #ifndef VM_ASSEMBLER_H_ 8 #ifndef VM_ASSEMBLER_H_
9 #error Do not include assembler_mips.h directly; use assembler.h instead. 9 #error Do not include assembler_mips.h directly; use assembler.h instead.
10 #endif 10 #endif
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 Address(const Address& other) 52 Address(const Address& other)
53 : ValueObject(), base_(other.base_), offset_(other.offset_) { } 53 : ValueObject(), base_(other.base_), offset_(other.offset_) { }
54 Address& operator=(const Address& other) { 54 Address& operator=(const Address& other) {
55 base_ = other.base_; 55 base_ = other.base_;
56 offset_ = other.offset_; 56 offset_ = other.offset_;
57 return *this; 57 return *this;
58 } 58 }
59 59
60 uint32_t encoding() const { 60 uint32_t encoding() const {
61 ASSERT(Utils::IsInt(16, offset_)); 61 ASSERT(Utils::IsInt(kImmBits, offset_));
62 uint16_t imm_value = static_cast<uint16_t>(offset_); 62 uint16_t imm_value = static_cast<uint16_t>(offset_);
63 return (base_ << kRsShift) | imm_value; 63 return (base_ << kRsShift) | imm_value;
64 } 64 }
65 65
66 static bool CanHoldOffset(int32_t offset) { 66 static bool CanHoldOffset(int32_t offset) {
67 return Utils::IsInt(16, offset); 67 return Utils::IsInt(kImmBits, offset);
68 } 68 }
69 69
70 private: 70 private:
71 Register base_; 71 Register base_;
72 int32_t offset_; 72 int32_t offset_;
73 }; 73 };
74 74
75 75
76 class FieldAddress : public Address { 76 class FieldAddress : public Address {
77 public: 77 public:
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) == 217 ASSERT(buffer_.Load<int32_t>(buffer_.GetPosition() - sizeof(int32_t)) ==
218 Instr::kNopInstruction); 218 Instr::kNopInstruction);
219 buffer_.Remit<int32_t>(); 219 buffer_.Remit<int32_t>();
220 delay_slot_available_ = false; 220 delay_slot_available_ = false;
221 in_delay_slot_ = true; 221 in_delay_slot_ = true;
222 return this; 222 return this;
223 } 223 }
224 224
225 // CPU instructions in alphabetical order. 225 // CPU instructions in alphabetical order.
226 void addiu(Register rt, Register rs, const Immediate& imm) { 226 void addiu(Register rt, Register rs, const Immediate& imm) {
227 ASSERT(Utils::IsInt(16, imm.value())); 227 ASSERT(Utils::IsInt(kImmBits, imm.value()));
228 const uint16_t imm_value = static_cast<uint16_t>(imm.value()); 228 const uint16_t imm_value = static_cast<uint16_t>(imm.value());
229 EmitIType(ADDIU, rs, rt, imm_value); 229 EmitIType(ADDIU, rs, rt, imm_value);
230 } 230 }
231 231
232 void addu(Register rd, Register rs, Register rt) { 232 void addu(Register rd, Register rs, Register rt) {
233 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); 233 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
234 } 234 }
235 235
236 void and_(Register rd, Register rs, Register rt) { 236 void and_(Register rd, Register rs, Register rt) {
237 EmitRType(SPECIAL, rs, rt, rd, 0, AND); 237 EmitRType(SPECIAL, rs, rt, rd, 0, AND);
238 } 238 }
239 239
240 void andi(Register rt, Register rs, const Immediate& imm) { 240 void andi(Register rt, Register rs, const Immediate& imm) {
241 ASSERT(Utils::IsUint(16, imm.value())); 241 ASSERT(Utils::IsUint(kImmBits, imm.value()));
242 const uint16_t imm_value = static_cast<uint16_t>(imm.value()); 242 const uint16_t imm_value = static_cast<uint16_t>(imm.value());
243 EmitIType(ANDI, rs, rt, imm_value); 243 EmitIType(ANDI, rs, rt, imm_value);
244 } 244 }
245 245
246 // Unconditional branch. 246 // Unconditional branch.
247 void b(Label* l) { 247 void b(Label* l) {
248 beq(R0, R0, l); 248 beq(R0, R0, l);
249 } 249 }
250 250
251 void bal(Label *l) { 251 void bal(Label *l) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 390
391 void lh(Register rt, const Address& addr) { 391 void lh(Register rt, const Address& addr) {
392 EmitLoadStore(LH, rt, addr); 392 EmitLoadStore(LH, rt, addr);
393 } 393 }
394 394
395 void lhu(Register rt, const Address& addr) { 395 void lhu(Register rt, const Address& addr) {
396 EmitLoadStore(LHU, rt, addr); 396 EmitLoadStore(LHU, rt, addr);
397 } 397 }
398 398
399 void lui(Register rt, const Immediate& imm) { 399 void lui(Register rt, const Immediate& imm) {
400 ASSERT(Utils::IsUint(16, imm.value())); 400 ASSERT(Utils::IsUint(kImmBits, imm.value()));
401 uint16_t imm_value = static_cast<uint16_t>(imm.value()); 401 uint16_t imm_value = static_cast<uint16_t>(imm.value());
402 EmitIType(LUI, R0, rt, imm_value); 402 EmitIType(LUI, R0, rt, imm_value);
403 } 403 }
404 404
405 void lw(Register rt, const Address& addr) { 405 void lw(Register rt, const Address& addr) {
406 EmitLoadStore(LW, rt, addr); 406 EmitLoadStore(LW, rt, addr);
407 } 407 }
408 408
409 void mfhi(Register rd) { 409 void mfhi(Register rd) {
410 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); 410 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
(...skipping 29 matching lines...) Expand all
440 440
441 void nor(Register rd, Register rs, Register rt) { 441 void nor(Register rd, Register rs, Register rt) {
442 EmitRType(SPECIAL, rs, rt, rd, 0, NOR); 442 EmitRType(SPECIAL, rs, rt, rd, 0, NOR);
443 } 443 }
444 444
445 void or_(Register rd, Register rs, Register rt) { 445 void or_(Register rd, Register rs, Register rt) {
446 EmitRType(SPECIAL, rs, rt, rd, 0, OR); 446 EmitRType(SPECIAL, rs, rt, rd, 0, OR);
447 } 447 }
448 448
449 void ori(Register rt, Register rs, const Immediate& imm) { 449 void ori(Register rt, Register rs, const Immediate& imm) {
450 ASSERT(Utils::IsUint(16, imm.value())); 450 ASSERT(Utils::IsUint(kImmBits, imm.value()));
451 uint16_t imm_value = static_cast<uint16_t>(imm.value()); 451 uint16_t imm_value = static_cast<uint16_t>(imm.value());
452 EmitIType(ORI, rs, rt, imm_value); 452 EmitIType(ORI, rs, rt, imm_value);
453 } 453 }
454 454
455 void sb(Register rt, const Address& addr) { 455 void sb(Register rt, const Address& addr) {
456 EmitLoadStore(SB, rt, addr); 456 EmitLoadStore(SB, rt, addr);
457 } 457 }
458 458
459 void sh(Register rt, const Address& addr) { 459 void sh(Register rt, const Address& addr) {
460 EmitLoadStore(SH, rt, addr); 460 EmitLoadStore(SH, rt, addr);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 501 }
502 502
503 void xor_(Register rd, Register rs, Register rt) { 503 void xor_(Register rd, Register rs, Register rt) {
504 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); 504 EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
505 } 505 }
506 506
507 // Macros in alphabetical order. 507 // Macros in alphabetical order.
508 508
509 // Addition of rs and rt with the result placed in rd. 509 // Addition of rs and rt with the result placed in rd.
510 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. 510 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise.
511 // A scratch register is needed when rd, rs, and rt are the same 511 // rd and ro must not be TMP1 or TMP2.
512 // register. The scratch register may not be TMP.
513 // ro must be different from all the other registers. 512 // ro must be different from all the other registers.
514 void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro, 513 void AdduDetectOverflow(Register rd, Register rs, Register rt, Register ro);
515 Register scratch = kNoRegister); 514
515 // ro must be different from rd and rs.
516 // rd and ro must not be TMP1 or TMP2
517 void AddImmediateDetectOverflow(Register rd, Register rs, int32_t imm,
518 Register ro) {
519 LoadImmediate(rd, imm);
520 AdduDetectOverflow(rd, rs, rd, ro);
521 }
516 522
517 void Branch(const ExternalLabel* label) { 523 void Branch(const ExternalLabel* label) {
518 LoadImmediate(TMP, label->address()); 524 LoadImmediate(TMP1, label->address());
519 jr(TMP); 525 jr(TMP1);
520 } 526 }
521 527
522 void BranchPatchable(const ExternalLabel* label) { 528 void BranchPatchable(const ExternalLabel* label) {
523 const uint16_t low = Utils::Low16Bits(label->address()); 529 const uint16_t low = Utils::Low16Bits(label->address());
524 const uint16_t high = Utils::High16Bits(label->address()); 530 const uint16_t high = Utils::High16Bits(label->address());
525 lui(TMP, Immediate(high)); 531 lui(TMP1, Immediate(high));
526 ori(TMP, TMP, Immediate(low)); 532 ori(TMP1, TMP1, Immediate(low));
527 jr(TMP); 533 jr(TMP1);
528 delay_slot_available_ = false; // CodePatcher expects a nop. 534 delay_slot_available_ = false; // CodePatcher expects a nop.
529 } 535 }
530 536
531 void BranchLink(const ExternalLabel* label) { 537 void BranchLink(const ExternalLabel* label) {
532 LoadImmediate(TMP, label->address()); 538 LoadImmediate(TMP1, label->address());
533 jalr(TMP); 539 jalr(TMP1);
534 } 540 }
535 541
536 void BranchLinkPatchable(const ExternalLabel* label) { 542 void BranchLinkPatchable(const ExternalLabel* label) {
537 const int32_t offset = 543 const int32_t offset =
538 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; 544 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
539 LoadWordFromPoolOffset(TMP, offset); 545 LoadWordFromPoolOffset(TMP1, offset);
540 jalr(TMP); 546 jalr(TMP1);
541 delay_slot_available_ = false; // CodePatcher expects a nop. 547 delay_slot_available_ = false; // CodePatcher expects a nop.
542 } 548 }
543 549
544 // If the signed value in rs is less than value, rd is 1, and 0 otherwise.
545 void LessThanSImmediate(Register rd, Register rs, int32_t value) {
546 LoadImmediate(TMP, value);
547 slt(rd, rs, TMP);
548 }
549
550 // If the unsigned value in rs is less than value, rd is 1, and 0 otherwise.
551 void LessThanUImmediate(Register rd, Register rs, uint32_t value) {
552 LoadImmediate(TMP, value);
553 sltu(rd, rs, TMP);
554 }
555
556 void Drop(intptr_t stack_elements) { 550 void Drop(intptr_t stack_elements) {
557 ASSERT(stack_elements >= 0); 551 ASSERT(stack_elements >= 0);
558 if (stack_elements > 0) { 552 if (stack_elements > 0) {
559 addiu(SP, SP, Immediate(stack_elements * kWordSize)); 553 addiu(SP, SP, Immediate(stack_elements * kWordSize));
560 } 554 }
561 } 555 }
562 556
563 void LoadImmediate(Register rd, int32_t value) { 557 void LoadImmediate(Register rd, int32_t value) {
564 if (Utils::IsInt(16, value)) { 558 if (Utils::IsInt(kImmBits, value)) {
565 addiu(rd, ZR, Immediate(value)); 559 addiu(rd, ZR, Immediate(value));
566 } else { 560 } else {
567 const uint16_t low = Utils::Low16Bits(value); 561 const uint16_t low = Utils::Low16Bits(value);
568 const uint16_t high = Utils::High16Bits(value); 562 const uint16_t high = Utils::High16Bits(value);
569 lui(rd, Immediate(high)); 563 lui(rd, Immediate(high));
570 ori(rd, rd, Immediate(low)); 564 ori(rd, rd, Immediate(low));
571 } 565 }
572 } 566 }
573 567
568 void BranchEqual(Register rd, int32_t value, Label* l) {
569 LoadImmediate(TMP1, value);
570 beq(rd, TMP1, l);
571 }
572
573 void BranchEqual(Register rd, const Object& object, Label* l) {
574 LoadObject(TMP1, object);
575 beq(rd, TMP1, l);
576 }
577
578 void BranchNotEqual(Register rd, int32_t value, Label* l) {
579 LoadImmediate(TMP1, value);
580 bne(rd, TMP1, l);
581 }
582
583 void BranchNotEqual(Register rd, const Object& object, Label* l) {
584 LoadObject(TMP1, object);
585 bne(rd, TMP1, l);
586 }
587
588 void BranchGreater(Register rd, int32_t value, Label* l) {
589 if (Utils::IsInt(kImmBits, -value)) {
590 addiu(TMP1, rd, Immediate(-value));
591 bgtz(TMP1, l);
592 } else {
593 LoadImmediate(TMP1, value);
594 subu(TMP1, rd, TMP1);
595 bgtz(TMP1, l);
596 }
597 }
598
599 void BranchGreater(Register rd, Register rs, Label* l) {
600 subu(TMP1, rd, rs);
601 bgtz(TMP1, l);
602 }
603
604 void BranchGreaterEqual(Register rd, int32_t value, Label* l) {
605 if (Utils::IsInt(kImmBits, -value)) {
606 addiu(TMP1, rd, Immediate(-value));
607 bgez(TMP1, l);
608 } else {
609 LoadImmediate(TMP1, value);
610 subu(TMP1, rd, TMP1);
611 bgez(TMP1, l);
612 }
613 }
614
615 void BranchGreaterEqual(Register rd, Register rs, Label* l) {
616 subu(TMP1, rd, rs);
617 bgez(TMP1, l);
618 }
619
620 void BranchLess(Register rd, int32_t value, Label* l) {
621 if (Utils::IsInt(kImmBits, -value)) {
622 addiu(TMP1, rd, Immediate(-value));
623 bltz(TMP1, l);
624 } else {
625 LoadImmediate(TMP1, value);
626 subu(TMP1, rd, TMP1);
627 bltz(TMP1, l);
628 }
629 }
630
631 void BranchLess(Register rd, Register rs, Label* l) {
632 subu(TMP1, rd, rs);
633 bltz(TMP1, l);
634 }
635
636 void BranchLessEqual(Register rd, int32_t value, Label* l) {
637 if (Utils::IsInt(kImmBits, -value)) {
638 addiu(TMP1, rd, Immediate(-value));
639 blez(TMP1, l);
640 } else {
641 LoadImmediate(TMP1, value);
642 subu(TMP1, rd, TMP1);
643 blez(TMP1, l);
644 }
645 }
646
647 void BranchLessEqual(Register rd, Register rs, Label* l) {
648 subu(TMP1, rd, rs);
649 blez(TMP1, l);
650 }
651
574 void Push(Register rt) { 652 void Push(Register rt) {
575 addiu(SP, SP, Immediate(-kWordSize)); 653 addiu(SP, SP, Immediate(-kWordSize));
576 sw(rt, Address(SP)); 654 sw(rt, Address(SP));
577 } 655 }
578 656
579 void Pop(Register rt) { 657 void Pop(Register rt) {
580 lw(rt, Address(SP)); 658 lw(rt, Address(SP));
581 addiu(SP, SP, Immediate(kWordSize)); 659 addiu(SP, SP, Immediate(kWordSize));
582 } 660 }
583 661
(...skipping 14 matching lines...) Expand all
598 void LoadWordFromPoolOffset(Register rd, int32_t offset); 676 void LoadWordFromPoolOffset(Register rd, int32_t offset);
599 void LoadObject(Register rd, const Object& object); 677 void LoadObject(Register rd, const Object& object);
600 void PushObject(const Object& object); 678 void PushObject(const Object& object);
601 679
602 // Sets register rd to zero if the object is equal to register rn, 680 // Sets register rd to zero if the object is equal to register rn,
603 // set to non-zero otherwise. 681 // set to non-zero otherwise.
604 void CompareObject(Register rd, Register rn, const Object& object); 682 void CompareObject(Register rd, Register rn, const Object& object);
605 683
606 void LoadClassId(Register result, Register object); 684 void LoadClassId(Register result, Register object);
607 void LoadClassById(Register result, Register class_id); 685 void LoadClassById(Register result, Register class_id);
608 void LoadClass(Register result, Register object, Register scratch); 686 void LoadClass(Register result, Register object);
609 687
610 void CallRuntime(const RuntimeEntry& entry); 688 void CallRuntime(const RuntimeEntry& entry);
611 689
612 // Set up a Dart frame on entry with a frame pointer and PC information to 690 // Set up a Dart frame on entry with a frame pointer and PC information to
613 // enable easy access to the RawInstruction object of code corresponding 691 // enable easy access to the RawInstruction object of code corresponding
614 // to this frame. 692 // to this frame.
615 void EnterDartFrame(intptr_t frame_size); 693 void EnterDartFrame(intptr_t frame_size);
616 void LeaveDartFrame(); 694 void LeaveDartFrame();
617 695
618 private: 696 private:
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 delay_slot_available_ = true; 815 delay_slot_available_ = true;
738 } 816 }
739 817
740 DISALLOW_ALLOCATION(); 818 DISALLOW_ALLOCATION();
741 DISALLOW_COPY_AND_ASSIGN(Assembler); 819 DISALLOW_COPY_AND_ASSIGN(Assembler);
742 }; 820 };
743 821
744 } // namespace dart 822 } // namespace dart
745 823
746 #endif // VM_ASSEMBLER_MIPS_H_ 824 #endif // VM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698