| 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 #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 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 const int32_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); | 470 const int32_t alu_out = addition ? (rn_val + imm) : (rn_val - imm); |
| 471 set_wregister(rd, alu_out, instr->RdMode()); | 471 set_wregister(rd, alu_out, instr->RdMode()); |
| 472 if (instr->HasS()) { | 472 if (instr->HasS()) { |
| 473 SetNZFlagsW(alu_out); | 473 SetNZFlagsW(alu_out); |
| 474 SetCFlag(CarryFromW(rn_val, imm)); | 474 SetCFlag(CarryFromW(rn_val, imm)); |
| 475 SetVFlag(OverflowFromW(alu_out, rn_val, imm, addition)); | 475 SetVFlag(OverflowFromW(alu_out, rn_val, imm, addition)); |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 } | 478 } |
| 479 | 479 |
| 480 |
| 481 void Simulator::DecodeLogicalImm(Instr* instr) { |
| 482 const int op = instr->Bits(29, 2); |
| 483 const bool set_flags = op == 3; |
| 484 const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0)) |
| 485 ? kWRegSizeInBits : kXRegSizeInBits; |
| 486 const Register rn = instr->RnField(); |
| 487 const Register rd = instr->RdField(); |
| 488 const int64_t rn_val = get_register(rn, instr->RnMode()); |
| 489 const uint64_t imm = instr->ImmLogical(); |
| 490 if (imm == 0) { |
| 491 UnimplementedInstruction(instr); |
| 492 } |
| 493 |
| 494 int64_t alu_out = 0; |
| 495 switch (op) { |
| 496 case 0: |
| 497 alu_out = rn_val & imm; |
| 498 break; |
| 499 case 1: |
| 500 alu_out = rn_val | imm; |
| 501 break; |
| 502 case 2: |
| 503 alu_out = rn_val ^ imm; |
| 504 break; |
| 505 case 3: |
| 506 alu_out = rn_val & imm; |
| 507 break; |
| 508 default: |
| 509 UNREACHABLE(); |
| 510 break; |
| 511 } |
| 512 |
| 513 if (set_flags) { |
| 514 if (out_size == kXRegSizeInBits) { |
| 515 SetNZFlagsX(alu_out); |
| 516 } else { |
| 517 SetNZFlagsW(alu_out); |
| 518 } |
| 519 SetCFlag(false); |
| 520 SetVFlag(false); |
| 521 } |
| 522 |
| 523 if (out_size == kXRegSizeInBits) { |
| 524 set_register(rd, alu_out, instr->RdMode()); |
| 525 } else { |
| 526 set_wregister(rd, alu_out, instr->RdMode()); |
| 527 } |
| 528 } |
| 529 |
| 530 |
| 480 void Simulator::DecodeDPImmediate(Instr* instr) { | 531 void Simulator::DecodeDPImmediate(Instr* instr) { |
| 481 if (instr->IsMoveWideOp()) { | 532 if (instr->IsMoveWideOp()) { |
| 482 DecodeMoveWide(instr); | 533 DecodeMoveWide(instr); |
| 483 } else if (instr->IsAddSubImmOp()) { | 534 } else if (instr->IsAddSubImmOp()) { |
| 484 DecodeAddSubImm(instr); | 535 DecodeAddSubImm(instr); |
| 536 } else if (instr->IsLogicalImmOp()) { |
| 537 DecodeLogicalImm(instr); |
| 485 } else { | 538 } else { |
| 486 UnimplementedInstruction(instr); | 539 UnimplementedInstruction(instr); |
| 487 } | 540 } |
| 488 } | 541 } |
| 489 | 542 |
| 490 | 543 |
| 491 void Simulator::DecodeExceptionGen(Instr* instr) { | 544 void Simulator::DecodeExceptionGen(Instr* instr) { |
| 492 UnimplementedInstruction(instr); | 545 UnimplementedInstruction(instr); |
| 493 } | 546 } |
| 494 | 547 |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 } | 867 } |
| 815 break; | 868 break; |
| 816 } | 869 } |
| 817 default: | 870 default: |
| 818 UnimplementedInstruction(instr); | 871 UnimplementedInstruction(instr); |
| 819 break; | 872 break; |
| 820 } | 873 } |
| 821 } | 874 } |
| 822 | 875 |
| 823 | 876 |
| 877 void Simulator::DecodeLogicalShift(Instr* instr) { |
| 878 const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21); |
| 879 const Register rd = instr->RdField(); |
| 880 const Register rn = instr->RnField(); |
| 881 const int64_t rn_val = get_register(rn, instr->RnMode()); |
| 882 const int64_t rm_val = DecodeShiftExtendOperand(instr); |
| 883 int64_t alu_out = 0; |
| 884 switch (op) { |
| 885 case 0: |
| 886 // Format(instr, "and'sf 'rd, 'rn, 'shift_op"); |
| 887 alu_out = rn_val & rm_val; |
| 888 break; |
| 889 case 1: |
| 890 // Format(instr, "bic'sf 'rd, 'rn, 'shift_op"); |
| 891 alu_out = rn_val & (~rm_val); |
| 892 break; |
| 893 case 2: |
| 894 // Format(instr, "orr'sf 'rd, 'rn, 'shift_op"); |
| 895 alu_out = rn_val | rm_val; |
| 896 break; |
| 897 case 3: |
| 898 // Format(instr, "orn'sf 'rd, 'rn, 'shift_op"); |
| 899 alu_out = rn_val | (~rm_val); |
| 900 break; |
| 901 case 4: |
| 902 // Format(instr, "eor'sf 'rd, 'rn, 'shift_op"); |
| 903 alu_out = rn_val ^ rm_val; |
| 904 break; |
| 905 case 5: |
| 906 // Format(instr, "eon'sf 'rd, 'rn, 'shift_op"); |
| 907 alu_out = rn_val ^ (~rm_val); |
| 908 break; |
| 909 case 6: |
| 910 // Format(instr, "and'sfs 'rd, 'rn, 'shift_op"); |
| 911 alu_out = rn_val & rm_val; |
| 912 break; |
| 913 case 7: |
| 914 // Format(instr, "bic'sfs 'rd, 'rn, 'shift_op"); |
| 915 alu_out = rn_val & (~rm_val); |
| 916 break; |
| 917 default: |
| 918 UNREACHABLE(); |
| 919 break; |
| 920 } |
| 921 |
| 922 // Set flags if ands or bics. |
| 923 if ((op == 6) || (op == 7)) { |
| 924 if (instr->SFField() == 1) { |
| 925 SetNZFlagsX(alu_out); |
| 926 } else { |
| 927 SetNZFlagsW(alu_out); |
| 928 } |
| 929 SetCFlag(false); |
| 930 SetVFlag(false); |
| 931 } |
| 932 |
| 933 if (instr->SFField() == 1) { |
| 934 set_register(rd, alu_out, instr->RdMode()); |
| 935 } else { |
| 936 set_wregister(rd, alu_out & kWRegMask, instr->RdMode()); |
| 937 } |
| 938 } |
| 939 |
| 940 |
| 824 void Simulator::DecodeDPRegister(Instr* instr) { | 941 void Simulator::DecodeDPRegister(Instr* instr) { |
| 825 if (instr->IsAddSubShiftExtOp()) { | 942 if (instr->IsAddSubShiftExtOp()) { |
| 826 DecodeAddSubShiftExt(instr); | 943 DecodeAddSubShiftExt(instr); |
| 944 } else if (instr->IsLogicalShiftOp()) { |
| 945 DecodeLogicalShift(instr); |
| 827 } else { | 946 } else { |
| 828 UnimplementedInstruction(instr); | 947 UnimplementedInstruction(instr); |
| 829 } | 948 } |
| 830 } | 949 } |
| 831 | 950 |
| 832 | 951 |
| 833 void Simulator::DecodeDPSimd1(Instr* instr) { | 952 void Simulator::DecodeDPSimd1(Instr* instr) { |
| 834 UnimplementedInstruction(instr); | 953 UnimplementedInstruction(instr); |
| 835 } | 954 } |
| 836 | 955 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 int64_t return_value; | 1118 int64_t return_value; |
| 1000 return_value = get_register(R0); | 1119 return_value = get_register(R0); |
| 1001 return return_value; | 1120 return return_value; |
| 1002 } | 1121 } |
| 1003 | 1122 |
| 1004 } // namespace dart | 1123 } // namespace dart |
| 1005 | 1124 |
| 1006 #endif // !defined(HOST_ARCH_ARM64) | 1125 #endif // !defined(HOST_ARCH_ARM64) |
| 1007 | 1126 |
| 1008 #endif // defined TARGET_ARCH_ARM64 | 1127 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |