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 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 3822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3833 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 && | 3833 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 && |
3834 instr->Bit(4) == 1) { | 3834 instr->Bit(4) == 1) { |
3835 // vmov Qd, Qm | 3835 // vmov Qd, Qm |
3836 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3836 int Vd = instr->VFPDRegValue(kSimd128Precision); |
3837 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3837 int Vm = instr->VFPMRegValue(kSimd128Precision); |
3838 uint32_t data[4]; | 3838 uint32_t data[4]; |
3839 get_q_register(Vm, data); | 3839 get_q_register(Vm, data); |
3840 set_q_register(Vd, data); | 3840 set_q_register(Vd, data); |
3841 } else if (instr->Bits(11, 8) == 8) { | 3841 } else if (instr->Bits(11, 8) == 8) { |
3842 // vadd/vtst | 3842 // vadd/vtst |
3843 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 3843 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
3844 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3844 int Vd = instr->VFPDRegValue(kSimd128Precision); |
3845 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3845 int Vm = instr->VFPMRegValue(kSimd128Precision); |
3846 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3846 int Vn = instr->VFPNRegValue(kSimd128Precision); |
3847 if (instr->Bit(4) == 0) { | 3847 if (instr->Bit(4) == 0) { |
3848 // vadd.i<size> Qd, Qm, Qn. | 3848 // vadd.i<size> Qd, Qm, Qn. |
3849 switch (size) { | 3849 switch (size) { |
3850 case Neon8: { | 3850 case Neon8: { |
3851 uint8_t src1[16], src2[16]; | 3851 uint8_t src1[16], src2[16]; |
3852 get_q_register(Vn, src1); | 3852 get_q_register(Vn, src1); |
3853 get_q_register(Vm, src2); | 3853 get_q_register(Vm, src2); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3986 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3986 int Vm = instr->VFPMRegValue(kSimd128Precision); |
3987 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3987 int Vn = instr->VFPNRegValue(kSimd128Precision); |
3988 float src1[4], src2[4]; | 3988 float src1[4], src2[4]; |
3989 get_q_register(Vn, src1); | 3989 get_q_register(Vn, src1); |
3990 get_q_register(Vm, src2); | 3990 get_q_register(Vm, src2); |
3991 uint32_t dst[4]; | 3991 uint32_t dst[4]; |
3992 for (int i = 0; i < 4; i++) { | 3992 for (int i = 0; i < 4; i++) { |
3993 dst[i] = (src1[i] == src2[i]) ? 0xFFFFFFFF : 0; | 3993 dst[i] = (src1[i] == src2[i]) ? 0xFFFFFFFF : 0; |
3994 } | 3994 } |
3995 set_q_register(Vd, dst); | 3995 set_q_register(Vd, dst); |
| 3996 } else if (instr->Bits(11, 8) == 0x3) { |
| 3997 // vcge/vcgt.s<size> Qd, Qm, Qn. |
| 3998 bool ge = instr->Bit(4) == 1; |
| 3999 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 4000 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4001 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4002 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4003 switch (size) { |
| 4004 case Neon8: { |
| 4005 int8_t src1[16], src2[16]; |
| 4006 get_q_register(Vn, src1); |
| 4007 get_q_register(Vm, src2); |
| 4008 for (int i = 0; i < 16; i++) { |
| 4009 if (ge) |
| 4010 src1[i] = src1[i] >= src2[i] ? 0xFF : 0; |
| 4011 else |
| 4012 src1[i] = src1[i] > src2[i] ? 0xFF : 0; |
| 4013 } |
| 4014 set_q_register(Vd, src1); |
| 4015 break; |
| 4016 } |
| 4017 case Neon16: { |
| 4018 int16_t src1[8], src2[8]; |
| 4019 get_q_register(Vn, src1); |
| 4020 get_q_register(Vm, src2); |
| 4021 for (int i = 0; i < 8; i++) { |
| 4022 if (ge) |
| 4023 src1[i] = src1[i] >= src2[i] ? 0xFFFF : 0; |
| 4024 else |
| 4025 src1[i] = src1[i] > src2[i] ? 0xFFFF : 0; |
| 4026 } |
| 4027 set_q_register(Vd, src1); |
| 4028 break; |
| 4029 } |
| 4030 case Neon32: { |
| 4031 int32_t src1[4], src2[4]; |
| 4032 get_q_register(Vn, src1); |
| 4033 get_q_register(Vm, src2); |
| 4034 for (int i = 0; i < 4; i++) { |
| 4035 if (ge) |
| 4036 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFF : 0; |
| 4037 else |
| 4038 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFF : 0; |
| 4039 } |
| 4040 set_q_register(Vd, src1); |
| 4041 break; |
| 4042 } |
| 4043 default: |
| 4044 UNREACHABLE(); |
| 4045 break; |
| 4046 } |
3996 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xf && | 4047 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xf && |
3997 instr->Bit(6) == 1 && instr->Bit(4) == 1) { | 4048 instr->Bit(6) == 1 && instr->Bit(4) == 1) { |
3998 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4049 int Vd = instr->VFPDRegValue(kSimd128Precision); |
3999 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4050 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4000 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4051 int Vn = instr->VFPNRegValue(kSimd128Precision); |
4001 float src1[4], src2[4]; | 4052 float src1[4], src2[4]; |
4002 get_q_register(Vn, src1); | 4053 get_q_register(Vn, src1); |
4003 get_q_register(Vm, src2); | 4054 get_q_register(Vm, src2); |
4004 if (instr->Bit(21) == 0) { | 4055 if (instr->Bit(21) == 0) { |
4005 // vrecps.f32 Qd, Qm, Qn. | 4056 // vrecps.f32 Qd, Qm, Qn. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4055 dst[i] = src2[i - boundary]; | 4106 dst[i] = src2[i - boundary]; |
4056 } | 4107 } |
4057 set_q_register(Vd, dst); | 4108 set_q_register(Vd, dst); |
4058 } else { | 4109 } else { |
4059 UNIMPLEMENTED(); | 4110 UNIMPLEMENTED(); |
4060 } | 4111 } |
4061 break; | 4112 break; |
4062 case 6: | 4113 case 6: |
4063 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { | 4114 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { |
4064 // vsub.size Qd, Qm, Qn. | 4115 // vsub.size Qd, Qm, Qn. |
4065 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 4116 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
4066 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4117 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4067 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4118 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4068 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4119 int Vn = instr->VFPNRegValue(kSimd128Precision); |
4069 switch (size) { | 4120 switch (size) { |
4070 case Neon8: { | 4121 case Neon8: { |
4071 uint8_t src1[16], src2[16]; | 4122 uint8_t src1[16], src2[16]; |
4072 get_q_register(Vn, src1); | 4123 get_q_register(Vn, src1); |
4073 get_q_register(Vm, src2); | 4124 get_q_register(Vm, src2); |
4074 for (int i = 0; i < 16; i++) { | 4125 for (int i = 0; i < 16; i++) { |
4075 src1[i] -= src2[i]; | 4126 src1[i] -= src2[i]; |
(...skipping 20 matching lines...) Expand all Loading... |
4096 } | 4147 } |
4097 set_q_register(Vd, src1); | 4148 set_q_register(Vd, src1); |
4098 break; | 4149 break; |
4099 } | 4150 } |
4100 default: | 4151 default: |
4101 UNREACHABLE(); | 4152 UNREACHABLE(); |
4102 break; | 4153 break; |
4103 } | 4154 } |
4104 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { | 4155 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { |
4105 // vceq.size Qd, Qm, Qn. | 4156 // vceq.size Qd, Qm, Qn. |
4106 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 4157 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
4107 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4158 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4108 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4159 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4109 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4160 int Vn = instr->VFPNRegValue(kSimd128Precision); |
4110 switch (size) { | 4161 switch (size) { |
4111 case Neon8: { | 4162 case Neon8: { |
4112 uint8_t src1[16], src2[16]; | 4163 uint8_t src1[16], src2[16]; |
4113 get_q_register(Vn, src1); | 4164 get_q_register(Vn, src1); |
4114 get_q_register(Vm, src2); | 4165 get_q_register(Vm, src2); |
4115 for (int i = 0; i < 16; i++) { | 4166 for (int i = 0; i < 16; i++) { |
4116 src1[i] = (src1[i] == src2[i]) ? 0xFFu : 0; | 4167 src1[i] = (src1[i] == src2[i]) ? 0xFFu : 0; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4186 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4237 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4187 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4238 int Vn = instr->VFPNRegValue(kSimd128Precision); |
4188 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4239 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4189 float src1[4], src2[4]; | 4240 float src1[4], src2[4]; |
4190 get_q_register(Vn, src1); | 4241 get_q_register(Vn, src1); |
4191 get_q_register(Vm, src2); | 4242 get_q_register(Vm, src2); |
4192 for (int i = 0; i < 4; i++) { | 4243 for (int i = 0; i < 4; i++) { |
4193 src1[i] = src1[i] * src2[i]; | 4244 src1[i] = src1[i] * src2[i]; |
4194 } | 4245 } |
4195 set_q_register(Vd, src1); | 4246 set_q_register(Vd, src1); |
| 4247 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xe && |
| 4248 instr->Bit(4) == 0) { |
| 4249 // vcge/vcgt.f32 Qd, Qm, Qn |
| 4250 bool ge = instr->Bit(21) == 0; |
| 4251 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4252 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4253 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4254 float src1[4], src2[4]; |
| 4255 get_q_register(Vn, src1); |
| 4256 get_q_register(Vm, src2); |
| 4257 uint32_t dst[4]; |
| 4258 for (int i = 0; i < 4; i++) { |
| 4259 if (ge) { |
| 4260 dst[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0; |
| 4261 } else { |
| 4262 dst[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0; |
| 4263 } |
| 4264 } |
| 4265 set_q_register(Vd, dst); |
| 4266 } else if (instr->Bits(11, 8) == 0x3) { |
| 4267 // vcge/vcgt.u<size> Qd, Qm, Qn. |
| 4268 bool ge = instr->Bit(4) == 1; |
| 4269 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 4270 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4271 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4272 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4273 switch (size) { |
| 4274 case Neon8: { |
| 4275 uint8_t src1[16], src2[16]; |
| 4276 get_q_register(Vn, src1); |
| 4277 get_q_register(Vm, src2); |
| 4278 for (int i = 0; i < 16; i++) { |
| 4279 if (ge) |
| 4280 src1[i] = src1[i] >= src2[i] ? 0xFFu : 0; |
| 4281 else |
| 4282 src1[i] = src1[i] > src2[i] ? 0xFFu : 0; |
| 4283 } |
| 4284 set_q_register(Vd, src1); |
| 4285 break; |
| 4286 } |
| 4287 case Neon16: { |
| 4288 uint16_t src1[8], src2[8]; |
| 4289 get_q_register(Vn, src1); |
| 4290 get_q_register(Vm, src2); |
| 4291 for (int i = 0; i < 8; i++) { |
| 4292 if (ge) |
| 4293 src1[i] = src1[i] >= src2[i] ? 0xFFFFu : 0; |
| 4294 else |
| 4295 src1[i] = src1[i] > src2[i] ? 0xFFFFu : 0; |
| 4296 } |
| 4297 set_q_register(Vd, src1); |
| 4298 break; |
| 4299 } |
| 4300 case Neon32: { |
| 4301 uint32_t src1[4], src2[4]; |
| 4302 get_q_register(Vn, src1); |
| 4303 get_q_register(Vm, src2); |
| 4304 for (int i = 0; i < 4; i++) { |
| 4305 if (ge) |
| 4306 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0; |
| 4307 else |
| 4308 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0; |
| 4309 } |
| 4310 set_q_register(Vd, src1); |
| 4311 break; |
| 4312 } |
| 4313 default: |
| 4314 UNREACHABLE(); |
| 4315 break; |
| 4316 } |
4196 } else { | 4317 } else { |
4197 UNIMPLEMENTED(); | 4318 UNIMPLEMENTED(); |
4198 } | 4319 } |
4199 break; | 4320 break; |
4200 case 7: | 4321 case 7: |
4201 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | 4322 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
4202 (instr->Bit(4) == 1)) { | 4323 (instr->Bit(4) == 1)) { |
4203 // vmovl unsigned | 4324 // vmovl unsigned |
4204 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); | 4325 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); |
4205 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); | 4326 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4307 result |= | 4428 result |= |
4308 ((table >> ((index % kDoubleSize) * kBitsPerByte)) & 0xFF) | 4429 ((table >> ((index % kDoubleSize) * kBitsPerByte)) & 0xFF) |
4309 << shift; | 4430 << shift; |
4310 } else if (vtbx) { | 4431 } else if (vtbx) { |
4311 result |= destination & (0xFFull << shift); | 4432 result |= destination & (0xFFull << shift); |
4312 } | 4433 } |
4313 } | 4434 } |
4314 set_d_register(vd, &result); | 4435 set_d_register(vd, &result); |
4315 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x7) { | 4436 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x7) { |
4316 // vzip.<size> Qd, Qm. | 4437 // vzip.<size> Qd, Qm. |
4317 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4438 NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
4318 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4439 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4319 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4440 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4320 switch (size) { | 4441 switch (size) { |
4321 case Neon8: { | 4442 case Neon8: { |
4322 uint8_t src1[16], src2[16], dst1[16], dst2[16]; | 4443 uint8_t src1[16], src2[16], dst1[16], dst2[16]; |
4323 get_q_register(Vd, src1); | 4444 get_q_register(Vd, src1); |
4324 get_q_register(Vm, src2); | 4445 get_q_register(Vm, src2); |
4325 for (int i = 0; i < 8; i++) { | 4446 for (int i = 0; i < 8; i++) { |
4326 dst1[i * 2] = src1[i]; | 4447 dst1[i * 2] = src1[i]; |
4327 dst1[i * 2 + 1] = src2[i]; | 4448 dst1[i * 2 + 1] = src2[i]; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4361 break; | 4482 break; |
4362 } | 4483 } |
4363 default: | 4484 default: |
4364 UNREACHABLE(); | 4485 UNREACHABLE(); |
4365 break; | 4486 break; |
4366 } | 4487 } |
4367 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0) { | 4488 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0) { |
4368 // vrev<op>.size Qd, Qm | 4489 // vrev<op>.size Qd, Qm |
4369 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4490 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4370 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4491 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4371 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4492 NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
4372 NeonSize op = static_cast<NeonSize>(static_cast<int>(Neon64) - | 4493 NeonSize op = static_cast<NeonSize>(static_cast<int>(Neon64) - |
4373 instr->Bits(8, 7)); | 4494 instr->Bits(8, 7)); |
4374 switch (op) { | 4495 switch (op) { |
4375 case Neon16: { | 4496 case Neon16: { |
4376 DCHECK_EQ(Neon8, size); | 4497 DCHECK_EQ(Neon8, size); |
4377 uint8_t src[16]; | 4498 uint8_t src[16]; |
4378 get_q_register(Vm, src); | 4499 get_q_register(Vm, src); |
4379 for (int i = 0; i < 16; i += 2) { | 4500 for (int i = 0; i < 16; i += 2) { |
4380 std::swap(src[i], src[i + 1]); | 4501 std::swap(src[i], src[i + 1]); |
4381 } | 4502 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4445 } | 4566 } |
4446 break; | 4567 break; |
4447 } | 4568 } |
4448 default: | 4569 default: |
4449 UNREACHABLE(); | 4570 UNREACHABLE(); |
4450 break; | 4571 break; |
4451 } | 4572 } |
4452 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) { | 4573 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) { |
4453 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4574 int Vd = instr->VFPDRegValue(kSimd128Precision); |
4454 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4575 int Vm = instr->VFPMRegValue(kSimd128Precision); |
4455 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4576 NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
4456 if (instr->Bits(9, 6) == 0xd) { | 4577 if (instr->Bits(9, 6) == 0xd) { |
4457 // vabs<type>.<size> Qd, Qm | 4578 // vabs<type>.<size> Qd, Qm |
4458 if (instr->Bit(10) != 0) { | 4579 if (instr->Bit(10) != 0) { |
4459 // floating point (clear sign bits) | 4580 // floating point (clear sign bits) |
4460 uint32_t src[4]; | 4581 uint32_t src[4]; |
4461 get_q_register(Vm, src); | 4582 get_q_register(Vm, src); |
4462 for (int i = 0; i < 4; i++) { | 4583 for (int i = 0; i < 4; i++) { |
4463 src[i] &= ~0x80000000; | 4584 src[i] &= ~0x80000000; |
4464 } | 4585 } |
4465 set_q_register(Vd, src); | 4586 set_q_register(Vd, src); |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5085 set_register(sp, current_sp + sizeof(uintptr_t)); | 5206 set_register(sp, current_sp + sizeof(uintptr_t)); |
5086 return address; | 5207 return address; |
5087 } | 5208 } |
5088 | 5209 |
5089 } // namespace internal | 5210 } // namespace internal |
5090 } // namespace v8 | 5211 } // namespace v8 |
5091 | 5212 |
5092 #endif // USE_SIMULATOR | 5213 #endif // USE_SIMULATOR |
5093 | 5214 |
5094 #endif // V8_TARGET_ARCH_ARM | 5215 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |