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 2187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2198 idx5 = imm5 >> 4; | 2198 idx5 = imm5 >> 4; |
2199 element_bytes = 8; | 2199 element_bytes = 8; |
2200 } else { | 2200 } else { |
2201 UnimplementedInstruction(instr); | 2201 UnimplementedInstruction(instr); |
2202 return; | 2202 return; |
2203 } | 2203 } |
2204 ASSERT((idx4 != -1) && (idx5 != -1)); | 2204 ASSERT((idx4 != -1) && (idx5 != -1)); |
2205 | 2205 |
2206 const VRegister vd = instr->VdField(); | 2206 const VRegister vd = instr->VdField(); |
2207 const VRegister vn = instr->VnField(); | 2207 const VRegister vn = instr->VnField(); |
2208 if ((Q == 1) && (op == 0) && (imm4 == 0)) { | 2208 const Register rn = instr->RnField(); |
| 2209 const Register rd = instr->RdField(); |
| 2210 if ((op == 0) && (imm4 == 7)) { |
| 2211 if (Q == 0) { |
| 2212 // Format(instr, "vmovrs 'rd, 'vn'idx5"); |
| 2213 set_wregister(rd, get_vregisters(vn, idx5), R31IsZR); |
| 2214 } else { |
| 2215 // Format(instr, "vmovrd 'rd, 'vn'idx5"); |
| 2216 set_register(rd, get_vregisterd(vn, idx5), R31IsZR); |
| 2217 } |
| 2218 } else if ((Q == 1) && (op == 0) && (imm4 == 0)) { |
2209 // Format(instr, "vdup'csz 'vd, 'vn'idx5"); | 2219 // Format(instr, "vdup'csz 'vd, 'vn'idx5"); |
2210 if (element_bytes == 4) { | 2220 if (element_bytes == 4) { |
2211 for (int i = 0; i < 4; i++) { | 2221 for (int i = 0; i < 4; i++) { |
2212 set_vregisters(vd, i, get_vregisters(vn, idx5)); | 2222 set_vregisters(vd, i, get_vregisters(vn, idx5)); |
2213 } | 2223 } |
2214 } else if (element_bytes == 8) { | 2224 } else if (element_bytes == 8) { |
2215 for (int i = 0; i < 2; i++) { | 2225 for (int i = 0; i < 2; i++) { |
2216 set_vregisterd(vd, i, get_vregisterd(vn, idx5)); | 2226 set_vregisterd(vd, i, get_vregisterd(vn, idx5)); |
2217 } | 2227 } |
2218 } else { | 2228 } else { |
2219 UnimplementedInstruction(instr); | 2229 UnimplementedInstruction(instr); |
2220 return; | 2230 return; |
2221 } | 2231 } |
| 2232 } else if ((Q == 1) && (op == 0) && (imm4 == 3)) { |
| 2233 // Format(instr, "vins'csz 'vd'idx5, 'rn"); |
| 2234 if (element_bytes == 4) { |
| 2235 set_vregisters(vd, idx5, get_wregister(rn, R31IsZR)); |
| 2236 } else if (element_bytes == 8) { |
| 2237 set_vregisterd(vd, idx5, get_register(rn, R31IsZR)); |
| 2238 } else { |
| 2239 UnimplementedInstruction(instr); |
| 2240 } |
| 2241 } else if ((Q == 1) && (op == 0) && (imm4 == 1)) { |
| 2242 // Format(instr, "vdup'csz 'vd, 'rn"); |
| 2243 if (element_bytes == 4) { |
| 2244 for (int i = 0; i < 4; i++) { |
| 2245 set_vregisters(vd, i, get_wregister(rn, R31IsZR)); |
| 2246 } |
| 2247 } else if (element_bytes == 8) { |
| 2248 for (int i = 0; i < 2; i++) { |
| 2249 set_vregisterd(vd, i, get_register(rn, R31IsZR)); |
| 2250 } |
| 2251 } else { |
| 2252 UnimplementedInstruction(instr); |
| 2253 return; |
| 2254 } |
2222 } else if ((Q == 1) && (op == 1)) { | 2255 } else if ((Q == 1) && (op == 1)) { |
2223 // Format(instr, "vins'csz 'vd'idx5, 'vn'idx4"); | 2256 // Format(instr, "vins'csz 'vd'idx5, 'vn'idx4"); |
2224 if (element_bytes == 4) { | 2257 if (element_bytes == 4) { |
2225 set_vregisters(vd, idx5, get_vregisters(vn, idx4)); | 2258 set_vregisters(vd, idx5, get_vregisters(vn, idx4)); |
2226 } else if (element_bytes == 8) { | 2259 } else if (element_bytes == 8) { |
2227 set_vregisterd(vd, idx5, get_vregisterd(vn, idx4)); | 2260 set_vregisterd(vd, idx5, get_vregisterd(vn, idx4)); |
2228 } else { | 2261 } else { |
2229 UnimplementedInstruction(instr); | 2262 UnimplementedInstruction(instr); |
2230 } | 2263 } |
2231 } else { | 2264 } else { |
(...skipping 11 matching lines...) Expand all Loading... |
2243 UnimplementedInstruction(instr); | 2276 UnimplementedInstruction(instr); |
2244 return; | 2277 return; |
2245 } | 2278 } |
2246 | 2279 |
2247 const VRegister vd = instr->VdField(); | 2280 const VRegister vd = instr->VdField(); |
2248 const VRegister vn = instr->VnField(); | 2281 const VRegister vn = instr->VnField(); |
2249 const VRegister vm = instr->VmField(); | 2282 const VRegister vm = instr->VmField(); |
2250 if (instr->Bit(22) == 0) { | 2283 if (instr->Bit(22) == 0) { |
2251 // f32 case. | 2284 // f32 case. |
2252 for (int idx = 0; idx < 4; idx++) { | 2285 for (int idx = 0; idx < 4; idx++) { |
2253 const float vn_val = bit_cast<float, int32_t>(get_vregisters(vn, idx)); | 2286 const int32_t vn_val = get_vregisters(vn, idx); |
2254 const float vm_val = bit_cast<float, int32_t>(get_vregisters(vm, idx)); | 2287 const int32_t vm_val = get_vregisters(vm, idx); |
2255 float res = 0.0; | 2288 const float vn_flt = bit_cast<float, int32_t>(vn_val); |
2256 if ((U == 0) && (opcode == 0x1a)) { | 2289 const float vm_flt = bit_cast<float, int32_t>(vm_val); |
| 2290 int32_t res = 0.0; |
| 2291 if ((U == 0) && (opcode == 0x3)) { |
| 2292 if (instr->Bit(23) == 0) { |
| 2293 // Format(instr, "vand 'vd, 'vn, 'vm"); |
| 2294 res = vn_val & vm_val; |
| 2295 } else { |
| 2296 // Format(instr, "vorr 'vd, 'vn, 'vm"); |
| 2297 res = vn_val | vm_val; |
| 2298 } |
| 2299 } else if ((U == 1) && (opcode == 0x3)) { |
| 2300 // Format(instr, "veor 'vd, 'vn, 'vm"); |
| 2301 res = vn_val ^ vm_val; |
| 2302 } else if ((U == 0) && (opcode == 0x10)) { |
| 2303 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); |
| 2304 res = vn_val + vm_val; |
| 2305 } else if ((U == 1) && (opcode == 0x10)) { |
| 2306 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); |
| 2307 res = vn_val - vm_val; |
| 2308 } else if ((U == 0) && (opcode == 0x1a)) { |
2257 if (instr->Bit(23) == 0) { | 2309 if (instr->Bit(23) == 0) { |
2258 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); | 2310 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); |
2259 res = vn_val + vm_val; | 2311 res = bit_cast<int32_t, float>(vn_flt + vm_flt); |
2260 } else { | 2312 } else { |
2261 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); | 2313 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); |
2262 res = vn_val - vm_val; | 2314 res = bit_cast<int32_t, float>(vn_flt - vm_flt); |
2263 } | 2315 } |
2264 } else if ((U == 1) && (opcode == 0x1b)) { | 2316 } else if ((U == 1) && (opcode == 0x1b)) { |
2265 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm"); | 2317 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm"); |
2266 res = vn_val * vm_val; | 2318 res = bit_cast<int32_t, float>(vn_flt * vm_flt); |
2267 } else if ((U == 1) && (opcode == 0x1f)) { | 2319 } else if ((U == 1) && (opcode == 0x1f)) { |
2268 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm"); | 2320 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm"); |
2269 res = vn_val / vm_val; | 2321 res = bit_cast<int32_t, float>(vn_flt / vm_flt); |
2270 } else { | 2322 } else { |
2271 UnimplementedInstruction(instr); | 2323 UnimplementedInstruction(instr); |
2272 return; | 2324 return; |
2273 } | 2325 } |
2274 set_vregisters(vd, idx, bit_cast<int32_t, float>(res)); | 2326 set_vregisters(vd, idx, res); |
2275 } | 2327 } |
2276 } else { | 2328 } else { |
2277 // f64 case. | 2329 // f64 case. |
2278 for (int idx = 0; idx < 2; idx++) { | 2330 for (int idx = 0; idx < 2; idx++) { |
2279 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn, idx)); | 2331 const int64_t vn_val = get_vregisterd(vn, idx); |
2280 const double vm_val = bit_cast<double, int64_t>(get_vregisterd(vm, idx)); | 2332 const int64_t vm_val = get_vregisterd(vm, idx); |
2281 double res = 0.0; | 2333 const double vn_dbl = bit_cast<double, int64_t>(vn_val); |
2282 if ((U == 0) && (opcode == 0x1a)) { | 2334 const double vm_dbl = bit_cast<double, int64_t>(vm_val); |
| 2335 int64_t res = 0.0; |
| 2336 if ((U == 0) && (opcode == 0x3)) { |
| 2337 if (instr->Bit(23) == 0) { |
| 2338 // Format(instr, "vand 'vd, 'vn, 'vm"); |
| 2339 res = vn_val & vm_val; |
| 2340 } else { |
| 2341 // Format(instr, "vorr 'vd, 'vn, 'vm"); |
| 2342 res = vn_val | vm_val; |
| 2343 } |
| 2344 } else if ((U == 1) && (opcode == 0x3)) { |
| 2345 // Format(instr, "veor 'vd, 'vn, 'vm"); |
| 2346 res = vn_val ^ vm_val; |
| 2347 } else if ((U == 0) && (opcode == 0x10)) { |
| 2348 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); |
| 2349 res = vn_val + vm_val; |
| 2350 } else if ((U == 1) && (opcode == 0x10)) { |
| 2351 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); |
| 2352 res = vn_val - vm_val; |
| 2353 } else if ((U == 0) && (opcode == 0x1a)) { |
2283 if (instr->Bit(23) == 0) { | 2354 if (instr->Bit(23) == 0) { |
2284 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); | 2355 // Format(instr, "vadd'vsz 'vd, 'vn, 'vm"); |
2285 res = vn_val + vm_val; | 2356 res = bit_cast<int64_t, double>(vn_dbl + vm_dbl); |
2286 } else { | 2357 } else { |
2287 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); | 2358 // Format(instr, "vsub'vsz 'vd, 'vn, 'vm"); |
2288 res = vn_val - vm_val; | 2359 res = bit_cast<int64_t, double>(vn_dbl - vm_dbl); |
2289 } | 2360 } |
2290 } else if ((U == 1) && (opcode == 0x1b)) { | 2361 } else if ((U == 1) && (opcode == 0x1b)) { |
2291 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm"); | 2362 // Format(instr, "vmul'vsz 'vd, 'vn, 'vm"); |
2292 res = vn_val * vm_val; | 2363 res = bit_cast<int64_t, double>(vn_dbl * vm_dbl); |
2293 } else if ((U == 1) && (opcode == 0x1f)) { | 2364 } else if ((U == 1) && (opcode == 0x1f)) { |
2294 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm"); | 2365 // Format(instr, "vdiv'vsz 'vd, 'vn, 'vm"); |
2295 res = vn_val / vm_val; | 2366 res = bit_cast<int64_t, double>(vn_dbl / vm_dbl); |
2296 } else { | 2367 } else { |
2297 UnimplementedInstruction(instr); | 2368 UnimplementedInstruction(instr); |
2298 return; | 2369 return; |
2299 } | 2370 } |
2300 set_vregisterd(vd, idx, bit_cast<int64_t, double>(res)); | 2371 set_vregisterd(vd, idx, res); |
2301 } | 2372 } |
2302 } | 2373 } |
2303 } | 2374 } |
2304 | 2375 |
2305 | 2376 |
| 2377 void Simulator::DecodeSIMDTwoReg(Instr* instr) { |
| 2378 const int32_t Q = instr->Bit(30); |
| 2379 const int32_t U = instr->Bit(29); |
| 2380 const int32_t op = instr->Bits(12, 5); |
| 2381 const int32_t sz = instr->Bits(22, 2); |
| 2382 const VRegister vd = instr->VdField(); |
| 2383 const VRegister vn = instr->VnField(); |
| 2384 |
| 2385 if ((Q == 1) && (U == 1) && (op == 5)) { |
| 2386 // Format(instr, "vnot 'vd, 'vn"); |
| 2387 for (int i = 0; i < 2; i++) { |
| 2388 set_vregisterd(vd, i, ~get_vregisterd(vn, i)); |
| 2389 } |
| 2390 } else if ((U == 0) && (op == 0xf)) { |
| 2391 if (sz == 2) { |
| 2392 // Format(instr, "vabss 'vd, 'vn"); |
| 2393 for (int i = 0; i < 4; i++) { |
| 2394 const int32_t vn_val = get_vregisters(vn, i); |
| 2395 const float vn_flt = bit_cast<float, int32_t>(vn_val); |
| 2396 set_vregisters(vd, i, bit_cast<int32_t, float>(fabsf(vn_flt))); |
| 2397 } |
| 2398 } else if (sz == 3) { |
| 2399 // Format(instr, "vabsd 'vd, 'vn"); |
| 2400 for (int i = 0; i < 2; i++) { |
| 2401 const int64_t vn_val = get_vregisterd(vn, i); |
| 2402 const double vn_dbl = bit_cast<double, int64_t>(vn_val); |
| 2403 set_vregisterd(vd, i, bit_cast<int64_t, double>(fabs(vn_dbl))); |
| 2404 } |
| 2405 } else { |
| 2406 UnimplementedInstruction(instr); |
| 2407 } |
| 2408 } else if ((U == 1) && (op == 0xf)) { |
| 2409 if (sz == 2) { |
| 2410 // Format(instr, "vnegs 'vd, 'vn"); |
| 2411 for (int i = 0; i < 4; i++) { |
| 2412 const int32_t vn_val = get_vregisters(vn, i); |
| 2413 const float vn_flt = bit_cast<float, int32_t>(vn_val); |
| 2414 set_vregisters(vd, i, bit_cast<int32_t, float>(-vn_flt)); |
| 2415 } |
| 2416 } else if (sz == 3) { |
| 2417 // Format(instr, "vnegd 'vd, 'vn"); |
| 2418 for (int i = 0; i < 2; i++) { |
| 2419 const int64_t vn_val = get_vregisterd(vn, i); |
| 2420 const double vn_dbl = bit_cast<double, int64_t>(vn_val); |
| 2421 set_vregisterd(vd, i, bit_cast<int64_t, double>(-vn_dbl)); |
| 2422 } |
| 2423 } else { |
| 2424 UnimplementedInstruction(instr); |
| 2425 } |
| 2426 } else { |
| 2427 UnimplementedInstruction(instr); |
| 2428 } |
| 2429 } |
| 2430 |
| 2431 |
2306 void Simulator::DecodeDPSimd1(Instr* instr) { | 2432 void Simulator::DecodeDPSimd1(Instr* instr) { |
2307 if (instr->IsSIMDCopyOp()) { | 2433 if (instr->IsSIMDCopyOp()) { |
2308 DecodeSIMDCopy(instr); | 2434 DecodeSIMDCopy(instr); |
2309 } else if (instr->IsSIMDThreeSameOp()) { | 2435 } else if (instr->IsSIMDThreeSameOp()) { |
2310 DecodeSIMDThreeSame(instr); | 2436 DecodeSIMDThreeSame(instr); |
| 2437 } else if (instr->IsSIMDTwoRegOp()) { |
| 2438 DecodeSIMDTwoReg(instr); |
2311 } else { | 2439 } else { |
2312 UnimplementedInstruction(instr); | 2440 UnimplementedInstruction(instr); |
2313 } | 2441 } |
2314 } | 2442 } |
2315 | 2443 |
2316 | 2444 |
2317 void Simulator::DecodeFPImm(Instr* instr) { | 2445 void Simulator::DecodeFPImm(Instr* instr) { |
2318 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || | 2446 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) || |
2319 (instr->Bits(5, 5) != 0)) { | 2447 (instr->Bits(5, 5) != 0)) { |
2320 UnimplementedInstruction(instr); | 2448 UnimplementedInstruction(instr); |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2726 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 2854 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
2727 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 2855 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
2728 buf->Longjmp(); | 2856 buf->Longjmp(); |
2729 } | 2857 } |
2730 | 2858 |
2731 } // namespace dart | 2859 } // namespace dart |
2732 | 2860 |
2733 #endif // !defined(HOST_ARCH_ARM64) | 2861 #endif // !defined(HOST_ARCH_ARM64) |
2734 | 2862 |
2735 #endif // defined TARGET_ARCH_ARM64 | 2863 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |