OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
10 | 10 |
(...skipping 3276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3287 } | 3287 } |
3288 | 3288 |
3289 case LFSU: | 3289 case LFSU: |
3290 case LFS: { | 3290 case LFS: { |
3291 int frt = instr->RTValue(); | 3291 int frt = instr->RTValue(); |
3292 int ra = instr->RAValue(); | 3292 int ra = instr->RAValue(); |
3293 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3293 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
3294 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3294 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
3295 int32_t val = ReadW(ra_val + offset, instr); | 3295 int32_t val = ReadW(ra_val + offset, instr); |
3296 float* fptr = reinterpret_cast<float*>(&val); | 3296 float* fptr = reinterpret_cast<float*>(&val); |
3297 // Conversion using double changes sNan to qNan on ia32/x64 | |
3298 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | 3297 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
3299 if (val == 0x7fa00000) { | 3298 // Conversion using double changes sNan to qNan on ia32/x64 |
3300 set_d_register(frt, 0x7ff4000000000000); | 3299 if ((val & 0x7f800000) == 0x7f800000) { |
| 3300 int64_t dval = static_cast<int64_t>(val); |
| 3301 dval = ((dval & 0xc0000000) << 32) | ((dval & 0x40000000) << 31) | |
| 3302 ((dval & 0x40000000) << 30) | ((dval & 0x7fffffff) << 29) | 0x0; |
| 3303 set_d_register(frt, dval); |
3301 } else { | 3304 } else { |
3302 #endif | |
3303 set_d_register_from_double(frt, static_cast<double>(*fptr)); | 3305 set_d_register_from_double(frt, static_cast<double>(*fptr)); |
3304 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3305 } | 3306 } |
| 3307 #else |
| 3308 set_d_register_from_double(frt, static_cast<double>(*fptr)); |
3306 #endif | 3309 #endif |
3307 if (opcode == LFSU) { | 3310 if (opcode == LFSU) { |
3308 DCHECK(ra != 0); | 3311 DCHECK(ra != 0); |
3309 set_register(ra, ra_val + offset); | 3312 set_register(ra, ra_val + offset); |
3310 } | 3313 } |
3311 break; | 3314 break; |
3312 } | 3315 } |
3313 | 3316 |
3314 case LFDU: | 3317 case LFDU: |
3315 case LFD: { | 3318 case LFD: { |
(...skipping 11 matching lines...) Expand all Loading... |
3327 } | 3330 } |
3328 | 3331 |
3329 case STFSU: { | 3332 case STFSU: { |
3330 case STFS: | 3333 case STFS: |
3331 int frs = instr->RSValue(); | 3334 int frs = instr->RSValue(); |
3332 int ra = instr->RAValue(); | 3335 int ra = instr->RAValue(); |
3333 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | 3336 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
3334 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | 3337 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
3335 float frs_val = static_cast<float>(get_double_from_d_register(frs)); | 3338 float frs_val = static_cast<float>(get_double_from_d_register(frs)); |
3336 int32_t* p; | 3339 int32_t* p; |
3337 // Conversion using double changes sNan to qNan on ia32/x64 | |
3338 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | 3340 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
3339 int64_t frs_isnan = get_d_register(frs); | 3341 // Conversion using double changes sNan to qNan on ia32/x64 |
3340 int32_t frs_nan_single = 0x7fa00000; | 3342 int32_t sval = 0; |
3341 if (frs_isnan == 0x7ff4000000000000) { | 3343 int64_t dval = get_d_register(frs); |
3342 p = &frs_nan_single; | 3344 if ((dval & 0x7ff0000000000000) == 0x7ff0000000000000) { |
| 3345 sval = ((dval & 0xc000000000000000) >> 32) | |
| 3346 ((dval & 0x07ffffffe0000000) >> 29); |
| 3347 p = &sval; |
3343 } else { | 3348 } else { |
3344 #endif | |
3345 p = reinterpret_cast<int32_t*>(&frs_val); | 3349 p = reinterpret_cast<int32_t*>(&frs_val); |
3346 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3347 } | 3350 } |
| 3351 #else |
| 3352 p = reinterpret_cast<int32_t*>(&frs_val); |
3348 #endif | 3353 #endif |
3349 WriteW(ra_val + offset, *p, instr); | 3354 WriteW(ra_val + offset, *p, instr); |
3350 if (opcode == STFSU) { | 3355 if (opcode == STFSU) { |
3351 DCHECK(ra != 0); | 3356 DCHECK(ra != 0); |
3352 set_register(ra, ra_val + offset); | 3357 set_register(ra, ra_val + offset); |
3353 } | 3358 } |
3354 break; | 3359 break; |
3355 } | 3360 } |
3356 | 3361 |
3357 case STFDU: | 3362 case STFDU: |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3992 int fra = instr->RAValue(); | 3997 int fra = instr->RAValue(); |
3993 int frb = instr->RBValue(); | 3998 int frb = instr->RBValue(); |
3994 double fra_val = get_double_from_d_register(fra); | 3999 double fra_val = get_double_from_d_register(fra); |
3995 double frb_val = get_double_from_d_register(frb); | 4000 double frb_val = get_double_from_d_register(frb); |
3996 double frt_val = fra_val / frb_val; | 4001 double frt_val = fra_val / frb_val; |
3997 set_d_register_from_double(frt, frt_val); | 4002 set_d_register_from_double(frt, frt_val); |
3998 return; | 4003 return; |
3999 } | 4004 } |
4000 | 4005 |
4001 default: { | 4006 default: { |
4002 printf("opcode = %x \n", instr->InstructionBits()); | |
4003 UNIMPLEMENTED(); | 4007 UNIMPLEMENTED(); |
4004 break; | 4008 break; |
4005 } | 4009 } |
4006 } | 4010 } |
4007 } // NOLINT | 4011 } // NOLINT |
4008 | 4012 |
4009 | 4013 |
4010 void Simulator::Trace(Instruction* instr) { | 4014 void Simulator::Trace(Instruction* instr) { |
4011 disasm::NameConverter converter; | 4015 disasm::NameConverter converter; |
4012 disasm::Disassembler dasm(converter); | 4016 disasm::Disassembler dasm(converter); |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4432 } | 4436 } |
4433 processor->prev_ = nullptr; | 4437 processor->prev_ = nullptr; |
4434 processor->next_ = nullptr; | 4438 processor->next_ = nullptr; |
4435 } | 4439 } |
4436 | 4440 |
4437 } // namespace internal | 4441 } // namespace internal |
4438 } // namespace v8 | 4442 } // namespace v8 |
4439 | 4443 |
4440 #endif // USE_SIMULATOR | 4444 #endif // USE_SIMULATOR |
4441 #endif // V8_TARGET_ARCH_PPC | 4445 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |