OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 3342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3353 UNREACHABLE(); | 3353 UNREACHABLE(); |
3354 break; | 3354 break; |
3355 } | 3355 } |
3356 set_q_register(vd, q_data); | 3356 set_q_register(vd, q_data); |
3357 } | 3357 } |
3358 } else if ((instr->VLValue() == 0x1) && (instr->VCValue() == 0x1)) { | 3358 } else if ((instr->VLValue() == 0x1) && (instr->VCValue() == 0x1)) { |
3359 // vmov (scalar to ARM core register) | 3359 // vmov (scalar to ARM core register) |
3360 int vn = instr->VFPNRegValue(kDoublePrecision); | 3360 int vn = instr->VFPNRegValue(kDoublePrecision); |
3361 int rt = instr->RtValue(); | 3361 int rt = instr->RtValue(); |
3362 int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5); | 3362 int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5); |
3363 uint64_t data; | |
3364 get_d_register(vn, &data); | |
3363 if ((opc1_opc2 & 0xb) == 0) { | 3365 if ((opc1_opc2 & 0xb) == 0) { |
3364 // NeonS32 / NeonU32 | 3366 // NeonS32 / NeonU32 |
3365 double dn_value = get_double_from_d_register(vn); | 3367 int32_t int_data[2]; |
3366 int32_t data[2]; | 3368 memcpy(int_data, &data, sizeof(int_data)); |
3367 memcpy(data, &dn_value, 8); | 3369 set_register(rt, int_data[instr->Bit(21)]); |
bbudge
2016/12/16 22:24:29
Not sure why, but this doesn't work correctly some
| |
3368 set_register(rt, data[instr->Bit(21)]); | |
3369 } else { | 3370 } else { |
3370 uint64_t data; | 3371 uint64_t data; |
3371 get_d_register(vn, &data); | 3372 get_d_register(vn, &data); |
3372 bool u = instr->Bit(23) != 0; | 3373 bool u = instr->Bit(23) != 0; |
3373 if ((opc1_opc2 & 0x8) != 0) { | 3374 if ((opc1_opc2 & 0x8) != 0) { |
3374 // NeonS8 / NeonU8 | 3375 // NeonS8 / NeonU8 |
3375 int i = opc1_opc2 & 0x7; | 3376 int i = opc1_opc2 & 0x7; |
3376 int shift = i * kBitsPerByte; | 3377 int shift = i * kBitsPerByte; |
3377 uint32_t scalar = (data >> shift) & 0xFFu; | 3378 uint32_t scalar = (data >> shift) & 0xFFu; |
3378 if (!u && (scalar & 0x80) != 0) scalar |= 0xffffff00; | 3379 if (!u && (scalar & 0x80) != 0) scalar |= 0xffffff00; |
(...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4122 q_data[i] = bit_cast<uint32_t>( | 4123 q_data[i] = bit_cast<uint32_t>( |
4123 std::round(static_cast<float>(bit_cast<int32_t>(q_data[i])))); | 4124 std::round(static_cast<float>(bit_cast<int32_t>(q_data[i])))); |
4124 break; | 4125 break; |
4125 case 1: | 4126 case 1: |
4126 // f32 <- u32, round towards nearest. | 4127 // f32 <- u32, round towards nearest. |
4127 q_data[i] = | 4128 q_data[i] = |
4128 bit_cast<uint32_t>(std::round(static_cast<float>(q_data[i]))); | 4129 bit_cast<uint32_t>(std::round(static_cast<float>(q_data[i]))); |
4129 break; | 4130 break; |
4130 case 2: | 4131 case 2: |
4131 // s32 <- f32, round to zero. | 4132 // s32 <- f32, round to zero. |
4132 q_data[i] = static_cast<uint32_t>( | 4133 q_data[i] = bit_cast<uint32_t>( |
bbudge
2016/12/16 22:24:29
I missed these, but I think the behavior is undefi
|
Rodolph Perfetta
2016/12/19 13:43:00
static_cast int32_t -> uint32_t is well defined. b
bbudge
2016/12/20 00:57:13
I googled a little and when values are outside th
|
4133 ConvertDoubleToInt(bit_cast<float>(q_data[i]), false, RZ)); | 4134 ConvertDoubleToInt(bit_cast<float>(q_data[i]), false, RZ)); |
4134 break; | 4135 break; |
4135 case 3: | 4136 case 3: |
4136 // u32 <- f32, round to zero. | 4137 // u32 <- f32, round to zero. |
4137 q_data[i] = static_cast<uint32_t>( | 4138 q_data[i] = bit_cast<uint32_t>( |
Rodolph Perfetta
2016/12/19 13:43:00
ditto.
| |
4138 ConvertDoubleToInt(bit_cast<float>(q_data[i]), true, RZ)); | 4139 ConvertDoubleToInt(bit_cast<float>(q_data[i]), true, RZ)); |
4139 break; | 4140 break; |
4140 } | 4141 } |
4141 } | 4142 } |
4142 set_q_register(Vd, q_data); | 4143 set_q_register(Vd, q_data); |
4143 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && | 4144 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && |
4144 (instr->Bit(4) == 0)) { | 4145 (instr->Bit(4) == 0)) { |
4145 if (instr->Bit(6) == 0) { | 4146 if (instr->Bit(6) == 0) { |
4146 // vswp Dd, Dm. | 4147 // vswp Dd, Dm. |
4147 uint64_t dval, mval; | 4148 uint64_t dval, mval; |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4717 set_register(sp, current_sp + sizeof(uintptr_t)); | 4718 set_register(sp, current_sp + sizeof(uintptr_t)); |
4718 return address; | 4719 return address; |
4719 } | 4720 } |
4720 | 4721 |
4721 } // namespace internal | 4722 } // namespace internal |
4722 } // namespace v8 | 4723 } // namespace v8 |
4723 | 4724 |
4724 #endif // USE_SIMULATOR | 4725 #endif // USE_SIMULATOR |
4725 | 4726 |
4726 #endif // V8_TARGET_ARCH_ARM | 4727 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |