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

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

Issue 14206002: Adds some floating point instructions to MIPS simulator, assembler, disassembler. (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_test.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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 ASSERT(delay_slot_available_); 216 ASSERT(delay_slot_available_);
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 addd(FRegister fd, FRegister fs, FRegister ft) {
227 ASSERT(EvenFPURegister(fd));
228 ASSERT(EvenFPURegister(fs));
229 ASSERT(EvenFPURegister(ft));
230 EmitFpuRType(COP1, FMT_D, ft, fs, fd, COP1_ADD);
231 }
232
226 void addiu(Register rt, Register rs, const Immediate& imm) { 233 void addiu(Register rt, Register rs, const Immediate& imm) {
227 ASSERT(Utils::IsInt(kImmBits, imm.value())); 234 ASSERT(Utils::IsInt(kImmBits, imm.value()));
228 const uint16_t imm_value = static_cast<uint16_t>(imm.value()); 235 const uint16_t imm_value = static_cast<uint16_t>(imm.value());
229 EmitIType(ADDIU, rs, rt, imm_value); 236 EmitIType(ADDIU, rs, rt, imm_value);
230 } 237 }
231 238
239 void adds(FRegister fd, FRegister fs, FRegister ft) {
240 EmitFpuRType(COP1, FMT_S, ft, fs, fd, COP1_ADD);
241 }
242
232 void addu(Register rd, Register rs, Register rt) { 243 void addu(Register rd, Register rs, Register rt) {
233 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU); 244 EmitRType(SPECIAL, rs, rt, rd, 0, ADDU);
234 } 245 }
235 246
236 void and_(Register rd, Register rs, Register rt) { 247 void and_(Register rd, Register rs, Register rt) {
237 EmitRType(SPECIAL, rs, rt, rd, 0, AND); 248 EmitRType(SPECIAL, rs, rt, rd, 0, AND);
238 } 249 }
239 250
240 void andi(Register rt, Register rs, const Immediate& imm) { 251 void andi(Register rt, Register rs, const Immediate& imm) {
241 ASSERT(Utils::IsUint(kImmBits, imm.value())); 252 ASSERT(Utils::IsUint(kImmBits, imm.value()));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 392 }
382 393
383 void lb(Register rt, const Address& addr) { 394 void lb(Register rt, const Address& addr) {
384 EmitLoadStore(LB, rt, addr); 395 EmitLoadStore(LB, rt, addr);
385 } 396 }
386 397
387 void lbu(Register rt, const Address& addr) { 398 void lbu(Register rt, const Address& addr) {
388 EmitLoadStore(LBU, rt, addr); 399 EmitLoadStore(LBU, rt, addr);
389 } 400 }
390 401
402 void ldc1(FRegister ft, const Address& addr) {
403 ASSERT(EvenFPURegister(ft));
404 EmitFpuLoadStore(LDC1, ft, addr);
405 }
406
391 void lh(Register rt, const Address& addr) { 407 void lh(Register rt, const Address& addr) {
392 EmitLoadStore(LH, rt, addr); 408 EmitLoadStore(LH, rt, addr);
393 } 409 }
394 410
395 void lhu(Register rt, const Address& addr) { 411 void lhu(Register rt, const Address& addr) {
396 EmitLoadStore(LHU, rt, addr); 412 EmitLoadStore(LHU, rt, addr);
397 } 413 }
398 414
399 void lui(Register rt, const Immediate& imm) { 415 void lui(Register rt, const Immediate& imm) {
400 ASSERT(Utils::IsUint(kImmBits, imm.value())); 416 ASSERT(Utils::IsUint(kImmBits, imm.value()));
401 uint16_t imm_value = static_cast<uint16_t>(imm.value()); 417 uint16_t imm_value = static_cast<uint16_t>(imm.value());
402 EmitIType(LUI, R0, rt, imm_value); 418 EmitIType(LUI, R0, rt, imm_value);
403 } 419 }
404 420
405 void lw(Register rt, const Address& addr) { 421 void lw(Register rt, const Address& addr) {
406 EmitLoadStore(LW, rt, addr); 422 EmitLoadStore(LW, rt, addr);
407 } 423 }
408 424
425 void lwc1(FRegister ft, const Address& addr) {
426 EmitFpuLoadStore(LWC1, ft, addr);
427 }
428
429 void mfc1(Register rt, FRegister fs) {
430 Emit(COP1 << kOpcodeShift |
431 COP1_MF << kCop1SubShift |
432 rt << kRtShift |
433 fs << kFsShift);
434 }
435
409 void mfhi(Register rd) { 436 void mfhi(Register rd) {
410 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI); 437 EmitRType(SPECIAL, R0, R0, rd, 0, MFHI);
411 } 438 }
412 439
413 void mflo(Register rd) { 440 void mflo(Register rd) {
414 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO); 441 EmitRType(SPECIAL, R0, R0, rd, 0, MFLO);
415 } 442 }
416 443
417 void mov(Register rd, Register rs) { 444 void mov(Register rd, Register rs) {
418 or_(rd, rs, ZR); 445 or_(rd, rs, ZR);
419 } 446 }
420 447
448 void movd(FRegister fd, FRegister fs) {
449 ASSERT(EvenFPURegister(fd));
450 ASSERT(EvenFPURegister(fs));
451 EmitFpuRType(COP1, FMT_D, F0, fs, fd, COP1_MOV);
452 }
453
421 void movn(Register rd, Register rs, Register rt) { 454 void movn(Register rd, Register rs, Register rt) {
422 EmitRType(SPECIAL, rs, rt, rd, 0, MOVN); 455 EmitRType(SPECIAL, rs, rt, rd, 0, MOVN);
423 } 456 }
424 457
425 void movz(Register rd, Register rs, Register rt) { 458 void movz(Register rd, Register rs, Register rt) {
426 EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ); 459 EmitRType(SPECIAL, rs, rt, rd, 0, MOVZ);
427 } 460 }
428 461
462 void movs(FRegister fd, FRegister fs) {
463 EmitFpuRType(COP1, FMT_S, F0, fs, fd, COP1_MOV);
464 }
465
466 void mtc1(Register rt, FRegister fs) {
467 Emit(COP1 << kOpcodeShift |
468 COP1_MT << kCop1SubShift |
469 rt << kRtShift |
470 fs << kFsShift);
471 }
472
429 void mult(Register rs, Register rt) { 473 void mult(Register rs, Register rt) {
430 EmitRType(SPECIAL, rs, rt, R0, 0, MULT); 474 EmitRType(SPECIAL, rs, rt, R0, 0, MULT);
431 } 475 }
432 476
433 void multu(Register rs, Register rt) { 477 void multu(Register rs, Register rt) {
434 EmitRType(SPECIAL, rs, rt, R0, 0, MULTU); 478 EmitRType(SPECIAL, rs, rt, R0, 0, MULTU);
435 } 479 }
436 480
437 void nop() { 481 void nop() {
438 Emit(Instr::kNopInstruction); 482 Emit(Instr::kNopInstruction);
(...skipping 10 matching lines...) Expand all
449 void ori(Register rt, Register rs, const Immediate& imm) { 493 void ori(Register rt, Register rs, const Immediate& imm) {
450 ASSERT(Utils::IsUint(kImmBits, imm.value())); 494 ASSERT(Utils::IsUint(kImmBits, imm.value()));
451 uint16_t imm_value = static_cast<uint16_t>(imm.value()); 495 uint16_t imm_value = static_cast<uint16_t>(imm.value());
452 EmitIType(ORI, rs, rt, imm_value); 496 EmitIType(ORI, rs, rt, imm_value);
453 } 497 }
454 498
455 void sb(Register rt, const Address& addr) { 499 void sb(Register rt, const Address& addr) {
456 EmitLoadStore(SB, rt, addr); 500 EmitLoadStore(SB, rt, addr);
457 } 501 }
458 502
503 void sdc1(FRegister ft, const Address& addr) {
504 ASSERT(EvenFPURegister(ft));
505 EmitFpuLoadStore(SDC1, ft, addr);
506 }
507
459 void sh(Register rt, const Address& addr) { 508 void sh(Register rt, const Address& addr) {
460 EmitLoadStore(SH, rt, addr); 509 EmitLoadStore(SH, rt, addr);
461 } 510 }
462 511
463 void sll(Register rd, Register rt, int sa) { 512 void sll(Register rd, Register rt, int sa) {
464 EmitRType(SPECIAL, R0, rt, rd, sa, SLL); 513 EmitRType(SPECIAL, R0, rt, rd, sa, SLL);
465 } 514 }
466 515
467 void sllv(Register rd, Register rt, Register rs) { 516 void sllv(Register rd, Register rt, Register rs) {
468 EmitRType(SPECIAL, rs, rt, rd, 0, SLLV); 517 EmitRType(SPECIAL, rs, rt, rd, 0, SLLV);
(...skipping 24 matching lines...) Expand all
493 } 542 }
494 543
495 void subu(Register rd, Register rs, Register rt) { 544 void subu(Register rd, Register rs, Register rt) {
496 EmitRType(SPECIAL, rs, rt, rd, 0, SUBU); 545 EmitRType(SPECIAL, rs, rt, rd, 0, SUBU);
497 } 546 }
498 547
499 void sw(Register rt, const Address& addr) { 548 void sw(Register rt, const Address& addr) {
500 EmitLoadStore(SW, rt, addr); 549 EmitLoadStore(SW, rt, addr);
501 } 550 }
502 551
552 void swc1(FRegister ft, const Address& addr) {
553 EmitFpuLoadStore(SWC1, ft, addr);
554 }
555
503 void xor_(Register rd, Register rs, Register rt) { 556 void xor_(Register rd, Register rs, Register rt) {
504 EmitRType(SPECIAL, rs, rt, rd, 0, XOR); 557 EmitRType(SPECIAL, rs, rt, rd, 0, XOR);
505 } 558 }
506 559
507 // Macros in alphabetical order. 560 // Macros in alphabetical order.
508 561
509 // Addition of rs and rt with the result placed in rd. 562 // Addition of rs and rt with the result placed in rd.
510 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise. 563 // After, ro < 0 if there was signed overflow, ro >= 0 otherwise.
511 // rd and ro must not be TMP1 or TMP2. 564 // rd and ro must not be TMP1 or TMP2.
512 // ro must be different from all the other registers. 565 // ro must be different from all the other registers.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 if (Utils::IsInt(kImmBits, value)) { 611 if (Utils::IsInt(kImmBits, value)) {
559 addiu(rd, ZR, Immediate(value)); 612 addiu(rd, ZR, Immediate(value));
560 } else { 613 } else {
561 const uint16_t low = Utils::Low16Bits(value); 614 const uint16_t low = Utils::Low16Bits(value);
562 const uint16_t high = Utils::High16Bits(value); 615 const uint16_t high = Utils::High16Bits(value);
563 lui(rd, Immediate(high)); 616 lui(rd, Immediate(high));
564 ori(rd, rd, Immediate(low)); 617 ori(rd, rd, Immediate(low));
565 } 618 }
566 } 619 }
567 620
621 void LoadImmediate(FRegister rd, double value) {
622 ASSERT(EvenFPURegister(rd));
623 const int64_t ival = bit_cast<uint64_t, double>(value);
624 const int32_t low = Utils::Low32Bits(ival);
625 const int32_t high = Utils::High32Bits(ival);
626 if (low != 0) {
627 LoadImmediate(TMP1, low);
628 mtc1(TMP1, rd);
629 } else {
630 mtc1(ZR, rd);
631 }
632
633 if (high != 0) {
634 LoadImmediate(TMP1, high);
635 mtc1(TMP1, static_cast<FRegister>(rd + 1));
636 } else {
637 mtc1(ZR, static_cast<FRegister>(rd + 1));
638 }
639 }
640
641 void LoadImmediate(FRegister rd, float value) {
regis 2013/04/12 17:08:56 I am not sure we will need this one, since there i
zra 2013/04/12 17:19:26 I'll keep it for now since I use it in some tests,
642 const int32_t ival = bit_cast<int32_t, float>(value);
643 if (ival == 0) {
644 mtc1(ZR, rd);
645 } else {
646 LoadImmediate(TMP1, ival);
647 mtc1(TMP1, rd);
648 }
649 }
650
568 void AddImmediate(Register rd, Register rs, int32_t value) { 651 void AddImmediate(Register rd, Register rs, int32_t value) {
569 if (Utils::IsInt(kImmBits, value)) { 652 if (Utils::IsInt(kImmBits, value)) {
570 addiu(rd, rs, Immediate(value)); 653 addiu(rd, rs, Immediate(value));
571 } else { 654 } else {
572 LoadImmediate(TMP1, value); 655 LoadImmediate(TMP1, value);
573 addu(rd, rs, TMP1); 656 addu(rd, rs, TMP1);
574 } 657 }
575 } 658 }
576 659
577 void AddImmediate(Register rd, int32_t value) { 660 void AddImmediate(Register rd, int32_t value) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 810
728 private: 811 private:
729 intptr_t pc_offset_; 812 intptr_t pc_offset_;
730 const String& comment_; 813 const String& comment_;
731 814
732 DISALLOW_COPY_AND_ASSIGN(CodeComment); 815 DISALLOW_COPY_AND_ASSIGN(CodeComment);
733 }; 816 };
734 817
735 GrowableArray<CodeComment*> comments_; 818 GrowableArray<CodeComment*> comments_;
736 819
820 bool EvenFPURegister(FRegister reg) {
821 return (static_cast<int>(reg) & 1) == 0;
822 }
823
737 void Emit(int32_t value) { 824 void Emit(int32_t value) {
738 // Emitting an instruction clears the delay slot state. 825 // Emitting an instruction clears the delay slot state.
739 in_delay_slot_ = false; 826 in_delay_slot_ = false;
740 delay_slot_available_ = false; 827 delay_slot_available_ = false;
741 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 828 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
742 buffer_.Emit<int32_t>(value); 829 buffer_.Emit<int32_t>(value);
743 } 830 }
744 831
745 // Encode CPU instructions according to the types specified in 832 // Encode CPU instructions according to the types specified in
746 // Figures 4-1, 4-2 and 4-3 in VolI-A. 833 // Figures 4-1, 4-2 and 4-3 in VolI-A.
747 void EmitIType(Opcode opcode, 834 void EmitIType(Opcode opcode,
748 Register rs, 835 Register rs,
749 Register rt, 836 Register rt,
750 uint16_t imm) { 837 uint16_t imm) {
751 Emit(opcode << kOpcodeShift | 838 Emit(opcode << kOpcodeShift |
752 rs << kRsShift | 839 rs << kRsShift |
753 rt << kRtShift | 840 rt << kRtShift |
754 imm); 841 imm);
755 } 842 }
756 843
757 void EmitLoadStore(Opcode opcode, Register rt, 844 void EmitLoadStore(Opcode opcode, Register rt,
758 const Address &addr) { 845 const Address &addr) {
759 Emit(opcode << kOpcodeShift | 846 Emit(opcode << kOpcodeShift |
760 rt << kRtShift | 847 rt << kRtShift |
761 addr.encoding()); 848 addr.encoding());
762 } 849 }
763 850
851 void EmitFpuLoadStore(Opcode opcode, FRegister ft,
852 const Address &addr) {
853 Emit(opcode << kOpcodeShift |
854 ft << kFtShift |
855 addr.encoding());
856 }
857
764 void EmitRegImmType(Opcode opcode, 858 void EmitRegImmType(Opcode opcode,
765 Register rs, 859 Register rs,
766 RtRegImm code, 860 RtRegImm code,
767 uint16_t imm) { 861 uint16_t imm) {
768 Emit(opcode << kOpcodeShift | 862 Emit(opcode << kOpcodeShift |
769 rs << kRsShift | 863 rs << kRsShift |
770 code << kRtShift | 864 code << kRtShift |
771 imm); 865 imm);
772 } 866 }
773 867
774 void EmitJType(Opcode opcode, uint32_t destination) { 868 void EmitJType(Opcode opcode, uint32_t destination) {
775 UNIMPLEMENTED(); 869 UNIMPLEMENTED();
776 } 870 }
777 871
778 void EmitRType(Opcode opcode, 872 void EmitRType(Opcode opcode,
779 Register rs, 873 Register rs,
780 Register rt, 874 Register rt,
781 Register rd, 875 Register rd,
782 int sa, 876 int sa,
783 SpecialFunction func) { 877 SpecialFunction func) {
784 ASSERT(Utils::IsUint(5, sa)); 878 ASSERT(Utils::IsUint(5, sa));
785 Emit(opcode << kOpcodeShift | 879 Emit(opcode << kOpcodeShift |
786 rs << kRsShift | 880 rs << kRsShift |
787 rt << kRtShift | 881 rt << kRtShift |
788 rd << kRdShift | 882 rd << kRdShift |
789 sa << kSaShift | 883 sa << kSaShift |
790 func << kFunctionShift); 884 func << kFunctionShift);
791 } 885 }
792 886
887 void EmitFpuRType(Opcode opcode,
888 Format fmt,
889 FRegister ft,
890 FRegister fs,
891 FRegister fd,
892 Cop1Function func) {
893 Emit(opcode << kOpcodeShift |
894 fmt << kFmtShift |
895 ft << kFtShift |
896 fs << kFsShift |
897 fd << kFdShift |
898 func << kCop1FnShift);
899 }
900
793 void EmitBranch(Opcode b, Register rs, Register rt, Label* label) { 901 void EmitBranch(Opcode b, Register rs, Register rt, Label* label) {
794 if (label->IsBound()) { 902 if (label->IsBound()) {
795 // Relative destination from an instruction after the branch. 903 // Relative destination from an instruction after the branch.
796 const int32_t dest = 904 const int32_t dest =
797 label->Position() - (buffer_.Size() + Instr::kInstrSize); 905 label->Position() - (buffer_.Size() + Instr::kInstrSize);
798 const uint16_t dest_off = EncodeBranchOffset(dest, 0); 906 const uint16_t dest_off = EncodeBranchOffset(dest, 0);
799 EmitIType(b, rs, rt, dest_off); 907 EmitIType(b, rs, rt, dest_off);
800 } else { 908 } else {
801 const int position = buffer_.Size(); 909 const int position = buffer_.Size();
802 const uint16_t dest_off = EncodeBranchOffset(label->position_, 0); 910 const uint16_t dest_off = EncodeBranchOffset(label->position_, 0);
(...skipping 25 matching lines...) Expand all
828 delay_slot_available_ = true; 936 delay_slot_available_ = true;
829 } 937 }
830 938
831 DISALLOW_ALLOCATION(); 939 DISALLOW_ALLOCATION();
832 DISALLOW_COPY_AND_ASSIGN(Assembler); 940 DISALLOW_COPY_AND_ASSIGN(Assembler);
833 }; 941 };
834 942
835 } // namespace dart 943 } // namespace dart
836 944
837 #endif // VM_ASSEMBLER_MIPS_H_ 945 #endif // VM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698