Chromium Code Reviews| 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) { |
| 1970 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { | 1961 const Register rd = instr->RdField(); |
| 1971 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); | 1962 const Register rn = instr->RnField(); |
| 1972 const Register rd = instr->RdField(); | 1963 const Register rm = instr->RmField(); |
| 1973 const Register rn = instr->RnField(); | 1964 const int64_t rm_val64 = get_register(rm, R31IsZR); |
| 1974 const Register rm = instr->RmField(); | 1965 const int32_t rm_val32 = get_wregister(rm, R31IsZR); |
| 1975 if (instr->SFField() == 1) { | 1966 const int64_t rn_val64 = get_register(rn, instr->RnMode()); |
| 1976 int64_t res = 0; | 1967 const int32_t rn_val32 = get_wregister(rn, instr->RnMode()); |
| 1977 if (ConditionallyExecute(instr)) { | 1968 int64_t result64 = rm_val64; |
| 1978 res = get_register(rn, instr->RnMode()); | 1969 int32_t result32 = rm_val32; |
|
regis
2014/05/06 20:01:12
I do not think this is correct for cinc, which doe
zra
2014/05/06 20:50:24
Whoops. Thanks for catching this. I totally misrea
| |
| 1979 } else { | 1970 |
| 1980 res = get_register(rm, R31IsZR); | 1971 if (ConditionallyExecute(instr)) { |
| 1981 } | 1972 if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 0)) { |
| 1982 set_register(rd, res, instr->RdMode()); | 1973 // Format(instr, "mov'sf'cond 'rd, 'rn, 'rm"); |
| 1974 result64 = rn_val64; | |
| 1975 result32 = rn_val32; | |
| 1976 } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(10, 2) == 1)) { | |
| 1977 // Format(instr, "inc'sf'cond 'rd, 'rn, 'rm"); | |
| 1978 result64 = rn_val64 + 1; | |
| 1979 result32 = rn_val32 + 1; | |
| 1983 } else { | 1980 } else { |
| 1984 int32_t res = 0; | 1981 UnimplementedInstruction(instr); |
| 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 } | 1982 } |
| 1983 } | |
| 1992 | 1984 |
| 1985 if (instr->SFField() == 1) { | |
| 1986 set_register(rd, result64, instr->RdMode()); | |
| 1993 } else { | 1987 } else { |
| 1994 UnimplementedInstruction(instr); | 1988 set_wregister(rd, result32, instr->RdMode()); |
| 1995 } | 1989 } |
| 1996 } | 1990 } |
| 1997 | 1991 |
| 1998 | 1992 |
| 1999 void Simulator::DecodeDPRegister(Instr* instr) { | 1993 void Simulator::DecodeDPRegister(Instr* instr) { |
| 2000 if (instr->IsAddSubShiftExtOp()) { | 1994 if (instr->IsAddSubShiftExtOp()) { |
| 2001 DecodeAddSubShiftExt(instr); | 1995 DecodeAddSubShiftExt(instr); |
| 2002 } else if (instr->IsLogicalShiftOp()) { | 1996 } else if (instr->IsLogicalShiftOp()) { |
| 2003 DecodeLogicalShift(instr); | 1997 DecodeLogicalShift(instr); |
| 2004 } else if (instr->IsMiscDP2SourceOp()) { | 1998 } else if (instr->IsMiscDP2SourceOp()) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2031 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); | 2025 const int64_t immd = Instr::VFPExpandImm(instr->Imm8Field()); |
| 2032 set_vregisterd(vd, immd); | 2026 set_vregisterd(vd, immd); |
| 2033 } else { | 2027 } else { |
| 2034 // Single. | 2028 // Single. |
| 2035 UnimplementedInstruction(instr); | 2029 UnimplementedInstruction(instr); |
| 2036 } | 2030 } |
| 2037 } | 2031 } |
| 2038 | 2032 |
| 2039 | 2033 |
| 2040 void Simulator::DecodeFPIntCvt(Instr* instr) { | 2034 void Simulator::DecodeFPIntCvt(Instr* instr) { |
| 2035 const VRegister vd = instr->VdField(); | |
| 2036 const VRegister vn = instr->VnField(); | |
| 2037 const Register rd = instr->RdField(); | |
| 2038 const Register rn = instr->RnField(); | |
| 2039 | |
| 2041 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || | 2040 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) || |
| 2042 (instr->Bits(22, 2) != 1)) { | 2041 (instr->Bits(22, 2) != 1)) { |
| 2043 UnimplementedInstruction(instr); | 2042 UnimplementedInstruction(instr); |
| 2044 return; | 2043 return; |
| 2045 } | 2044 } |
| 2046 if (instr->Bits(16, 3) == 6) { | 2045 if (instr->Bits(16, 5) == 2) { |
| 2046 // Format(instr, "scvtfd 'vd, 'vn"); | |
| 2047 const int64_t rn_val = get_register(rn, instr->RnMode()); | |
| 2048 const double vn_dbl = static_cast<double>(rn_val); | |
| 2049 set_vregisterd(vd, bit_cast<int64_t, double>(vn_dbl)); | |
| 2050 } else if (instr->Bits(16, 5) == 6) { | |
| 2047 // Format(instr, "fmovrd 'rd, 'vn"); | 2051 // 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); | 2052 const int64_t vn_val = get_vregisterd(vn); |
| 2051 set_register(rd, vn_val, R31IsZR); | 2053 set_register(rd, vn_val, R31IsZR); |
| 2052 } else if (instr->Bits(16, 3) == 7) { | 2054 } else if (instr->Bits(16, 5) == 7) { |
| 2053 // Format(instr, "fmovdr 'vd, 'rn"); | 2055 // 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); | 2056 const int64_t rn_val = get_register(rn, R31IsZR); |
| 2057 set_vregisterd(vd, rn_val); | 2057 set_vregisterd(vd, rn_val); |
| 2058 } else if (instr->Bits(16, 5) == 24) { | |
| 2059 // Format(instr, "fcvtzds 'rd, 'vn"); | |
| 2060 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); | |
| 2061 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); | |
| 2058 } else { | 2062 } else { |
| 2059 UnimplementedInstruction(instr); | 2063 UnimplementedInstruction(instr); |
| 2060 } | 2064 } |
| 2061 } | 2065 } |
| 2062 | 2066 |
| 2063 | 2067 |
| 2064 void Simulator::DecodeFPOneSource(Instr* instr) { | 2068 void Simulator::DecodeFPOneSource(Instr* instr) { |
| 2065 const int opc = instr->Bits(15, 2); | 2069 const int opc = instr->Bits(15, 2); |
| 2066 const VRegister vd = instr->VdField(); | 2070 const VRegister vd = instr->VdField(); |
| 2067 const VRegister vn = instr->VnField(); | 2071 const VRegister vn = instr->VnField(); |
| 2068 switch (opc) { | 2072 switch (opc) { |
| 2069 case 0: | 2073 case 0: |
| 2070 // Format("fmovdd 'vd, 'vn"); | 2074 // Format("fmovdd 'vd, 'vn"); |
| 2071 set_vregisterd(vd, get_vregisterd(vn)); | 2075 set_vregisterd(vd, get_vregisterd(vn)); |
| 2072 break; | 2076 break; |
| 2073 default: | 2077 default: |
| 2074 UnimplementedInstruction(instr); | 2078 UnimplementedInstruction(instr); |
| 2075 break; | 2079 break; |
| 2076 } | 2080 } |
| 2077 } | 2081 } |
| 2078 | 2082 |
| 2079 | 2083 |
| 2084 void Simulator::DecodeFPTwoSource(Instr* instr) { | |
| 2085 if (instr->Bits(22, 2) != 1) { | |
| 2086 UnimplementedInstruction(instr); | |
| 2087 return; | |
| 2088 } | |
| 2089 const VRegister vd = instr->VdField(); | |
| 2090 const VRegister vn = instr->VnField(); | |
| 2091 const VRegister vm = instr->VmField(); | |
| 2092 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); | |
| 2093 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm)); | |
| 2094 const int opc = instr->Bits(12, 4); | |
| 2095 double result; | |
| 2096 | |
| 2097 switch (opc) { | |
| 2098 case 0: | |
| 2099 // Format(instr, "fmuld 'vd, 'vn, 'vm"); | |
| 2100 result = vn_val * vm_val; | |
| 2101 break; | |
| 2102 case 1: | |
| 2103 // Format(instr, "fdivd 'vd, 'vn, 'vm"); | |
| 2104 result = vn_val / vm_val; | |
| 2105 break; | |
| 2106 case 2: | |
| 2107 // Format(instr, "faddd 'vd, 'vn, 'vm"); | |
| 2108 result = vn_val + vm_val; | |
| 2109 break; | |
| 2110 case 3: | |
| 2111 // Format(instr, "fsubd 'vd, 'vn, 'vm"); | |
| 2112 result = vn_val - vm_val; | |
| 2113 break; | |
| 2114 default: | |
| 2115 // Unknown(instr); | |
| 2116 break; | |
| 2117 } | |
| 2118 | |
| 2119 set_vregisterd(vd, bit_cast<int64_t, double>(result)); | |
| 2120 } | |
| 2121 | |
| 2122 | |
| 2123 void Simulator::DecodeFPCompare(Instr* instr) { | |
| 2124 const VRegister vn = instr->VnField(); | |
| 2125 const VRegister vm = instr->VmField(); | |
| 2126 const double vn_val = get_vregisterd(vn); | |
| 2127 double vm_val; | |
| 2128 | |
| 2129 if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 0)) { | |
| 2130 // Format(instr, "fcmpd 'vn, 'vm"); | |
| 2131 vm_val = get_vregisterd(vm); | |
| 2132 } else if ((instr->Bit(22) == 1) && (instr->Bits(3, 2) == 1)) { | |
| 2133 if (instr->VmField() == V0) { | |
| 2134 // Format(instr, "fcmpd 'vn, #0.0"); | |
| 2135 vm_val = 0.0; | |
| 2136 } else { | |
| 2137 UnimplementedInstruction(instr); | |
| 2138 return; | |
| 2139 } | |
| 2140 } else { | |
| 2141 UnimplementedInstruction(instr); | |
| 2142 return; | |
| 2143 } | |
| 2144 | |
| 2145 n_flag_ = false; | |
| 2146 z_flag_ = false; | |
| 2147 c_flag_ = false; | |
| 2148 v_flag_ = false; | |
| 2149 | |
| 2150 if (isnan(vn_val) || isnan(vm_val)) { | |
| 2151 c_flag_ = true; | |
| 2152 v_flag_ = true; | |
| 2153 } else if (vn_val == vm_val) { | |
| 2154 z_flag_ = true; | |
| 2155 c_flag_ = true; | |
| 2156 } else if (vn_val < vm_val) { | |
| 2157 n_flag_ = true; | |
| 2158 } else { | |
| 2159 c_flag_ = true; | |
| 2160 } | |
| 2161 } | |
| 2162 | |
| 2163 | |
| 2080 void Simulator::DecodeFP(Instr* instr) { | 2164 void Simulator::DecodeFP(Instr* instr) { |
| 2081 if (instr->IsFPImmOp()) { | 2165 if (instr->IsFPImmOp()) { |
| 2082 DecodeFPImm(instr); | 2166 DecodeFPImm(instr); |
| 2083 } else if (instr->IsFPIntCvtOp()) { | 2167 } else if (instr->IsFPIntCvtOp()) { |
| 2084 DecodeFPIntCvt(instr); | 2168 DecodeFPIntCvt(instr); |
| 2085 } else if (instr->IsFPOneSourceOp()) { | 2169 } else if (instr->IsFPOneSourceOp()) { |
| 2086 DecodeFPOneSource(instr); | 2170 DecodeFPOneSource(instr); |
| 2171 } else if (instr->IsFPTwoSourceOp()) { | |
| 2172 DecodeFPTwoSource(instr); | |
| 2173 } else if (instr->IsFPCompareOp()) { | |
| 2174 DecodeFPCompare(instr); | |
| 2087 } else { | 2175 } else { |
| 2088 UnimplementedInstruction(instr); | 2176 UnimplementedInstruction(instr); |
| 2089 } | 2177 } |
| 2090 } | 2178 } |
| 2091 | 2179 |
| 2092 | 2180 |
| 2093 void Simulator::DecodeDPSimd2(Instr* instr) { | 2181 void Simulator::DecodeDPSimd2(Instr* instr) { |
| 2094 if (instr->IsFPOp()) { | 2182 if (instr->IsFPOp()) { |
| 2095 DecodeFP(instr); | 2183 DecodeFP(instr); |
| 2096 } else { | 2184 } else { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2286 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 2374 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 2287 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 2375 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 2288 buf->Longjmp(); | 2376 buf->Longjmp(); |
| 2289 } | 2377 } |
| 2290 | 2378 |
| 2291 } // namespace dart | 2379 } // namespace dart |
| 2292 | 2380 |
| 2293 #endif // !defined(HOST_ARCH_ARM64) | 2381 #endif // !defined(HOST_ARCH_ARM64) |
| 2294 | 2382 |
| 2295 #endif // defined TARGET_ARCH_ARM64 | 2383 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |