| 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 |