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

Side by Side Diff: runtime/vm/simulator_arm64.cc

Issue 235363005: Adds comparisons, labels, branches to arm64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | « runtime/vm/simulator_arm64.h ('k') | no next file » | 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) 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 #include <math.h> // for isnan. 5 #include <math.h> // for isnan.
6 #include <setjmp.h> 6 #include <setjmp.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include "vm/globals.h" 9 #include "vm/globals.h"
10 #if defined(TARGET_ARCH_ARM64) 10 #if defined(TARGET_ARCH_ARM64)
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 521 }
522 522
523 if (out_size == kXRegSizeInBits) { 523 if (out_size == kXRegSizeInBits) {
524 set_register(rd, alu_out, instr->RdMode()); 524 set_register(rd, alu_out, instr->RdMode());
525 } else { 525 } else {
526 set_wregister(rd, alu_out, instr->RdMode()); 526 set_wregister(rd, alu_out, instr->RdMode());
527 } 527 }
528 } 528 }
529 529
530 530
531 void Simulator::DecodePCRel(Instr* instr) {
532 const int op = instr->Bit(31);
533 if (op == 0) {
534 // Format(instr, "adr 'rd, 'pcrel")
535 const Register rd = instr->RdField();
536 const int64_t immhi = instr->SImm19Field();
537 const int64_t immlo = instr->Bits(29, 2);
538 const int64_t off = (immhi << 2) | immlo;
539 const int64_t dest = get_pc() + off;
540 set_register(rd, dest, instr->RdMode());
541 } else {
542 UnimplementedInstruction(instr);
543 }
544 }
545
546
531 void Simulator::DecodeDPImmediate(Instr* instr) { 547 void Simulator::DecodeDPImmediate(Instr* instr) {
532 if (instr->IsMoveWideOp()) { 548 if (instr->IsMoveWideOp()) {
533 DecodeMoveWide(instr); 549 DecodeMoveWide(instr);
534 } else if (instr->IsAddSubImmOp()) { 550 } else if (instr->IsAddSubImmOp()) {
535 DecodeAddSubImm(instr); 551 DecodeAddSubImm(instr);
536 } else if (instr->IsLogicalImmOp()) { 552 } else if (instr->IsLogicalImmOp()) {
537 DecodeLogicalImm(instr); 553 DecodeLogicalImm(instr);
554 } else if (instr->IsPCRelOp()) {
555 DecodePCRel(instr);
538 } else { 556 } else {
539 UnimplementedInstruction(instr); 557 UnimplementedInstruction(instr);
540 } 558 }
541 } 559 }
542 560
543 561
562 void Simulator::DecodeCompareAndBranch(Instr* instr) {
563 const int op = instr->Bit(24);
564 const Register rt = instr->RtField();
565 const int64_t imm19 = instr->SImm19Field();
566 const int64_t dest = get_pc() + (imm19 << 2);
567 const int64_t mask = instr->SFField() == 1 ? kXRegMask : kWRegMask;
568 const int64_t rt_val = get_register(rt, R31IsZR) & mask;
569 if (op == 0) {
570 // Format(instr, "cbz'sf 'rt, 'dest19");
571 if (rt_val == 0) {
572 set_pc(dest);
573 }
574 } else {
575 // Format(instr, "cbnz'sf 'rt, 'dest19");
576 if (rt_val != 0) {
577 set_pc(dest);
578 }
579 }
580 }
581
582
583 bool Simulator::ConditionallyExecute(Instr* instr) {
584 switch (instr->ConditionField()) {
585 case EQ: return z_flag_;
586 case NE: return !z_flag_;
587 case CS: return c_flag_;
588 case CC: return !c_flag_;
589 case MI: return n_flag_;
590 case PL: return !n_flag_;
591 case VS: return v_flag_;
592 case VC: return !v_flag_;
593 case HI: return c_flag_ && !z_flag_;
594 case LS: return !c_flag_ || z_flag_;
595 case GE: return n_flag_ == v_flag_;
596 case LT: return n_flag_ != v_flag_;
597 case GT: return !z_flag_ && (n_flag_ == v_flag_);
598 case LE: return z_flag_ || (n_flag_ != v_flag_);
599 case AL: return true;
600 default: UNREACHABLE();
601 }
602 return false;
603 }
604
605
606 void Simulator::DecodeConditionalBranch(Instr* instr) {
607 // Format(instr, "b'cond 'dest19");
608 if ((instr->Bit(24) != 0) || (instr->Bit(4) != 0)) {
609 UnimplementedInstruction(instr);
610 }
611 const int64_t imm19 = instr->SImm19Field();
612 const int64_t dest = get_pc() + (imm19 << 2);
613 if (ConditionallyExecute(instr)) {
614 set_pc(dest);
615 }
616 }
617
618
544 void Simulator::DecodeExceptionGen(Instr* instr) { 619 void Simulator::DecodeExceptionGen(Instr* instr) {
545 UnimplementedInstruction(instr); 620 UnimplementedInstruction(instr);
546 } 621 }
547 622
548 623
549 void Simulator::DecodeSystem(Instr* instr) { 624 void Simulator::DecodeSystem(Instr* instr) {
550 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) && 625 if ((instr->Bits(0, 8) == 0x5f) && (instr->Bits(12, 4) == 2) &&
551 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) && 626 (instr->Bits(16, 3) == 3) && (instr->Bits(19, 2) == 0) &&
552 (instr->Bit(21) == 0)) { 627 (instr->Bit(21) == 0)) {
553 if (instr->Bits(8, 4) == 0) { 628 if (instr->Bits(8, 4) == 0) {
554 // Format(instr, "nop"); 629 // Format(instr, "nop");
555 } else { 630 } else {
556 UnimplementedInstruction(instr); 631 UnimplementedInstruction(instr);
557 } 632 }
558 } else { 633 } else {
559 UnimplementedInstruction(instr); 634 UnimplementedInstruction(instr);
560 } 635 }
561 } 636 }
562 637
563 638
639 void Simulator::DecodeTestAndBranch(Instr* instr) {
640 const int op = instr->Bit(24);
641 const int bitpos = instr->Bits(19, 4) | (instr->Bit(31) << 5);
642 const int64_t imm14 = instr->SImm14Field();
643 const int64_t dest = get_pc() + (imm14 << 2);
644 const Register rt = instr->RtField();
645 const int64_t rt_val = get_register(rt, R31IsZR);
646 if (op == 0) {
647 // Format(instr, "tbz'sf 'rt, 'bitpos, 'dest14");
648 if ((rt_val & (1 << bitpos)) == 0) {
649 set_pc(dest);
650 }
651 } else {
652 // Format(instr, "tbnz'sf 'rt, 'bitpos, 'dest14");
653 if ((rt_val & (1 << bitpos)) != 0) {
654 set_pc(dest);
655 }
656 }
657 }
658
659
660 void Simulator::DecodeUnconditionalBranch(Instr* instr) {
661 const bool link = instr->Bit(31) == 1;
662 const int64_t imm26 = instr->SImm26Field();
663 const int64_t dest = get_pc() + (imm26 << 2);
664 const int64_t ret = get_pc() + Instr::kInstrSize;
665 set_pc(dest);
666 if (link) {
667 set_register(LR, ret);
668 }
669 }
670
671
564 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) { 672 void Simulator::DecodeUnconditionalBranchReg(Instr* instr) {
565 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) && 673 if ((instr->Bits(0, 5) == 0) && (instr->Bits(10, 6) == 0) &&
566 (instr->Bits(16, 5) == 0x1f)) { 674 (instr->Bits(16, 5) == 0x1f)) {
567 switch (instr->Bits(21, 4)) { 675 switch (instr->Bits(21, 4)) {
676 case 0: {
677 // Format(instr, "br 'rn");
678 const Register rn = instr->RnField();
679 const int64_t dest = get_register(rn, instr->RnMode());
680 set_pc(dest);
681 break;
682 }
683 case 1: {
684 // Format(instr, "blr 'rn");
685 const Register rn = instr->RnField();
686 const int64_t dest = get_register(rn, instr->RnMode());
687 const int64_t ret = get_pc() + Instr::kInstrSize;
688 set_pc(dest);
689 set_register(LR, ret);
690 break;
691 }
568 case 2: { 692 case 2: {
569 // Format(instr, "ret 'rn"); 693 // Format(instr, "ret 'rn");
570 const Register rn = instr->RnField(); 694 const Register rn = instr->RnField();
571 const int64_t rn_val = get_register(rn, instr->RnMode()); 695 const int64_t rn_val = get_register(rn, instr->RnMode());
572 set_pc(rn_val); 696 set_pc(rn_val);
573 break; 697 break;
574 } 698 }
575 default: 699 default:
576 UnimplementedInstruction(instr); 700 UnimplementedInstruction(instr);
577 break; 701 break;
578 } 702 }
579 } else { 703 } else {
580 UnimplementedInstruction(instr); 704 UnimplementedInstruction(instr);
581 } 705 }
582 } 706 }
583 707
584 708
585 void Simulator::DecodeCompareBranch(Instr* instr) { 709 void Simulator::DecodeCompareBranch(Instr* instr) {
586 if (instr->IsExceptionGenOp()) { 710 if (instr->IsCompareAndBranchOp()) {
711 DecodeCompareAndBranch(instr);
712 } else if (instr->IsConditionalBranchOp()) {
713 DecodeConditionalBranch(instr);
714 } else if (instr->IsExceptionGenOp()) {
587 DecodeExceptionGen(instr); 715 DecodeExceptionGen(instr);
588 } else if (instr->IsSystemOp()) { 716 } else if (instr->IsSystemOp()) {
589 DecodeSystem(instr); 717 DecodeSystem(instr);
718 } else if (instr->IsTestAndBranchOp()) {
719 DecodeTestAndBranch(instr);
720 } else if (instr->IsUnconditionalBranchOp()) {
721 DecodeUnconditionalBranch(instr);
590 } else if (instr->IsUnconditionalBranchRegOp()) { 722 } else if (instr->IsUnconditionalBranchRegOp()) {
591 DecodeUnconditionalBranchReg(instr); 723 DecodeUnconditionalBranchReg(instr);
592 } else { 724 } else {
593 UnimplementedInstruction(instr); 725 UnimplementedInstruction(instr);
594 } 726 }
595 } 727 }
596 728
597 729
598 void Simulator::DecodeLoadStoreReg(Instr* instr) { 730 void Simulator::DecodeLoadStoreReg(Instr* instr) {
599 // TODO(zra): SIMD loads and stores have bit 26 (V) set. 731 // TODO(zra): SIMD loads and stores have bit 26 (V) set.
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 value = (value << 48) >> 48; 936 value = (value << 48) >> 48;
805 break; 937 break;
806 case SXTW: 938 case SXTW:
807 value = (value << 32) >> 32; 939 value = (value << 32) >> 32;
808 break; 940 break;
809 case UXTX: 941 case UXTX:
810 case SXTX: 942 case SXTX:
811 break; 943 break;
812 default: 944 default:
813 UNREACHABLE(); 945 UNREACHABLE();
946 break;
814 } 947 }
815 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask; 948 int64_t mask = (reg_size == kXRegSizeInBits) ? kXRegMask : kWRegMask;
816 return (value << amount) & mask; 949 return (value << amount) & mask;
817 } 950 }
818 951
819 952
820 int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) { 953 int64_t Simulator::DecodeShiftExtendOperand(Instr* instr) {
821 const Register rm = instr->RmField(); 954 const Register rm = instr->RmField();
822 const int64_t rm_val = get_register(rm, R31IsZR); 955 const int64_t rm_val = get_register(rm, R31IsZR);
823 const uint8_t size = instr->SFField() ? kXRegSizeInBits : kWRegSizeInBits; 956 const uint8_t size = instr->SFField() ? kXRegSizeInBits : kWRegSizeInBits;
824 if (instr->IsShift()) { 957 if (instr->IsShift()) {
825 const Shift shift_type = instr->ShiftTypeField(); 958 const Shift shift_type = instr->ShiftTypeField();
826 const uint8_t shift_amount = instr->Imm6Field(); 959 const uint8_t shift_amount = instr->Imm6Field();
827 return ShiftOperand(size, rm_val, shift_type, shift_amount); 960 return ShiftOperand(size, rm_val, shift_type, shift_amount);
828 } else { 961 } else {
829 ASSERT(instr->IsExtend()); 962 ASSERT(instr->IsExtend());
830 const Extend extend_type = instr->ExtendTypeField(); 963 const Extend extend_type = instr->ExtendTypeField();
831 const uint8_t shift_amount = instr->Imm3Field(); 964 const uint8_t shift_amount = instr->Imm3Field();
832 return ExtendOperand(size, rm_val, extend_type, shift_amount); 965 return ExtendOperand(size, rm_val, extend_type, shift_amount);
833 } 966 }
834 UNREACHABLE(); 967 UNREACHABLE();
835 return -1; 968 return -1;
836 } 969 }
837 970
838 971
839 void Simulator::DecodeAddSubShiftExt(Instr* instr) { 972 void Simulator::DecodeAddSubShiftExt(Instr* instr) {
840 switch (instr->Bit(30)) { 973 // Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
841 case 0: { 974 // also, sub, cmp, etc.
842 // Format(instr, "add'sf's 'rd, 'rn, 'shift_op"); 975 const bool subtract = instr->Bit(30) == 1;
843 const Register rd = instr->RdField(); 976 const Register rd = instr->RdField();
844 const Register rn = instr->RnField(); 977 const Register rn = instr->RnField();
845 const int64_t rm_val = DecodeShiftExtendOperand(instr); 978 const int64_t rm_val = DecodeShiftExtendOperand(instr);
846 if (instr->SFField()) { 979 if (instr->SFField()) {
847 // 64-bit add. 980 // 64-bit add.
848 const int64_t rn_val = get_register(rn, instr->RnMode()); 981 const int64_t rn_val = get_register(rn, instr->RnMode());
849 const int64_t alu_out = rn_val + rm_val; 982 int64_t alu_out = 0;
850 set_register(rd, alu_out, instr->RdMode()); 983 if (subtract) {
851 if (instr->HasS()) { 984 alu_out = rn_val - rm_val;
852 SetNZFlagsX(alu_out); 985 } else {
853 SetCFlag(CarryFromX(rn_val, rm_val)); 986 alu_out = rn_val + rm_val;
854 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, true));
855 }
856 } else {
857 // 32-bit add.
858 const int32_t rn_val = get_wregister(rn, instr->RnMode());
859 const int32_t rm_val32 = static_cast<int32_t>(rm_val & kWRegMask);
860 const int32_t alu_out = rn_val + rm_val32;
861 set_wregister(rd, alu_out, instr->RdMode());
862 if (instr->HasS()) {
863 SetNZFlagsW(alu_out);
864 SetCFlag(CarryFromW(rn_val, rm_val32));
865 SetVFlag(OverflowFromW(alu_out, rn_val, rm_val32, true));
866 }
867 }
868 break;
869 } 987 }
870 default: 988 set_register(rd, alu_out, instr->RdMode());
871 UnimplementedInstruction(instr); 989 if (instr->HasS()) {
872 break; 990 SetNZFlagsX(alu_out);
991 SetCFlag(CarryFromX(rn_val, rm_val));
992 SetVFlag(OverflowFromX(alu_out, rn_val, rm_val, !subtract));
993 }
994 } else {
995 // 32-bit add.
996 const int32_t rn_val = get_wregister(rn, instr->RnMode());
997 const int32_t rm_val32 = static_cast<int32_t>(rm_val & kWRegMask);
998 int32_t alu_out = 0;
999 if (subtract) {
1000 alu_out = rn_val - rm_val32;
1001 } else {
1002 alu_out = rn_val + rm_val32;
1003 }
1004 set_wregister(rd, alu_out, instr->RdMode());
1005 if (instr->HasS()) {
1006 SetNZFlagsW(alu_out);
1007 SetCFlag(CarryFromW(rn_val, rm_val32));
1008 SetVFlag(OverflowFromW(alu_out, rn_val, rm_val32, !subtract));
1009 }
873 } 1010 }
874 } 1011 }
875 1012
876 1013
877 void Simulator::DecodeLogicalShift(Instr* instr) { 1014 void Simulator::DecodeLogicalShift(Instr* instr) {
878 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); 1015 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
879 const Register rd = instr->RdField(); 1016 const Register rd = instr->RdField();
880 const Register rn = instr->RnField(); 1017 const Register rn = instr->RnField();
881 const int64_t rn_val = get_register(rn, instr->RnMode()); 1018 const int64_t rn_val = get_register(rn, instr->RnMode());
882 const int64_t rm_val = DecodeShiftExtendOperand(instr); 1019 const int64_t rm_val = DecodeShiftExtendOperand(instr);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 int64_t return_value; 1255 int64_t return_value;
1119 return_value = get_register(R0); 1256 return_value = get_register(R0);
1120 return return_value; 1257 return return_value;
1121 } 1258 }
1122 1259
1123 } // namespace dart 1260 } // namespace dart
1124 1261
1125 #endif // !defined(HOST_ARCH_ARM64) 1262 #endif // !defined(HOST_ARCH_ARM64)
1126 1263
1127 #endif // defined TARGET_ARCH_ARM64 1264 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698