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 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 WriteW(reinterpret_cast<int32_t>(address), | 1628 WriteW(reinterpret_cast<int32_t>(address), |
1629 get_sinteger_from_s_register(reg), instr); | 1629 get_sinteger_from_s_register(reg), instr); |
1630 } | 1630 } |
1631 address += 1; | 1631 address += 1; |
1632 } else { | 1632 } else { |
1633 if (load) { | 1633 if (load) { |
1634 int32_t data[] = { | 1634 int32_t data[] = { |
1635 ReadW(reinterpret_cast<int32_t>(address), instr), | 1635 ReadW(reinterpret_cast<int32_t>(address), instr), |
1636 ReadW(reinterpret_cast<int32_t>(address + 1), instr) | 1636 ReadW(reinterpret_cast<int32_t>(address + 1), instr) |
1637 }; | 1637 }; |
1638 double d; | 1638 set_d_register(reg, reinterpret_cast<uint32_t*>(data)); |
1639 memcpy(&d, data, 8); | |
1640 set_d_register_from_double(reg, d); | |
1641 } else { | 1639 } else { |
1642 int32_t data[2]; | 1640 uint32_t data[2]; |
1643 double d = get_double_from_d_register(reg); | 1641 get_d_register(reg, data); |
1644 memcpy(data, &d, 8); | |
1645 WriteW(reinterpret_cast<int32_t>(address), data[0], instr); | 1642 WriteW(reinterpret_cast<int32_t>(address), data[0], instr); |
1646 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr); | 1643 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr); |
1647 } | 1644 } |
1648 address += 2; | 1645 address += 2; |
1649 } | 1646 } |
1650 } | 1647 } |
1651 DCHECK(reinterpret_cast<intptr_t>(address) - operand_size == end_address); | 1648 DCHECK(reinterpret_cast<intptr_t>(address) - operand_size == end_address); |
1652 if (instr->HasW()) { | 1649 if (instr->HasW()) { |
1653 set_register(instr->RnValue(), rn_val); | 1650 set_register(instr->RnValue(), rn_val); |
1654 } | 1651 } |
(...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 int vn = instr->VFPNRegValue(kDoublePrecision); | 3026 int vn = instr->VFPNRegValue(kDoublePrecision); |
3030 | 3027 |
3031 if (instr->Bit(4) == 0) { | 3028 if (instr->Bit(4) == 0) { |
3032 if (instr->Opc1Value() == 0x7) { | 3029 if (instr->Opc1Value() == 0x7) { |
3033 // Other data processing instructions | 3030 // Other data processing instructions |
3034 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { | 3031 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { |
3035 // vmov register to register. | 3032 // vmov register to register. |
3036 if (instr->SzValue() == 0x1) { | 3033 if (instr->SzValue() == 0x1) { |
3037 int m = instr->VFPMRegValue(kDoublePrecision); | 3034 int m = instr->VFPMRegValue(kDoublePrecision); |
3038 int d = instr->VFPDRegValue(kDoublePrecision); | 3035 int d = instr->VFPDRegValue(kDoublePrecision); |
3039 set_d_register_from_double(d, get_double_from_d_register(m)); | 3036 uint32_t data[2]; |
| 3037 get_d_register(m, data); |
| 3038 set_d_register(d, data); |
3040 } else { | 3039 } else { |
3041 int m = instr->VFPMRegValue(kSinglePrecision); | 3040 int m = instr->VFPMRegValue(kSinglePrecision); |
3042 int d = instr->VFPDRegValue(kSinglePrecision); | 3041 int d = instr->VFPDRegValue(kSinglePrecision); |
3043 set_s_register_from_float(d, get_float_from_s_register(m)); | 3042 set_s_register_from_float(d, get_float_from_s_register(m)); |
3044 } | 3043 } |
3045 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { | 3044 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { |
3046 // vabs | 3045 // vabs |
3047 double dm_value = get_double_from_d_register(vm); | 3046 double dm_value = get_double_from_d_register(vm); |
3048 double dd_value = std::fabs(dm_value); | 3047 double dd_value = std::fabs(dm_value); |
3049 dd_value = canonicalizeNaN(dd_value); | 3048 dd_value = canonicalizeNaN(dd_value); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3165 } | 3164 } |
3166 } else { | 3165 } else { |
3167 if ((instr->VCValue() == 0x0) && | 3166 if ((instr->VCValue() == 0x0) && |
3168 (instr->VAValue() == 0x0)) { | 3167 (instr->VAValue() == 0x0)) { |
3169 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); | 3168 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
3170 } else if ((instr->VLValue() == 0x0) && | 3169 } else if ((instr->VLValue() == 0x0) && |
3171 (instr->VCValue() == 0x1) && | 3170 (instr->VCValue() == 0x1) && |
3172 (instr->Bit(23) == 0x0)) { | 3171 (instr->Bit(23) == 0x0)) { |
3173 // vmov (ARM core register to scalar) | 3172 // vmov (ARM core register to scalar) |
3174 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4); | 3173 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4); |
3175 double dd_value = get_double_from_d_register(vd); | 3174 uint32_t data[2]; |
3176 int32_t data[2]; | 3175 get_d_register(vd, data); |
3177 memcpy(data, &dd_value, 8); | |
3178 data[instr->Bit(21)] = get_register(instr->RtValue()); | 3176 data[instr->Bit(21)] = get_register(instr->RtValue()); |
3179 memcpy(&dd_value, data, 8); | 3177 set_d_register(vd, data); |
3180 set_d_register_from_double(vd, dd_value); | |
3181 } else if ((instr->VLValue() == 0x1) && | 3178 } else if ((instr->VLValue() == 0x1) && |
3182 (instr->VCValue() == 0x1) && | 3179 (instr->VCValue() == 0x1) && |
3183 (instr->Bit(23) == 0x0)) { | 3180 (instr->Bit(23) == 0x0)) { |
3184 // vmov (scalar to ARM core register) | 3181 // vmov (scalar to ARM core register) |
3185 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4); | 3182 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4); |
3186 double dn_value = get_double_from_d_register(vn); | 3183 double dn_value = get_double_from_d_register(vn); |
3187 int32_t data[2]; | 3184 int32_t data[2]; |
3188 memcpy(data, &dn_value, 8); | 3185 memcpy(data, &dn_value, 8); |
3189 set_register(instr->RtValue(), data[instr->Bit(21)]); | 3186 set_register(instr->RtValue(), data[instr->Bit(21)]); |
3190 } else if ((instr->VLValue() == 0x1) && | 3187 } else if ((instr->VLValue() == 0x1) && |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3527 switch (instr->OpcodeValue()) { | 3524 switch (instr->OpcodeValue()) { |
3528 case 0x2: | 3525 case 0x2: |
3529 // Load and store double to two GP registers | 3526 // Load and store double to two GP registers |
3530 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) { | 3527 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) { |
3531 UNIMPLEMENTED(); // Not used by V8. | 3528 UNIMPLEMENTED(); // Not used by V8. |
3532 } else { | 3529 } else { |
3533 int rt = instr->RtValue(); | 3530 int rt = instr->RtValue(); |
3534 int rn = instr->RnValue(); | 3531 int rn = instr->RnValue(); |
3535 int vm = instr->VFPMRegValue(kDoublePrecision); | 3532 int vm = instr->VFPMRegValue(kDoublePrecision); |
3536 if (instr->HasL()) { | 3533 if (instr->HasL()) { |
3537 int32_t data[2]; | 3534 uint32_t data[2]; |
3538 double d = get_double_from_d_register(vm); | 3535 get_d_register(vm, data); |
3539 memcpy(data, &d, 8); | |
3540 set_register(rt, data[0]); | 3536 set_register(rt, data[0]); |
3541 set_register(rn, data[1]); | 3537 set_register(rn, data[1]); |
3542 } else { | 3538 } else { |
3543 int32_t data[] = { get_register(rt), get_register(rn) }; | 3539 int32_t data[] = { get_register(rt), get_register(rn) }; |
3544 double d; | 3540 set_d_register(vm, reinterpret_cast<uint32_t*>(data)); |
3545 memcpy(&d, data, 8); | |
3546 set_d_register_from_double(vm, d); | |
3547 } | 3541 } |
3548 } | 3542 } |
3549 break; | 3543 break; |
3550 case 0x8: | 3544 case 0x8: |
3551 case 0xA: | 3545 case 0xA: |
3552 case 0xC: | 3546 case 0xC: |
3553 case 0xE: { // Load and store double to memory. | 3547 case 0xE: { // Load and store double to memory. |
3554 int rn = instr->RnValue(); | 3548 int rn = instr->RnValue(); |
3555 int vd = instr->VFPDRegValue(kDoublePrecision); | 3549 int vd = instr->VFPDRegValue(kDoublePrecision); |
3556 int offset = instr->Immed8Value(); | 3550 int offset = instr->Immed8Value(); |
3557 if (!instr->HasU()) { | 3551 if (!instr->HasU()) { |
3558 offset = -offset; | 3552 offset = -offset; |
3559 } | 3553 } |
3560 int32_t address = get_register(rn) + 4 * offset; | 3554 int32_t address = get_register(rn) + 4 * offset; |
3561 if (instr->HasL()) { | 3555 if (instr->HasL()) { |
3562 // Load double from memory: vldr. | 3556 // Load double from memory: vldr. |
3563 int32_t data[] = { | 3557 int32_t data[] = { |
3564 ReadW(address, instr), | 3558 ReadW(address, instr), |
3565 ReadW(address + 4, instr) | 3559 ReadW(address + 4, instr) |
3566 }; | 3560 }; |
3567 double val; | 3561 set_d_register(vd, reinterpret_cast<uint32_t*>(data)); |
3568 memcpy(&val, data, 8); | |
3569 set_d_register_from_double(vd, val); | |
3570 } else { | 3562 } else { |
3571 // Store double to memory: vstr. | 3563 // Store double to memory: vstr. |
3572 int32_t data[2]; | 3564 uint32_t data[2]; |
3573 double val = get_double_from_d_register(vd); | 3565 get_d_register(vd, data); |
3574 memcpy(data, &val, 8); | |
3575 WriteW(address, data[0], instr); | 3566 WriteW(address, data[0], instr); |
3576 WriteW(address + 4, data[1], instr); | 3567 WriteW(address + 4, data[1], instr); |
3577 } | 3568 } |
3578 break; | 3569 break; |
3579 } | 3570 } |
3580 case 0x4: | 3571 case 0x4: |
3581 case 0x5: | 3572 case 0x5: |
3582 case 0x6: | 3573 case 0x6: |
3583 case 0x7: | 3574 case 0x7: |
3584 case 0x9: | 3575 case 0x9: |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4027 uintptr_t address = *stack_slot; | 4018 uintptr_t address = *stack_slot; |
4028 set_register(sp, current_sp + sizeof(uintptr_t)); | 4019 set_register(sp, current_sp + sizeof(uintptr_t)); |
4029 return address; | 4020 return address; |
4030 } | 4021 } |
4031 | 4022 |
4032 } } // namespace v8::internal | 4023 } } // namespace v8::internal |
4033 | 4024 |
4034 #endif // USE_SIMULATOR | 4025 #endif // USE_SIMULATOR |
4035 | 4026 |
4036 #endif // V8_TARGET_ARCH_ARM | 4027 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |