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

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

Issue 2711863002: Implement remaining Boolean SIMD operations on ARM. (Closed)
Patch Set: All Boolean vector tests. Created 3 years, 9 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
OLDNEW
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 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value) * 2); 893 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value) * 2);
894 } 894 }
895 895
896 896
897 void Simulator::set_d_register(int dreg, const uint32_t* value) { 897 void Simulator::set_d_register(int dreg, const uint32_t* value) {
898 DCHECK((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); 898 DCHECK((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters()));
899 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value) * 2); 899 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value) * 2);
900 } 900 }
901 901
902 template <typename T> 902 template <typename T>
903 void Simulator::get_d_register(int dreg, T* value) {
904 DCHECK((dreg >= 0) && (dreg < num_d_registers));
905 memcpy(value, vfp_registers_ + dreg * 2, kDoubleSize);
906 }
907
908 template <typename T>
909 void Simulator::set_d_register(int dreg, const T* value) {
910 DCHECK((dreg >= 0) && (dreg < num_d_registers));
911 memcpy(vfp_registers_ + dreg * 2, value, kDoubleSize);
912 }
913
914 template <typename T>
903 void Simulator::get_q_register(int qreg, T* value) { 915 void Simulator::get_q_register(int qreg, T* value) {
904 DCHECK((qreg >= 0) && (qreg < num_q_registers)); 916 DCHECK((qreg >= 0) && (qreg < num_q_registers));
905 memcpy(value, vfp_registers_ + qreg * 4, kSimd128Size); 917 memcpy(value, vfp_registers_ + qreg * 4, kSimd128Size);
906 } 918 }
907 919
908 template <typename T> 920 template <typename T>
909 void Simulator::set_q_register(int qreg, const T* value) { 921 void Simulator::set_q_register(int qreg, const T* value) {
910 DCHECK((qreg >= 0) && (qreg < num_q_registers)); 922 DCHECK((qreg >= 0) && (qreg < num_q_registers));
911 memcpy(vfp_registers_ + qreg * 4, value, kSimd128Size); 923 memcpy(vfp_registers_ + qreg * 4, value, kSimd128Size);
912 } 924 }
913 925
914
915 // Raw access to the PC register. 926 // Raw access to the PC register.
916 void Simulator::set_pc(int32_t value) { 927 void Simulator::set_pc(int32_t value) {
917 pc_modified_ = true; 928 pc_modified_ = true;
918 registers_[pc] = value; 929 registers_[pc] = value;
919 } 930 }
920 931
921 932
922 bool Simulator::has_bad_pc() const { 933 bool Simulator::has_bad_pc() const {
923 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); 934 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc));
924 } 935 }
(...skipping 3411 matching lines...) Expand 10 before | Expand all | Expand 10 after
4336 } 4347 }
4337 default: 4348 default:
4338 UNREACHABLE(); 4349 UNREACHABLE();
4339 break; 4350 break;
4340 } 4351 }
4341 } else { 4352 } else {
4342 UNIMPLEMENTED(); 4353 UNIMPLEMENTED();
4343 } 4354 }
4344 break; 4355 break;
4345 } 4356 }
4357 case 0xa: {
4358 // vpmin/vpmax.s<size> Dd, Dm, Dn.
4359 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4360 bool min = instr->Bit(4) != 0;
4361 switch (size) {
4362 case Neon8: {
4363 int8_t dst[8], src1[8], src2[8];
4364 get_d_register(Vn, src1);
4365 get_d_register(Vm, src2);
4366 for (int i = 0; i < 4; i++) {
4367 if (min) {
martyn.capewell 2017/02/28 15:45:24 How about a templated minmax helper? template <typ
bbudge 2017/02/28 17:39:35 That does look nicer. Done.
4368 dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
4369 dst[i + 4] = std::min(src2[i * 2], src2[i * 2 + 1]);
4370 } else {
4371 dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
4372 dst[i + 4] = std::max(src2[i * 2], src2[i * 2 + 1]);
4373 }
4374 }
4375 set_d_register(Vd, dst);
4376 break;
4377 }
4378 case Neon16: {
4379 int16_t dst[4], src1[4], src2[4];
4380 get_d_register(Vn, src1);
4381 get_d_register(Vm, src2);
4382 for (int i = 0; i < 2; i++) {
4383 if (min) {
4384 dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
4385 dst[i + 2] = std::min(src2[i * 2], src2[i * 2 + 1]);
4386 } else {
4387 dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
4388 dst[i + 2] = std::max(src2[i * 2], src2[i * 2 + 1]);
4389 }
4390 }
4391 set_d_register(Vd, dst);
4392 break;
4393 }
4394 case Neon32: {
4395 int32_t dst[2], src1[2], src2[2];
4396 get_d_register(Vn, src1);
4397 get_d_register(Vm, src2);
4398 if (min) {
4399 dst[0] = std::min(src1[0], src1[1]);
4400 dst[1] = std::min(src2[0], src2[1]);
4401 } else {
4402 dst[0] = std::max(src1[0], src1[1]);
4403 dst[1] = std::max(src2[0], src2[1]);
4404 }
4405 set_d_register(Vd, dst);
4406 break;
4407 }
4408 default:
4409 UNREACHABLE();
4410 break;
4411 }
4412 break;
4413 }
4346 case 0xd: { 4414 case 0xd: {
4347 if (instr->Bit(4) == 0) { 4415 if (instr->Bit(4) == 0) {
4348 float src1[4], src2[4]; 4416 float src1[4], src2[4];
4349 get_q_register(Vn, src1); 4417 get_q_register(Vn, src1);
4350 get_q_register(Vm, src2); 4418 get_q_register(Vm, src2);
4351 for (int i = 0; i < 4; i++) { 4419 for (int i = 0; i < 4; i++) {
4352 if (instr->Bit(21) == 0) { 4420 if (instr->Bit(21) == 0) {
4353 // vadd.f32 Qd, Qm, Qn. 4421 // vadd.f32 Qd, Qm, Qn.
4354 src1[i] = src1[i] + src2[i]; 4422 src1[i] = src1[i] + src2[i];
4355 } else { 4423 } else {
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
4805 set_q_register(Vd, src1); 4873 set_q_register(Vd, src1);
4806 break; 4874 break;
4807 } 4875 }
4808 default: 4876 default:
4809 UNREACHABLE(); 4877 UNREACHABLE();
4810 break; 4878 break;
4811 } 4879 }
4812 } 4880 }
4813 break; 4881 break;
4814 } 4882 }
4883 case 0xa: {
4884 // vpmin/vpmax.u<size> Dd, Dm, Dn.
4885 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4886 bool min = instr->Bit(4) != 0;
4887 switch (size) {
4888 case Neon8: {
4889 uint8_t dst[8], src1[8], src2[8];
4890 get_d_register(Vn, src1);
4891 get_d_register(Vm, src2);
4892 for (int i = 0; i < 4; i++) {
4893 if (min) {
4894 dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
4895 dst[i + 4] = std::min(src2[i * 2], src2[i * 2 + 1]);
4896 } else {
4897 dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
4898 dst[i + 4] = std::max(src2[i * 2], src2[i * 2 + 1]);
4899 }
4900 }
4901 set_d_register(Vd, dst);
4902 break;
4903 }
4904 case Neon16: {
4905 uint16_t dst[4], src1[4], src2[4];
4906 get_d_register(Vn, src1);
4907 get_d_register(Vm, src2);
4908 for (int i = 0; i < 2; i++) {
4909 if (min) {
4910 dst[i + 0] = std::min(src1[i * 2], src1[i * 2 + 1]);
4911 dst[i + 2] = std::min(src2[i * 2], src2[i * 2 + 1]);
4912 } else {
4913 dst[i + 0] = std::max(src1[i * 2], src1[i * 2 + 1]);
4914 dst[i + 2] = std::max(src2[i * 2], src2[i * 2 + 1]);
4915 }
4916 }
4917 set_d_register(Vd, dst);
4918 break;
4919 }
4920 case Neon32: {
4921 uint32_t dst[2], src1[2], src2[2];
4922 get_d_register(Vn, src1);
4923 get_d_register(Vm, src2);
4924 if (min) {
4925 dst[0] = std::min(src1[0], src1[1]);
4926 dst[1] = std::min(src2[0], src2[1]);
4927 } else {
4928 dst[0] = std::max(src1[0], src1[1]);
4929 dst[1] = std::max(src2[0], src2[1]);
4930 }
4931 set_d_register(Vd, dst);
4932 break;
4933 }
4934 default:
4935 UNREACHABLE();
4936 break;
4937 }
4938 break;
4939 }
4815 case 0xd: { 4940 case 0xd: {
4816 if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) { 4941 if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) {
4817 // vmul.f32 Qd, Qn, Qm 4942 // vmul.f32 Qd, Qn, Qm
4818 float src1[4], src2[4]; 4943 float src1[4], src2[4];
4819 get_q_register(Vn, src1); 4944 get_q_register(Vn, src1);
4820 get_q_register(Vm, src2); 4945 get_q_register(Vm, src2);
4821 for (int i = 0; i < 4; i++) { 4946 for (int i = 0; i < 4; i++) {
4822 src1[i] = src1[i] * src2[i]; 4947 src1[i] = src1[i] * src2[i];
4823 } 4948 }
4824 set_q_register(Vd, src1); 4949 set_q_register(Vd, src1);
(...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
5982 processor->prev_ = nullptr; 6107 processor->prev_ = nullptr;
5983 processor->next_ = nullptr; 6108 processor->next_ = nullptr;
5984 } 6109 }
5985 6110
5986 } // namespace internal 6111 } // namespace internal
5987 } // namespace v8 6112 } // namespace v8
5988 6113
5989 #endif // USE_SIMULATOR 6114 #endif // USE_SIMULATOR
5990 6115
5991 #endif // V8_TARGET_ARCH_ARM 6116 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698