| 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 end = start + (length * Instr::kInstrSize); | 352 end = start + (length * Instr::kInstrSize); |
| 353 } | 353 } |
| 354 } | 354 } |
| 355 Disassembler::Disassemble(start, end); | 355 Disassembler::Disassemble(start, end); |
| 356 } else if (strcmp(cmd, "flags") == 0) { | 356 } else if (strcmp(cmd, "flags") == 0) { |
| 357 OS::Print("APSR: "); | 357 OS::Print("APSR: "); |
| 358 OS::Print("N flag: %d; ", sim_->n_flag_); | 358 OS::Print("N flag: %d; ", sim_->n_flag_); |
| 359 OS::Print("Z flag: %d; ", sim_->z_flag_); | 359 OS::Print("Z flag: %d; ", sim_->z_flag_); |
| 360 OS::Print("C flag: %d; ", sim_->c_flag_); | 360 OS::Print("C flag: %d; ", sim_->c_flag_); |
| 361 OS::Print("V flag: %d\n", sim_->v_flag_); | 361 OS::Print("V flag: %d\n", sim_->v_flag_); |
| 362 OS::Print("FPSCR: "); | |
| 363 OS::Print("N flag: %d; ", sim_->fp_n_flag_); | |
| 364 OS::Print("Z flag: %d; ", sim_->fp_z_flag_); | |
| 365 OS::Print("C flag: %d; ", sim_->fp_c_flag_); | |
| 366 OS::Print("V flag: %d\n", sim_->fp_v_flag_); | |
| 367 } else if (strcmp(cmd, "gdb") == 0) { | 362 } else if (strcmp(cmd, "gdb") == 0) { |
| 368 OS::Print("relinquishing control to gdb\n"); | 363 OS::Print("relinquishing control to gdb\n"); |
| 369 OS::DebugBreak(); | 364 OS::DebugBreak(); |
| 370 OS::Print("regaining control from gdb\n"); | 365 OS::Print("regaining control from gdb\n"); |
| 371 } else { | 366 } else { |
| 372 OS::Print("Unknown command: %s\n", cmd); | 367 OS::Print("Unknown command: %s\n", cmd); |
| 373 } | 368 } |
| 374 } | 369 } |
| 375 delete[] line; | 370 delete[] line; |
| 376 } | 371 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 } | 467 } |
| 473 n_flag_ = false; | 468 n_flag_ = false; |
| 474 z_flag_ = false; | 469 z_flag_ = false; |
| 475 c_flag_ = false; | 470 c_flag_ = false; |
| 476 v_flag_ = false; | 471 v_flag_ = false; |
| 477 | 472 |
| 478 for (int i = 0; i < kNumberOfVRegisters; i++) { | 473 for (int i = 0; i < kNumberOfVRegisters; i++) { |
| 479 vregisters_[i].lo = 0; | 474 vregisters_[i].lo = 0; |
| 480 vregisters_[i].hi = 0; | 475 vregisters_[i].hi = 0; |
| 481 } | 476 } |
| 482 fp_n_flag_ = false; | |
| 483 fp_z_flag_ = false; | |
| 484 fp_c_flag_ = false; | |
| 485 fp_v_flag_ = false; | |
| 486 | 477 |
| 487 // The sp is initialized to point to the bottom (high address) of the | 478 // The sp is initialized to point to the bottom (high address) of the |
| 488 // allocated stack area. | 479 // allocated stack area. |
| 489 registers_[R31] = StackTop(); | 480 registers_[R31] = StackTop(); |
| 490 // The lr and pc are initialized to a known bad value that will cause an | 481 // The lr and pc are initialized to a known bad value that will cause an |
| 491 // access violation if the simulator ever tries to execute it. | 482 // access violation if the simulator ever tries to execute it. |
| 492 registers_[LR] = kBadLR; | 483 registers_[LR] = kBadLR; |
| 493 pc_ = kBadLR; | 484 pc_ = kBadLR; |
| 494 } | 485 } |
| 495 | 486 |
| (...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1960 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val); | 1951 static_cast<__int128>(rn_val) * static_cast<__int128>(rm_val); |
| 1961 const int64_t alu_out = static_cast<int64_t>(res >> 64); | 1952 const int64_t alu_out = static_cast<int64_t>(res >> 64); |
| 1962 set_register(rd, alu_out, R31IsZR); | 1953 set_register(rd, alu_out, R31IsZR); |
| 1963 } else { | 1954 } else { |
| 1964 UnimplementedInstruction(instr); | 1955 UnimplementedInstruction(instr); |
| 1965 } | 1956 } |
| 1966 } | 1957 } |
| 1967 | 1958 |
| 1968 | 1959 |
| 1969 void Simulator::DecodeConditionalSelect(Instr* instr) { | 1960 void Simulator::DecodeConditionalSelect(Instr* instr) { |
| 1961 const Register rd = instr->RdField(); |
| 1962 const Register rn = instr->RnField(); |
| 1963 const Register rm = instr->RmField(); |
| 1964 const int64_t rm_val64 = get_register(rm, R31IsZR); |
| 1965 const int32_t rm_val32 = get_wregister(rm, R31IsZR); |
| 1966 const int64_t rn_val64 = get_register(rn, instr->RnMode()); |
| 1967 const int32_t rn_val32 = get_wregister(rn, instr->RnMode()); |
| 1968 int64_t result64 = 0; |
| 1969 int32_t result32 = 0; |
| 1970 |
| 1970 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { | 1971 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { |
| 1971 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); | 1972 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); |
| 1972 const Register rd = instr->RdField(); | 1973 result64 = rm_val64; |
| 1973 const Register rn = instr->RnField(); | 1974 result32 = rm_val32; |
| 1974 const Register rm = instr->RmField(); | 1975 if (ConditionallyExecute(instr)) { |
| 1975 if (instr->SFField() == 1) { | 1976 result64 = rn_val64; |
| 1976 int64_t res = 0; | 1977 result32 = rn_val32; |
| 1977 if (ConditionallyExecute(instr)) { | |
| 1978 res = get_register(rn, instr->RnMode()); | |
| 1979 } else { | |
| 1980 res = get_register(rm, R31IsZR); | |
| 1981 } | |
| 1982 set_register(rd, res, instr->RdMode()); | |
| 1983 } else { | |
| 1984 int32_t res = 0; | |
| 1985 if (ConditionallyExecute(instr)) { | |
| 1986 res = get_wregister(rn, instr->RnMode()); | |
| 1987 } else { | |
| 1988 res = get_wregister(rm, R31IsZR); | |
| 1989 } | |
| 1990 set_wregister(rd, res, instr->RdMode()); | |
| 1991 } | 1978 } |
| 1992 | 1979 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) { |
| 1980 // Format(instr, "csinc'sf'cond 'rd, 'rn, 'rm"); |
| 1981 result64 = rm_val64 + 1; |
| 1982 result32 = rm_val32 + 1; |
| 1983 if (ConditionallyExecute(instr)) { |
| 1984 result64 = rn_val64; |
| 1985 result32 = rn_val32; |
| 1986 } |
| 1993 } else { | 1987 } else { |
| 1994 UnimplementedInstruction(instr); | 1988 UnimplementedInstruction(instr); |
| 1989 return; |
| 1990 } |
| 1991 |
| 1992 if (instr->SFField() == 1) { |
| 1993 set_register(rd, result64, instr->RdMode()); |
| 1994 } else { |
| 1995 set_wregister(rd, result32, instr->RdMode()); |
| 1995 } | 1996 } |
| 1996 } | 1997 } |
| 1997 | 1998 |
| 1998 | 1999 |
| 1999 void Simulator::DecodeDPRegister(Instr* instr) { | 2000 void Simulator::DecodeDPRegister(Instr* instr) { |
| 2000 if (instr->IsAddSubShiftExtOp()) { | 2001 if (instr->IsAddSubShiftExtOp()) { |
| 2001 DecodeAddSubShiftExt(instr); | 2002 DecodeAddSubShiftExt(instr); |
| 2002 } else if (instr->IsLogicalShiftOp()) { | 2003 } else if (instr->IsLogicalShiftOp()) { |
| 2003 DecodeLogicalShift(instr); | 2004 DecodeLogicalShift(instr); |
| 2004 } else if (instr->IsMiscDP2SourceOp()) { | 2005 } else if (instr->IsMiscDP2SourceOp()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2031 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); | 2032 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); |
| 2032 set_vregisterd(vd, immd); | 2033 set_vregisterd(vd, immd); |
| 2033 } else { | 2034 } else { |
| 2034 // Single. | 2035 // Single. |
| 2035 UnimplementedInstruction(instr); | 2036 UnimplementedInstruction(instr); |
| 2036 } | 2037 } |
| 2037 } | 2038 } |
| 2038 | 2039 |
| 2039 | 2040 |
| 2040 void Simulator::DecodeFPIntCvt(Instr* instr) { | 2041 void Simulator::DecodeFPIntCvt(Instr* instr) { |
| 2042 const VRegister vd = instr->VdField(); |
| 2043 const VRegister vn = instr->VnField(); |
| 2044 const Register rd = instr->RdField(); |
| 2045 const Register rn = instr->RnField(); |
| 2046 |
| 2041 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || | 2047 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || |
| 2042 (instr->Bits(22, 2) != 1)) { | 2048 (instr->Bits(22, 2) != 1)) { |
| 2043 UnimplementedInstruction(instr); | 2049 UnimplementedInstruction(instr); |
| 2044 return; | 2050 return; |
| 2045 } | 2051 } |
| 2046 if (instr->Bits(16, 3) == 6) { | 2052 if (instr->Bits(16, 5) == 2) { |
| 2053 // Format(instr, "scvtfd 'vd, 'vn"); |
| 2054 const int64_t rn_val = get_register(rn, instr->RnMode()); |
| 2055 const double vn_dbl = static_cast<double>(rn_val); |
| 2056 set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl)); |
| 2057 } else if (instr->Bits(16, 5) == 6) { |
| 2047 // Format(instr, "fmovrd 'rd, 'vn"); | 2058 // Format(instr, "fmovrd 'rd, 'vn"); |
| 2048 const VRegister vn = instr->VnField(); | |
| 2049 const Register rd = instr->RdField(); | |
| 2050 const int64_t vn_val = get_vregisterd(vn); | 2059 const int64_t vn_val = get_vregisterd(vn); |
| 2051 set_register(rd, vn_val, R31IsZR); | 2060 set_register(rd, vn_val, R31IsZR); |
| 2052 } else if (instr->Bits(16, 3) == 7) { | 2061 } else if (instr->Bits(16, 5) == 7) { |
| 2053 // Format(instr, "fmovdr 'vd, 'rn"); | 2062 // Format(instr, "fmovdr 'vd, 'rn"); |
| 2054 const VRegister vd = instr->VdField(); | |
| 2055 const Register rn = instr->RnField(); | |
| 2056 const int64_t rn_val = get_register(rn, R31IsZR); | 2063 const int64_t rn_val = get_register(rn, R31IsZR); |
| 2057 set_vregisterd(vd, rn_val); | 2064 set_vregisterd(vd, rn_val); |
| 2065 } else if (instr->Bits(16, 5) == 24) { |
| 2066 // Format(instr, "fcvtzds 'rd, 'vn"); |
| 2067 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); |
| 2068 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); |
| 2058 } else { | 2069 } else { |
| 2059 UnimplementedInstruction(instr); | 2070 UnimplementedInstruction(instr); |
| 2060 } | 2071 } |
| 2061 } | 2072 } |
| 2062 | 2073 |
| 2063 | 2074 |
| 2064 void Simulator::DecodeFPOneSource(Instr* instr) { | 2075 void Simulator::DecodeFPOneSource(Instr* instr) { |
| 2065 const int opc = instr->Bits(15, 2); | 2076 const int opc = instr->Bits(15, 2); |
| 2066 const VRegister vd = instr->VdField(); | 2077 const VRegister vd = instr->VdField(); |
| 2067 const VRegister vn = instr->VnField(); | 2078 const VRegister vn = instr->VnField(); |
| 2068 switch (opc) { | 2079 switch (opc) { |
| 2069 case 0: | 2080 case 0: |
| 2070 // Format("fmovdd 'vd, 'vn"); | 2081 // Format("fmovdd 'vd, 'vn"); |
| 2071 set_vregisterd(vd, get_vregisterd(vn)); | 2082 set_vregisterd(vd, get_vregisterd(vn)); |
| 2072 break; | 2083 break; |
| 2073 default: | 2084 default: |
| 2074 UnimplementedInstruction(instr); | 2085 UnimplementedInstruction(instr); |
| 2075 break; | 2086 break; |
| 2076 } | 2087 } |
| 2077 } | 2088 } |
| 2078 | 2089 |
| 2079 | 2090 |
| 2091 void Simulator::DecodeFPTwoSource(Instr* instr) { |
| 2092 if (instr->Bits(22, 2) != 1) { |
| 2093 UnimplementedInstruction(instr); |
| 2094 return; |
| 2095 } |
| 2096 const VRegister vd = instr->VdField(); |
| 2097 const VRegister vn = instr->VnField(); |
| 2098 const VRegister vm = instr->VmField(); |
| 2099 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); |
| 2100 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm)); |
| 2101 const int opc = instr->Bits(12, 4); |
| 2102 double result; |
| 2103 |
| 2104 switch (opc) { |
| 2105 case 0: |
| 2106 // Format(instr, "fmuld 'vd, 'vn, 'vm"); |
| 2107 result = vn_val * vm_val; |
| 2108 break; |
| 2109 case 1: |
| 2110 // Format(instr, "fdivd 'vd, 'vn, 'vm"); |
| 2111 result = vn_val / vm_val; |
| 2112 break; |
| 2113 case 2: |
| 2114 // Format(instr, "faddd 'vd, 'vn, 'vm"); |
| 2115 result = vn_val + vm_val; |
| 2116 break; |
| 2117 case 3: |
| 2118 // Format(instr, "fsubd 'vd, 'vn, 'vm"); |
| 2119 result = vn_val - vm_val; |
| 2120 break; |
| 2121 default: |
| 2122 // Unknown(instr); |
| 2123 break; |
| 2124 } |
| 2125 |
| 2126 set_vregisterd(vd, bit_cast<int64_t, double>(result)); |
| 2127 } |
| 2128 |
| 2129 |
| 2130 void Simulator::DecodeFPCompare(Instr* instr) { |
| 2131 const VRegister vn = instr->VnField(); |
| 2132 const VRegister vm = instr->VmField(); |
| 2133 const double vn_val = get_vregisterd(vn); |
| 2134 double vm_val; |
| 2135 |
| 2136 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { |
| 2137 // Format(instr, "fcmpd 'vn, 'vm"); |
| 2138 vm_val = get_vregisterd(vm); |
| 2139 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { |
| 2140 if (instr->VmField() == V0) { |
| 2141 // Format(instr, "fcmpd 'vn, #0.0"); |
| 2142 vm_val = 0.0; |
| 2143 } else { |
| 2144 UnimplementedInstruction(instr); |
| 2145 return; |
| 2146 } |
| 2147 } else { |
| 2148 UnimplementedInstruction(instr); |
| 2149 return; |
| 2150 } |
| 2151 |
| 2152 n_flag_ = false; |
| 2153 z_flag_ = false; |
| 2154 c_flag_ = false; |
| 2155 v_flag_ = false; |
| 2156 |
| 2157 if (isnan(vn_val) || isnan(vm_val)) { |
| 2158 c_flag_ = true; |
| 2159 v_flag_ = true; |
| 2160 } else if (vn_val == vm_val) { |
| 2161 z_flag_ = true; |
| 2162 c_flag_ = true; |
| 2163 } else if (vn_val < vm_val) { |
| 2164 n_flag_ = true; |
| 2165 } else { |
| 2166 c_flag_ = true; |
| 2167 } |
| 2168 } |
| 2169 |
| 2170 |
| 2080 void Simulator::DecodeFP(Instr* instr) { | 2171 void Simulator::DecodeFP(Instr* instr) { |
| 2081 if (instr->IsFPImmOp()) { | 2172 if (instr->IsFPImmOp()) { |
| 2082 DecodeFPImm(instr); | 2173 DecodeFPImm(instr); |
| 2083 } else if (instr->IsFPIntCvtOp()) { | 2174 } else if (instr->IsFPIntCvtOp()) { |
| 2084 DecodeFPIntCvt(instr); | 2175 DecodeFPIntCvt(instr); |
| 2085 } else if (instr->IsFPOneSourceOp()) { | 2176 } else if (instr->IsFPOneSourceOp()) { |
| 2086 DecodeFPOneSource(instr); | 2177 DecodeFPOneSource(instr); |
| 2178 } else if (instr->IsFPTwoSourceOp()) { |
| 2179 DecodeFPTwoSource(instr); |
| 2180 } else if (instr->IsFPCompareOp()) { |
| 2181 DecodeFPCompare(instr); |
| 2087 } else { | 2182 } else { |
| 2088 UnimplementedInstruction(instr); | 2183 UnimplementedInstruction(instr); |
| 2089 } | 2184 } |
| 2090 } | 2185 } |
| 2091 | 2186 |
| 2092 | 2187 |
| 2093 void Simulator::DecodeDPSimd2(Instr* instr) { | 2188 void Simulator::DecodeDPSimd2(Instr* instr) { |
| 2094 if (instr->IsFPOp()) { | 2189 if (instr->IsFPOp()) { |
| 2095 DecodeFP(instr); | 2190 DecodeFP(instr); |
| 2096 } else { | 2191 } else { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2286 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 2381 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 2287 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 2382 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 2288 buf->Longjmp(); | 2383 buf->Longjmp(); |
| 2289 } | 2384 } |
| 2290 | 2385 |
| 2291 } // namespace dart | 2386 } // namespace dart |
| 2292 | 2387 |
| 2293 #endif // !defined(HOST_ARCH_ARM64) | 2388 #endif // !defined(HOST_ARCH_ARM64) |
| 2294 | 2389 |
| 2295 #endif // defined TARGET_ARCH_ARM64 | 2390 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |