Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/arm/simulator-arm.cc

Issue 11428137: ARM: Make use of d16-d31 when available. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 16 matching lines...) Expand all
27 27
28 #include <stdlib.h> 28 #include <stdlib.h>
29 #include <math.h> 29 #include <math.h>
30 #include <cstdarg> 30 #include <cstdarg>
31 #include "v8.h" 31 #include "v8.h"
32 32
33 #if defined(V8_TARGET_ARCH_ARM) 33 #if defined(V8_TARGET_ARCH_ARM)
34 34
35 #include "disasm.h" 35 #include "disasm.h"
36 #include "assembler.h" 36 #include "assembler.h"
37 #include "codegen.h"
37 #include "arm/constants-arm.h" 38 #include "arm/constants-arm.h"
38 #include "arm/simulator-arm.h" 39 #include "arm/simulator-arm.h"
39 40
40 #if defined(USE_SIMULATOR) 41 #if defined(USE_SIMULATOR)
41 42
42 // Only build the simulator if not compiling for real ARM hardware. 43 // Only build the simulator if not compiling for real ARM hardware.
43 namespace v8 { 44 namespace v8 {
44 namespace internal { 45 namespace internal {
45 46
46 // This macro provides a platform independent use of sscanf. The reason for 47 // This macro provides a platform independent use of sscanf. The reason for
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } 758 }
758 n_flag_ = false; 759 n_flag_ = false;
759 z_flag_ = false; 760 z_flag_ = false;
760 c_flag_ = false; 761 c_flag_ = false;
761 v_flag_ = false; 762 v_flag_ = false;
762 763
763 // Initializing VFP registers. 764 // Initializing VFP registers.
764 // All registers are initialized to zero to start with 765 // All registers are initialized to zero to start with
765 // even though s_registers_ & d_registers_ share the same 766 // even though s_registers_ & d_registers_ share the same
766 // physical registers in the target. 767 // physical registers in the target.
767 for (int i = 0; i < num_s_registers; i++) { 768 for (int i = 0; i < num_d_registers * 2; i++) {
768 vfp_register[i] = 0; 769 vfp_register[i] = 0;
769 } 770 }
770 n_flag_FPSCR_ = false; 771 n_flag_FPSCR_ = false;
771 z_flag_FPSCR_ = false; 772 z_flag_FPSCR_ = false;
772 c_flag_FPSCR_ = false; 773 c_flag_FPSCR_ = false;
773 v_flag_FPSCR_ = false; 774 v_flag_FPSCR_ = false;
774 FPSCR_rounding_mode_ = RZ; 775 FPSCR_rounding_mode_ = RZ;
775 776
776 inv_op_vfp_flag_ = false; 777 inv_op_vfp_flag_ = false;
777 div_zero_vfp_flag_ = false; 778 div_zero_vfp_flag_ = false;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 unsigned int Simulator::get_s_register(int sreg) const { 943 unsigned int Simulator::get_s_register(int sreg) const {
943 ASSERT((sreg >= 0) && (sreg < num_s_registers)); 944 ASSERT((sreg >= 0) && (sreg < num_s_registers));
944 return vfp_register[sreg]; 945 return vfp_register[sreg];
945 } 946 }
946 947
947 948
948 template<class InputType, int register_size> 949 template<class InputType, int register_size>
949 void Simulator::SetVFPRegister(int reg_index, const InputType& value) { 950 void Simulator::SetVFPRegister(int reg_index, const InputType& value) {
950 ASSERT(reg_index >= 0); 951 ASSERT(reg_index >= 0);
951 if (register_size == 1) ASSERT(reg_index < num_s_registers); 952 if (register_size == 1) ASSERT(reg_index < num_s_registers);
952 if (register_size == 2) ASSERT(reg_index < num_d_registers); 953 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters());
953 954
954 char buffer[register_size * sizeof(vfp_register[0])]; 955 char buffer[register_size * sizeof(vfp_register[0])];
955 memcpy(buffer, &value, register_size * sizeof(vfp_register[0])); 956 memcpy(buffer, &value, register_size * sizeof(vfp_register[0]));
956 memcpy(&vfp_register[reg_index * register_size], buffer, 957 memcpy(&vfp_register[reg_index * register_size], buffer,
957 register_size * sizeof(vfp_register[0])); 958 register_size * sizeof(vfp_register[0]));
958 } 959 }
959 960
960 961
961 template<class ReturnType, int register_size> 962 template<class ReturnType, int register_size>
962 ReturnType Simulator::GetFromVFPRegister(int reg_index) { 963 ReturnType Simulator::GetFromVFPRegister(int reg_index) {
963 ASSERT(reg_index >= 0); 964 ASSERT(reg_index >= 0);
964 if (register_size == 1) ASSERT(reg_index < num_s_registers); 965 if (register_size == 1) ASSERT(reg_index < num_s_registers);
965 if (register_size == 2) ASSERT(reg_index < num_d_registers); 966 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters());
966 967
967 ReturnType value = 0; 968 ReturnType value = 0;
968 char buffer[register_size * sizeof(vfp_register[0])]; 969 char buffer[register_size * sizeof(vfp_register[0])];
969 memcpy(buffer, &vfp_register[register_size * reg_index], 970 memcpy(buffer, &vfp_register[register_size * reg_index],
970 register_size * sizeof(vfp_register[0])); 971 register_size * sizeof(vfp_register[0]));
971 memcpy(&value, buffer, register_size * sizeof(vfp_register[0])); 972 memcpy(&value, buffer, register_size * sizeof(vfp_register[0]));
972 return value; 973 return value;
973 } 974 }
974 975
975 976
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 if (load) { 1607 if (load) {
1607 set_s_register_from_sinteger( 1608 set_s_register_from_sinteger(
1608 reg, ReadW(reinterpret_cast<int32_t>(address), instr)); 1609 reg, ReadW(reinterpret_cast<int32_t>(address), instr));
1609 } else { 1610 } else {
1610 WriteW(reinterpret_cast<int32_t>(address), 1611 WriteW(reinterpret_cast<int32_t>(address),
1611 get_sinteger_from_s_register(reg), instr); 1612 get_sinteger_from_s_register(reg), instr);
1612 } 1613 }
1613 address += 1; 1614 address += 1;
1614 } else { 1615 } else {
1615 if (load) { 1616 if (load) {
1616 set_s_register_from_sinteger( 1617 int32_t data[] = {
1617 2 * reg, ReadW(reinterpret_cast<int32_t>(address), instr)); 1618 ReadW(reinterpret_cast<int32_t>(address), instr),
1618 set_s_register_from_sinteger( 1619 ReadW(reinterpret_cast<int32_t>(address + 1), instr)
1619 2 * reg + 1, ReadW(reinterpret_cast<int32_t>(address + 1), instr)); 1620 };
1621 double d;
1622 memcpy(&d, data, 8);
1623 set_d_register_from_double(reg, d);
1620 } else { 1624 } else {
1621 WriteW(reinterpret_cast<int32_t>(address), 1625 int32_t data[2];
1622 get_sinteger_from_s_register(2 * reg), instr); 1626 double d = get_double_from_d_register(reg);
1623 WriteW(reinterpret_cast<int32_t>(address + 1), 1627 memcpy(data, &d, 8);
1624 get_sinteger_from_s_register(2 * reg + 1), instr); 1628 WriteW(reinterpret_cast<int32_t>(address), data[0], instr);
1629 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr);
1625 } 1630 }
1626 address += 2; 1631 address += 2;
1627 } 1632 }
1628 } 1633 }
1629 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address); 1634 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address);
1630 } 1635 }
1631 1636
1632 1637
1633 // Calls into the V8 runtime are based on this very simple interface. 1638 // 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 1639 // 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
2803 double dd_value = dn_value / dm_value; 2808 double dd_value = dn_value / dm_value;
2804 div_zero_vfp_flag_ = (dm_value == 0); 2809 div_zero_vfp_flag_ = (dm_value == 0);
2805 set_d_register_from_double(vd, dd_value); 2810 set_d_register_from_double(vd, dd_value);
2806 } else { 2811 } else {
2807 UNIMPLEMENTED(); // Not used by V8. 2812 UNIMPLEMENTED(); // Not used by V8.
2808 } 2813 }
2809 } else { 2814 } else {
2810 if ((instr->VCValue() == 0x0) && 2815 if ((instr->VCValue() == 0x0) &&
2811 (instr->VAValue() == 0x0)) { 2816 (instr->VAValue() == 0x0)) {
2812 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 2817 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
2818 } else if ((instr->VLValue() == 0x0) &&
2819 (instr->VCValue() == 0x1) &&
2820 (instr->Bit(23) == 0x0)) {
2821 // vmov (ARM core register to scalar)
2822 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4);
2823 double dd_value = get_double_from_d_register(vd);
2824 int32_t data[2];
2825 memcpy(data, &dd_value, 8);
2826 data[instr->Bit(21)] = get_register(instr->RtValue());
2827 memcpy(&dd_value, data, 8);
2828 set_d_register_from_double(vd, dd_value);
2813 } else if ((instr->VLValue() == 0x1) && 2829 } else if ((instr->VLValue() == 0x1) &&
2814 (instr->VCValue() == 0x0) && 2830 (instr->VCValue() == 0x0) &&
2815 (instr->VAValue() == 0x7) && 2831 (instr->VAValue() == 0x7) &&
2816 (instr->Bits(19, 16) == 0x1)) { 2832 (instr->Bits(19, 16) == 0x1)) {
2817 // vmrs 2833 // vmrs
2818 uint32_t rt = instr->RtValue(); 2834 uint32_t rt = instr->RtValue();
2819 if (rt == 0xF) { 2835 if (rt == 0xF) {
2820 Copy_FPSCR_to_APSR(); 2836 Copy_FPSCR_to_APSR();
2821 } else { 2837 } else {
2822 // Emulate FPSCR from the Simulator flags. 2838 // Emulate FPSCR from the Simulator flags.
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
3141 // Load/store multiple single from memory: vldm/vstm. 3157 // Load/store multiple single from memory: vldm/vstm.
3142 HandleVList(instr); 3158 HandleVList(instr);
3143 break; 3159 break;
3144 default: 3160 default:
3145 UNIMPLEMENTED(); // Not used by V8. 3161 UNIMPLEMENTED(); // Not used by V8.
3146 } 3162 }
3147 } else if (instr->CoprocessorValue() == 0xB) { 3163 } else if (instr->CoprocessorValue() == 0xB) {
3148 switch (instr->OpcodeValue()) { 3164 switch (instr->OpcodeValue()) {
3149 case 0x2: 3165 case 0x2:
3150 // Load and store double to two GP registers 3166 // Load and store double to two GP registers
3151 if (instr->Bits(7, 4) != 0x1) { 3167 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) {
3152 UNIMPLEMENTED(); // Not used by V8. 3168 UNIMPLEMENTED(); // Not used by V8.
3153 } else { 3169 } else {
3154 int rt = instr->RtValue(); 3170 int rt = instr->RtValue();
3155 int rn = instr->RnValue(); 3171 int rn = instr->RnValue();
3156 int vm = instr->VmValue(); 3172 int vm = instr->VFPMRegValue(kDoublePrecision);
3157 if (instr->HasL()) { 3173 if (instr->HasL()) {
3158 int32_t rt_int_value = get_sinteger_from_s_register(2*vm); 3174 int32_t data[2];
3159 int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1); 3175 double d = get_double_from_d_register(vm);
3160 3176 memcpy(data, &d, 8);
3161 set_register(rt, rt_int_value); 3177 set_register(rt, data[0]);
3162 set_register(rn, rn_int_value); 3178 set_register(rn, data[1]);
3163 } else { 3179 } else {
3164 int32_t rs_val = get_register(rt); 3180 int32_t data[] = { get_register(rt), get_register(rn) };
3165 int32_t rn_val = get_register(rn); 3181 double d;
3166 3182 memcpy(&d, data, 8);
3167 set_s_register_from_sinteger(2*vm, rs_val); 3183 set_d_register_from_double(vm, d);
3168 set_s_register_from_sinteger((2*vm+1), rn_val);
3169 } 3184 }
3170 } 3185 }
3171 break; 3186 break;
3172 case 0x8: 3187 case 0x8:
3173 case 0xC: { // Load and store double to memory. 3188 case 0xA:
3189 case 0xC:
3190 case 0xE: { // Load and store double to memory.
3174 int rn = instr->RnValue(); 3191 int rn = instr->RnValue();
3175 int vd = instr->VdValue(); 3192 int vd = instr->VFPDRegValue(kDoublePrecision);
3176 int offset = instr->Immed8Value(); 3193 int offset = instr->Immed8Value();
3177 if (!instr->HasU()) { 3194 if (!instr->HasU()) {
3178 offset = -offset; 3195 offset = -offset;
3179 } 3196 }
3180 int32_t address = get_register(rn) + 4 * offset; 3197 int32_t address = get_register(rn) + 4 * offset;
3181 if (instr->HasL()) { 3198 if (instr->HasL()) {
3182 // Load double from memory: vldr. 3199 // Load double from memory: vldr.
3183 set_s_register_from_sinteger(2*vd, ReadW(address, instr)); 3200 int32_t data[] = {
3184 set_s_register_from_sinteger(2*vd + 1, ReadW(address + 4, instr)); 3201 ReadW(address, instr),
3202 ReadW(address + 4, instr)
3203 };
3204 double val;
3205 memcpy(&val, data, 8);
3206 set_d_register_from_double(vd, val);
3185 } else { 3207 } else {
3186 // Store double to memory: vstr. 3208 // Store double to memory: vstr.
3187 WriteW(address, get_sinteger_from_s_register(2*vd), instr); 3209 int32_t data[2];
3188 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr); 3210 double val = get_double_from_d_register(vd);
3211 memcpy(data, &val, 8);
3212 WriteW(address, data[0], instr);
3213 WriteW(address + 4, data[1], instr);
3189 } 3214 }
3190 break; 3215 break;
3191 } 3216 }
3192 case 0x4: 3217 case 0x4:
3193 case 0x5: 3218 case 0x5:
3219 case 0x6:
3220 case 0x7:
3194 case 0x9: 3221 case 0x9:
3222 case 0xB:
3195 // Load/store multiple double from memory: vldm/vstm. 3223 // Load/store multiple double from memory: vldm/vstm.
3196 HandleVList(instr); 3224 HandleVList(instr);
3197 break; 3225 break;
3198 default: 3226 default:
3199 UNIMPLEMENTED(); // Not used by V8. 3227 UNIMPLEMENTED(); // Not used by V8.
3200 } 3228 }
3201 } else { 3229 } else {
3202 UNIMPLEMENTED(); // Not used by V8. 3230 UNIMPLEMENTED(); // Not used by V8.
3203 } 3231 }
3204 } 3232 }
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3432 uintptr_t address = *stack_slot; 3460 uintptr_t address = *stack_slot;
3433 set_register(sp, current_sp + sizeof(uintptr_t)); 3461 set_register(sp, current_sp + sizeof(uintptr_t));
3434 return address; 3462 return address;
3435 } 3463 }
3436 3464
3437 } } // namespace v8::internal 3465 } } // namespace v8::internal
3438 3466
3439 #endif // USE_SIMULATOR 3467 #endif // USE_SIMULATOR
3440 3468
3441 #endif // V8_TARGET_ARCH_ARM 3469 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698