OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 } | 757 } |
758 n_flag_ = false; | 758 n_flag_ = false; |
759 z_flag_ = false; | 759 z_flag_ = false; |
760 c_flag_ = false; | 760 c_flag_ = false; |
761 v_flag_ = false; | 761 v_flag_ = false; |
762 | 762 |
763 // Initializing VFP registers. | 763 // Initializing VFP registers. |
764 // All registers are initialized to zero to start with | 764 // All registers are initialized to zero to start with |
765 // even though s_registers_ & d_registers_ share the same | 765 // even though s_registers_ & d_registers_ share the same |
766 // physical registers in the target. | 766 // physical registers in the target. |
767 for (int i = 0; i < num_s_registers; i++) { | 767 for (int i = 0; i < num_d_registers * 2; i++) { |
768 vfp_register[i] = 0; | 768 vfp_register[i] = 0; |
769 } | 769 } |
770 n_flag_FPSCR_ = false; | 770 n_flag_FPSCR_ = false; |
771 z_flag_FPSCR_ = false; | 771 z_flag_FPSCR_ = false; |
772 c_flag_FPSCR_ = false; | 772 c_flag_FPSCR_ = false; |
773 v_flag_FPSCR_ = false; | 773 v_flag_FPSCR_ = false; |
774 FPSCR_rounding_mode_ = RZ; | 774 FPSCR_rounding_mode_ = RZ; |
775 | 775 |
776 inv_op_vfp_flag_ = false; | 776 inv_op_vfp_flag_ = false; |
777 div_zero_vfp_flag_ = false; | 777 div_zero_vfp_flag_ = false; |
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1606 if (load) { | 1606 if (load) { |
1607 set_s_register_from_sinteger( | 1607 set_s_register_from_sinteger( |
1608 reg, ReadW(reinterpret_cast<int32_t>(address), instr)); | 1608 reg, ReadW(reinterpret_cast<int32_t>(address), instr)); |
1609 } else { | 1609 } else { |
1610 WriteW(reinterpret_cast<int32_t>(address), | 1610 WriteW(reinterpret_cast<int32_t>(address), |
1611 get_sinteger_from_s_register(reg), instr); | 1611 get_sinteger_from_s_register(reg), instr); |
1612 } | 1612 } |
1613 address += 1; | 1613 address += 1; |
1614 } else { | 1614 } else { |
1615 if (load) { | 1615 if (load) { |
1616 set_s_register_from_sinteger( | 1616 int32_t data[] = { |
1617 2 * reg, ReadW(reinterpret_cast<int32_t>(address), instr)); | 1617 ReadW(reinterpret_cast<int32_t>(address), instr), |
1618 set_s_register_from_sinteger( | 1618 ReadW(reinterpret_cast<int32_t>(address + 1), instr) |
1619 2 * reg + 1, ReadW(reinterpret_cast<int32_t>(address + 1), instr)); | 1619 }; |
| 1620 double d; |
| 1621 memcpy(&d, data, 8); |
| 1622 set_d_register_from_double(reg, d); |
1620 } else { | 1623 } else { |
1621 WriteW(reinterpret_cast<int32_t>(address), | 1624 int32_t data[2]; |
1622 get_sinteger_from_s_register(2 * reg), instr); | 1625 double d = get_double_from_d_register(reg); |
1623 WriteW(reinterpret_cast<int32_t>(address + 1), | 1626 memcpy(data, &d, 8); |
1624 get_sinteger_from_s_register(2 * reg + 1), instr); | 1627 WriteW(reinterpret_cast<int32_t>(address), data[0], instr); |
| 1628 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr); |
1625 } | 1629 } |
1626 address += 2; | 1630 address += 2; |
1627 } | 1631 } |
1628 } | 1632 } |
1629 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address); | 1633 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address); |
1630 } | 1634 } |
1631 | 1635 |
1632 | 1636 |
1633 // Calls into the V8 runtime are based on this very simple interface. | 1637 // Calls into the V8 runtime are based on this very simple interface. |
1634 // Note: To be able to return two values from some calls the code in runtime.cc | 1638 // Note: To be able to return two values from some calls the code in runtime.cc |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2803 double dd_value = dn_value / dm_value; | 2807 double dd_value = dn_value / dm_value; |
2804 div_zero_vfp_flag_ = (dm_value == 0); | 2808 div_zero_vfp_flag_ = (dm_value == 0); |
2805 set_d_register_from_double(vd, dd_value); | 2809 set_d_register_from_double(vd, dd_value); |
2806 } else { | 2810 } else { |
2807 UNIMPLEMENTED(); // Not used by V8. | 2811 UNIMPLEMENTED(); // Not used by V8. |
2808 } | 2812 } |
2809 } else { | 2813 } else { |
2810 if ((instr->VCValue() == 0x0) && | 2814 if ((instr->VCValue() == 0x0) && |
2811 (instr->VAValue() == 0x0)) { | 2815 (instr->VAValue() == 0x0)) { |
2812 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); | 2816 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
| 2817 } else if ((instr->VLValue() == 0x0) && |
| 2818 (instr->VCValue() == 0x1) && |
| 2819 (instr->Bit(23) == 0x0)) { |
| 2820 // vmov (ARM core register to scalar) |
| 2821 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4); |
| 2822 double dd_value = get_double_from_d_register(vd); |
| 2823 int32_t data[2]; |
| 2824 memcpy(data, &dd_value, 8); |
| 2825 data[instr->Bit(21)] = get_register(instr->RtValue()); |
| 2826 memcpy(&dd_value, data, 8); |
| 2827 set_d_register_from_double(vd, dd_value); |
2813 } else if ((instr->VLValue() == 0x1) && | 2828 } else if ((instr->VLValue() == 0x1) && |
2814 (instr->VCValue() == 0x0) && | 2829 (instr->VCValue() == 0x0) && |
2815 (instr->VAValue() == 0x7) && | 2830 (instr->VAValue() == 0x7) && |
2816 (instr->Bits(19, 16) == 0x1)) { | 2831 (instr->Bits(19, 16) == 0x1)) { |
2817 // vmrs | 2832 // vmrs |
2818 uint32_t rt = instr->RtValue(); | 2833 uint32_t rt = instr->RtValue(); |
2819 if (rt == 0xF) { | 2834 if (rt == 0xF) { |
2820 Copy_FPSCR_to_APSR(); | 2835 Copy_FPSCR_to_APSR(); |
2821 } else { | 2836 } else { |
2822 // Emulate FPSCR from the Simulator flags. | 2837 // Emulate FPSCR from the Simulator flags. |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3141 // Load/store multiple single from memory: vldm/vstm. | 3156 // Load/store multiple single from memory: vldm/vstm. |
3142 HandleVList(instr); | 3157 HandleVList(instr); |
3143 break; | 3158 break; |
3144 default: | 3159 default: |
3145 UNIMPLEMENTED(); // Not used by V8. | 3160 UNIMPLEMENTED(); // Not used by V8. |
3146 } | 3161 } |
3147 } else if (instr->CoprocessorValue() == 0xB) { | 3162 } else if (instr->CoprocessorValue() == 0xB) { |
3148 switch (instr->OpcodeValue()) { | 3163 switch (instr->OpcodeValue()) { |
3149 case 0x2: | 3164 case 0x2: |
3150 // Load and store double to two GP registers | 3165 // Load and store double to two GP registers |
3151 if (instr->Bits(7, 4) != 0x1) { | 3166 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) { |
3152 UNIMPLEMENTED(); // Not used by V8. | 3167 UNIMPLEMENTED(); // Not used by V8. |
3153 } else { | 3168 } else { |
3154 int rt = instr->RtValue(); | 3169 int rt = instr->RtValue(); |
3155 int rn = instr->RnValue(); | 3170 int rn = instr->RnValue(); |
3156 int vm = instr->VmValue(); | 3171 int vm = instr->VFPMRegValue(kDoublePrecision); |
3157 if (instr->HasL()) { | 3172 if (instr->HasL()) { |
3158 int32_t rt_int_value = get_sinteger_from_s_register(2*vm); | 3173 int32_t data[2]; |
3159 int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1); | 3174 double d = get_double_from_d_register(vm); |
3160 | 3175 memcpy(data, &d, 8); |
3161 set_register(rt, rt_int_value); | 3176 set_register(rt, data[0]); |
3162 set_register(rn, rn_int_value); | 3177 set_register(rn, data[1]); |
3163 } else { | 3178 } else { |
3164 int32_t rs_val = get_register(rt); | 3179 int32_t data[] = { get_register(rt), get_register(rn) }; |
3165 int32_t rn_val = get_register(rn); | 3180 double d; |
3166 | 3181 memcpy(&d, data, 8); |
3167 set_s_register_from_sinteger(2*vm, rs_val); | 3182 set_d_register_from_double(vm, d); |
3168 set_s_register_from_sinteger((2*vm+1), rn_val); | |
3169 } | 3183 } |
3170 } | 3184 } |
3171 break; | 3185 break; |
3172 case 0x8: | 3186 case 0x8: |
3173 case 0xC: { // Load and store double to memory. | 3187 case 0xA: |
| 3188 case 0xC: |
| 3189 case 0xE: { // Load and store double to memory. |
3174 int rn = instr->RnValue(); | 3190 int rn = instr->RnValue(); |
3175 int vd = instr->VdValue(); | 3191 int vd = instr->VFPDRegValue(kDoublePrecision); |
3176 int offset = instr->Immed8Value(); | 3192 int offset = instr->Immed8Value(); |
3177 if (!instr->HasU()) { | 3193 if (!instr->HasU()) { |
3178 offset = -offset; | 3194 offset = -offset; |
3179 } | 3195 } |
3180 int32_t address = get_register(rn) + 4 * offset; | 3196 int32_t address = get_register(rn) + 4 * offset; |
3181 if (instr->HasL()) { | 3197 if (instr->HasL()) { |
3182 // Load double from memory: vldr. | 3198 // Load double from memory: vldr. |
3183 set_s_register_from_sinteger(2*vd, ReadW(address, instr)); | 3199 int32_t data[] = { |
3184 set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr)); | 3200 ReadW(address, instr), |
| 3201 ReadW(address + 4, instr) |
| 3202 }; |
| 3203 double val; |
| 3204 memcpy(&val, data, 8); |
| 3205 set_d_register_from_double(vd, val); |
3185 } else { | 3206 } else { |
3186 // Store double to memory: vstr. | 3207 // Store double to memory: vstr. |
3187 WriteW(address, get_sinteger_from_s_register(2*vd), instr); | 3208 int32_t data[2]; |
3188 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr); | 3209 double val = get_double_from_d_register(vd); |
| 3210 memcpy(data, &val, 8); |
| 3211 WriteW(address, data[0], instr); |
| 3212 WriteW(address + 4, data[1], instr); |
3189 } | 3213 } |
3190 break; | 3214 break; |
3191 } | 3215 } |
3192 case 0x4: | 3216 case 0x4: |
3193 case 0x5: | 3217 case 0x5: |
| 3218 case 0x6: |
| 3219 case 0x7: |
3194 case 0x9: | 3220 case 0x9: |
| 3221 case 0xB: |
3195 // Load/store multiple double from memory: vldm/vstm. | 3222 // Load/store multiple double from memory: vldm/vstm. |
3196 HandleVList(instr); | 3223 HandleVList(instr); |
3197 break; | 3224 break; |
3198 default: | 3225 default: |
3199 UNIMPLEMENTED(); // Not used by V8. | 3226 UNIMPLEMENTED(); // Not used by V8. |
3200 } | 3227 } |
3201 } else { | 3228 } else { |
3202 UNIMPLEMENTED(); // Not used by V8. | 3229 UNIMPLEMENTED(); // Not used by V8. |
3203 } | 3230 } |
3204 } | 3231 } |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3432 uintptr_t address = *stack_slot; | 3459 uintptr_t address = *stack_slot; |
3433 set_register(sp, current_sp + sizeof(uintptr_t)); | 3460 set_register(sp, current_sp + sizeof(uintptr_t)); |
3434 return address; | 3461 return address; |
3435 } | 3462 } |
3436 | 3463 |
3437 } } // namespace v8::internal | 3464 } } // namespace v8::internal |
3438 | 3465 |
3439 #endif // USE_SIMULATOR | 3466 #endif // USE_SIMULATOR |
3440 | 3467 |
3441 #endif // V8_TARGET_ARCH_ARM | 3468 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |