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

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

Issue 2649323012: [ARM] Add Neon saturating add and subtract instructions. (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « src/arm/disasm-arm.cc ('k') | test/cctest/test-assembler-arm.cc » ('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 // 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 3972 matching lines...) Expand 10 before | Expand all | Expand 10 after
3983 default: 3983 default:
3984 UNIMPLEMENTED(); // Not used by V8. 3984 UNIMPLEMENTED(); // Not used by V8.
3985 } 3985 }
3986 } else { 3986 } else {
3987 UNIMPLEMENTED(); // Not used by V8. 3987 UNIMPLEMENTED(); // Not used by V8.
3988 } 3988 }
3989 } 3989 }
3990 3990
3991 void Simulator::DecodeSpecialCondition(Instruction* instr) { 3991 void Simulator::DecodeSpecialCondition(Instruction* instr) {
3992 switch (instr->SpecialValue()) { 3992 switch (instr->SpecialValue()) {
3993 case 4: 3993 case 4: {
3994 if (instr->Bits(11, 8) == 1 && instr->Bits(21, 20) == 2 && 3994 int Vd, Vm, Vn;
3995 instr->Bit(4) == 1) { 3995 if (instr->Bit(6) == 0) {
3996 // vmov Qd, Qm. 3996 Vd = instr->VFPDRegValue(kDoublePrecision);
3997 // vorr, Qd, Qm, Qn. 3997 Vm = instr->VFPMRegValue(kDoublePrecision);
3998 int Vd = instr->VFPDRegValue(kSimd128Precision); 3998 Vn = instr->VFPNRegValue(kDoublePrecision);
3999 int Vm = instr->VFPMRegValue(kSimd128Precision); 3999 } else {
4000 int Vn = instr->VFPNRegValue(kSimd128Precision); 4000 Vd = instr->VFPDRegValue(kSimd128Precision);
4001 uint32_t src1[4]; 4001 Vm = instr->VFPMRegValue(kSimd128Precision);
4002 get_q_register(Vm, src1); 4002 Vn = instr->VFPNRegValue(kSimd128Precision);
4003 if (Vm != Vn) { 4003 }
4004 uint32_t src2[4]; 4004 switch (instr->Bits(11, 8)) {
4005 get_q_register(Vn, src2); 4005 case 0x0: {
4006 for (int i = 0; i < 4; i++) { 4006 if (instr->Bit(4) == 1) {
4007 src1[i] = src1[i] | src2[i]; 4007 // vqadd.s<size> Qd, Qm, Qn.
4008 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4009 switch (size) {
4010 case Neon8: {
4011 int8_t src1[16], src2[16];
martyn.capewell 2017/01/30 13:50:47 It might be possible to factor out simulator opera
bbudge 2017/01/31 19:58:24 Done for vqadd/vqsub, and added a TODO to do this
4012 get_q_register(Vn, src1);
4013 get_q_register(Vm, src2);
4014 for (int i = 0; i < 16; i++) {
4015 int16_t s1 = static_cast<int16_t>(src1[i]);
4016 int16_t s2 = static_cast<int16_t>(src2[i]);
4017 int16_t sum = std::max(0xff80, std::min(0x7f, s1 + s2));
4018 src1[i] = static_cast<int8_t>(sum);
4019 }
4020 set_q_register(Vd, src1);
4021 break;
4022 }
4023 case Neon16: {
4024 int16_t src1[8], src2[8];
4025 get_q_register(Vn, src1);
4026 get_q_register(Vm, src2);
4027 for (int i = 0; i < 8; i++) {
4028 int32_t s1 = static_cast<int32_t>(src1[i]);
4029 int32_t s2 = static_cast<int32_t>(src2[i]);
4030 int32_t sum = std::max(-0x8000, std::min(0x7fff, s1 + s2));
4031 src1[i] = static_cast<int16_t>(sum);
4032 }
4033 set_q_register(Vd, src1);
4034 break;
4035 }
4036 case Neon32: {
4037 int32_t src1[4], src2[4];
4038 get_q_register(Vn, src1);
4039 get_q_register(Vm, src2);
4040 for (int i = 0; i < 4; i++) {
4041 int64_t s1 = static_cast<int64_t>(src1[i]);
4042 int64_t s2 = static_cast<int64_t>(src2[i]);
4043 int64_t sum =
4044 std::max(-0x80000000LL, std::min(0x7fffffffLL, s1 + s2));
4045 src1[i] = static_cast<int32_t>(sum);
4046 }
4047 set_q_register(Vd, src1);
4048 break;
4049 }
4050 default:
4051 UNREACHABLE();
4052 break;
4053 }
4054 } else {
4055 UNIMPLEMENTED();
4008 } 4056 }
4057 break;
4009 } 4058 }
4010 set_q_register(Vd, src1); 4059 case 0x1: {
4011 } else if (instr->Bits(11, 8) == 8) { 4060 if (instr->Bits(21, 20) == 2 && instr->Bit(6) == 1 &&
4012 // vadd/vtst 4061 instr->Bit(4) == 1) {
4013 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); 4062 // vmov Qd, Qm.
4014 int Vd = instr->VFPDRegValue(kSimd128Precision); 4063 // vorr, Qd, Qm, Qn.
4015 int Vm = instr->VFPMRegValue(kSimd128Precision); 4064 uint32_t src1[4];
4016 int Vn = instr->VFPNRegValue(kSimd128Precision); 4065 get_q_register(Vm, src1);
4017 if (instr->Bit(4) == 0) { 4066 if (Vm != Vn) {
4018 // vadd.i<size> Qd, Qm, Qn. 4067 uint32_t src2[4];
4068 get_q_register(Vn, src2);
4069 for (int i = 0; i < 4; i++) {
4070 src1[i] = src1[i] | src2[i];
4071 }
4072 }
4073 set_q_register(Vd, src1);
4074 } else if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 1 &&
4075 instr->Bit(4) == 1) {
4076 // vand Qd, Qm, Qn.
4077 uint32_t src1[4], src2[4];
4078 get_q_register(Vn, src1);
4079 get_q_register(Vm, src2);
4080 for (int i = 0; i < 4; i++) {
4081 src1[i] = src1[i] & src2[i];
4082 }
4083 set_q_register(Vd, src1);
4084 } else {
4085 UNIMPLEMENTED();
4086 }
4087 break;
4088 }
4089 case 0x2: {
4090 if (instr->Bit(4) == 1) {
4091 // vqsub.s<size> Qd, Qm, Qn.
4092 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4093 switch (size) {
4094 case Neon8: {
4095 int8_t src1[16], src2[16];
4096 get_q_register(Vn, src1);
4097 get_q_register(Vm, src2);
4098 for (int i = 0; i < 16; i++) {
4099 int16_t diff =
4100 std::max(-0x80, std::min(0x7f, src1[i] - src2[i]));
4101 src1[i] = static_cast<int8_t>(diff);
4102 }
4103 set_q_register(Vd, src1);
4104 break;
4105 }
4106 case Neon16: {
4107 int16_t src1[8], src2[8];
4108 get_q_register(Vn, src1);
4109 get_q_register(Vm, src2);
4110 for (int i = 0; i < 8; i++) {
4111 int32_t diff =
4112 std::max(-0x8000, std::min(0x7fff, src1[i] - src2[i]));
4113 src1[i] = static_cast<int16_t>(diff);
4114 }
4115 set_q_register(Vd, src1);
4116 break;
4117 }
4118 case Neon32: {
4119 int32_t src1[4], src2[4];
4120 get_q_register(Vn, src1);
4121 get_q_register(Vm, src2);
4122 for (int i = 0; i < 4; i++) {
4123 int64_t s1 = src1[i];
4124 int64_t s2 = src2[i];
4125 int64_t sum =
4126 std::max(-0x80000000LL, std::min(0x7fffffffLL, s1 - s2));
4127 src1[i] = static_cast<int32_t>(sum);
4128 }
4129 set_q_register(Vd, src1);
4130 break;
4131 }
4132 default:
4133 UNREACHABLE();
4134 break;
4135 }
4136 } else {
4137 UNIMPLEMENTED();
4138 }
4139 break;
4140 }
4141 case 0x3: {
4142 // vcge/vcgt.s<size> Qd, Qm, Qn.
4143 bool ge = instr->Bit(4) == 1;
4144 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4019 switch (size) { 4145 switch (size) {
4020 case Neon8: { 4146 case Neon8: {
4021 uint8_t src1[16], src2[16]; 4147 int8_t src1[16], src2[16];
4022 get_q_register(Vn, src1); 4148 get_q_register(Vn, src1);
4023 get_q_register(Vm, src2); 4149 get_q_register(Vm, src2);
4024 for (int i = 0; i < 16; i++) { 4150 for (int i = 0; i < 16; i++) {
4025 src1[i] += src2[i]; 4151 if (ge)
4152 src1[i] = src1[i] >= src2[i] ? 0xFF : 0;
4153 else
4154 src1[i] = src1[i] > src2[i] ? 0xFF : 0;
4026 } 4155 }
4027 set_q_register(Vd, src1); 4156 set_q_register(Vd, src1);
4028 break; 4157 break;
4029 } 4158 }
4030 case Neon16: { 4159 case Neon16: {
4031 uint16_t src1[8], src2[8]; 4160 int16_t src1[8], src2[8];
4032 get_q_register(Vn, src1); 4161 get_q_register(Vn, src1);
4033 get_q_register(Vm, src2); 4162 get_q_register(Vm, src2);
4034 for (int i = 0; i < 8; i++) { 4163 for (int i = 0; i < 8; i++) {
4035 src1[i] += src2[i]; 4164 if (ge)
4165 src1[i] = src1[i] >= src2[i] ? 0xFFFF : 0;
4166 else
4167 src1[i] = src1[i] > src2[i] ? 0xFFFF : 0;
4036 } 4168 }
4037 set_q_register(Vd, src1); 4169 set_q_register(Vd, src1);
4038 break; 4170 break;
4039 } 4171 }
4040 case Neon32: { 4172 case Neon32: {
4041 uint32_t src1[4], src2[4]; 4173 int32_t src1[4], src2[4];
4042 get_q_register(Vn, src1); 4174 get_q_register(Vn, src1);
4043 get_q_register(Vm, src2); 4175 get_q_register(Vm, src2);
4044 for (int i = 0; i < 4; i++) { 4176 for (int i = 0; i < 4; i++) {
4045 src1[i] += src2[i]; 4177 if (ge)
4178 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFF : 0;
4179 else
4180 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFF : 0;
4046 } 4181 }
4047 set_q_register(Vd, src1); 4182 set_q_register(Vd, src1);
4048 break; 4183 break;
4049 } 4184 }
4050 default: 4185 default:
4051 UNREACHABLE(); 4186 UNREACHABLE();
4052 break; 4187 break;
4053 } 4188 }
4054 } else { 4189 break;
4055 // vtst.i<size> Qd, Qm, Qn. 4190 }
4191 case 0x6: {
4192 // vmin/vmax.s<size> Qd, Qm, Qn.
4193 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4194 bool min = instr->Bit(4) != 0;
4056 switch (size) { 4195 switch (size) {
4057 case Neon8: { 4196 case Neon8: {
4058 uint8_t src1[16], src2[16]; 4197 int8_t src1[16], src2[16];
4059 get_q_register(Vn, src1); 4198 get_q_register(Vn, src1);
4060 get_q_register(Vm, src2); 4199 get_q_register(Vm, src2);
4061 for (int i = 0; i < 16; i++) { 4200 for (int i = 0; i < 16; i++) {
4062 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFu : 0; 4201 if (min)
4202 src1[i] = std::min(src1[i], src2[i]);
4203 else
4204 src1[i] = std::max(src1[i], src2[i]);
4063 } 4205 }
4064 set_q_register(Vd, src1); 4206 set_q_register(Vd, src1);
4065 break; 4207 break;
4066 } 4208 }
4067 case Neon16: { 4209 case Neon16: {
4068 uint16_t src1[8], src2[8]; 4210 int16_t src1[8], src2[8];
4069 get_q_register(Vn, src1); 4211 get_q_register(Vn, src1);
4070 get_q_register(Vm, src2); 4212 get_q_register(Vm, src2);
4071 for (int i = 0; i < 8; i++) { 4213 for (int i = 0; i < 8; i++) {
4072 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFu : 0; 4214 if (min)
4215 src1[i] = std::min(src1[i], src2[i]);
4216 else
4217 src1[i] = std::max(src1[i], src2[i]);
4073 } 4218 }
4074 set_q_register(Vd, src1); 4219 set_q_register(Vd, src1);
4075 break; 4220 break;
4076 } 4221 }
4077 case Neon32: { 4222 case Neon32: {
4078 uint32_t src1[4], src2[4]; 4223 int32_t src1[4], src2[4];
4079 get_q_register(Vn, src1); 4224 get_q_register(Vn, src1);
4080 get_q_register(Vm, src2); 4225 get_q_register(Vm, src2);
4081 for (int i = 0; i < 4; i++) { 4226 for (int i = 0; i < 4; i++) {
4082 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0; 4227 if (min)
4228 src1[i] = std::min(src1[i], src2[i]);
4229 else
4230 src1[i] = std::max(src1[i], src2[i]);
4083 } 4231 }
4084 set_q_register(Vd, src1); 4232 set_q_register(Vd, src1);
4085 break; 4233 break;
4086 } 4234 }
4087 default: 4235 default:
4088 UNREACHABLE(); 4236 UNREACHABLE();
4089 break; 4237 break;
4090 } 4238 }
4091 } 4239 break;
4092 } else if (instr->Bits(11, 8) == 0xd && instr->Bit(20) == 0 && 4240 }
4093 instr->Bit(4) == 0) { 4241 case 0x8: {
4094 int Vd = instr->VFPDRegValue(kSimd128Precision); 4242 // vadd/vtst
4095 int Vm = instr->VFPMRegValue(kSimd128Precision); 4243 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4096 int Vn = instr->VFPNRegValue(kSimd128Precision); 4244 if (instr->Bit(4) == 0) {
4097 float src1[4], src2[4]; 4245 // vadd.i<size> Qd, Qm, Qn.
4098 get_q_register(Vn, src1); 4246 switch (size) {
4099 get_q_register(Vm, src2); 4247 case Neon8: {
4100 for (int i = 0; i < 4; i++) { 4248 uint8_t src1[16], src2[16];
4101 if (instr->Bit(21) == 0) { 4249 get_q_register(Vn, src1);
4102 // vadd.f32 Qd, Qm, Qn. 4250 get_q_register(Vm, src2);
4103 src1[i] = src1[i] + src2[i]; 4251 for (int i = 0; i < 16; i++) {
4104 } else { 4252 src1[i] += src2[i];
4105 // vsub.f32 Qd, Qm, Qn. 4253 }
4106 src1[i] = src1[i] - src2[i]; 4254 set_q_register(Vd, src1);
4107 } 4255 break;
4108 } 4256 }
4109 set_q_register(Vd, src1); 4257 case Neon16: {
4110 } else if (instr->Bits(11, 8) == 0x9 && instr->Bit(6) == 1 && 4258 uint16_t src1[8], src2[8];
4111 instr->Bit(4) == 1) { 4259 get_q_register(Vn, src1);
4112 // vmul.i<size> Qd, Qm, Qn. 4260 get_q_register(Vm, src2);
4113 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); 4261 for (int i = 0; i < 8; i++) {
4114 int Vd = instr->VFPDRegValue(kSimd128Precision); 4262 src1[i] += src2[i];
4115 int Vm = instr->VFPMRegValue(kSimd128Precision); 4263 }
4116 int Vn = instr->VFPNRegValue(kSimd128Precision); 4264 set_q_register(Vd, src1);
4117 switch (size) { 4265 break;
4118 case Neon8: { 4266 }
4119 uint8_t src1[16], src2[16]; 4267 case Neon32: {
4120 get_q_register(Vn, src1); 4268 uint32_t src1[4], src2[4];
4121 get_q_register(Vm, src2); 4269 get_q_register(Vn, src1);
4122 for (int i = 0; i < 16; i++) { 4270 get_q_register(Vm, src2);
4123 src1[i] *= src2[i]; 4271 for (int i = 0; i < 4; i++) {
4124 } 4272 src1[i] += src2[i];
4125 set_q_register(Vd, src1); 4273 }
4126 break; 4274 set_q_register(Vd, src1);
4127 } 4275 break;
4128 case Neon16: { 4276 }
4129 uint16_t src1[8], src2[8]; 4277 default:
4130 get_q_register(Vn, src1); 4278 UNREACHABLE();
4131 get_q_register(Vm, src2); 4279 break;
4132 for (int i = 0; i < 8; i++) { 4280 }
4133 src1[i] *= src2[i]; 4281 } else {
4134 } 4282 // vtst.i<size> Qd, Qm, Qn.
4135 set_q_register(Vd, src1); 4283 switch (size) {
4136 break; 4284 case Neon8: {
4137 } 4285 uint8_t src1[16], src2[16];
4138 case Neon32: { 4286 get_q_register(Vn, src1);
4139 uint32_t src1[4], src2[4]; 4287 get_q_register(Vm, src2);
4288 for (int i = 0; i < 16; i++) {
4289 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFu : 0;
4290 }
4291 set_q_register(Vd, src1);
4292 break;
4293 }
4294 case Neon16: {
4295 uint16_t src1[8], src2[8];
4296 get_q_register(Vn, src1);
4297 get_q_register(Vm, src2);
4298 for (int i = 0; i < 8; i++) {
4299 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFu : 0;
4300 }
4301 set_q_register(Vd, src1);
4302 break;
4303 }
4304 case Neon32: {
4305 uint32_t src1[4], src2[4];
4306 get_q_register(Vn, src1);
4307 get_q_register(Vm, src2);
4308 for (int i = 0; i < 4; i++) {
4309 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0;
4310 }
4311 set_q_register(Vd, src1);
4312 break;
4313 }
4314 default:
4315 UNREACHABLE();
4316 break;
4317 }
4318 }
4319 break;
4320 }
4321 case 0x9: {
4322 if (instr->Bit(6) == 1 && instr->Bit(4) == 1) {
4323 // vmul.i<size> Qd, Qm, Qn.
4324 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4325 switch (size) {
4326 case Neon8: {
4327 uint8_t src1[16], src2[16];
4328 get_q_register(Vn, src1);
4329 get_q_register(Vm, src2);
4330 for (int i = 0; i < 16; i++) {
4331 src1[i] *= src2[i];
4332 }
4333 set_q_register(Vd, src1);
4334 break;
4335 }
4336 case Neon16: {
4337 uint16_t src1[8], src2[8];
4338 get_q_register(Vn, src1);
4339 get_q_register(Vm, src2);
4340 for (int i = 0; i < 8; i++) {
4341 src1[i] *= src2[i];
4342 }
4343 set_q_register(Vd, src1);
4344 break;
4345 }
4346 case Neon32: {
4347 uint32_t src1[4], src2[4];
4348 get_q_register(Vn, src1);
4349 get_q_register(Vm, src2);
4350 for (int i = 0; i < 4; i++) {
4351 src1[i] *= src2[i];
4352 }
4353 set_q_register(Vd, src1);
4354 break;
4355 }
4356 default:
4357 UNREACHABLE();
4358 break;
4359 }
4360 } else {
4361 UNIMPLEMENTED();
4362 }
4363 break;
4364 }
4365 case 0xd: {
4366 if (instr->Bit(4) == 0) {
4367 float src1[4], src2[4];
4140 get_q_register(Vn, src1); 4368 get_q_register(Vn, src1);
4141 get_q_register(Vm, src2); 4369 get_q_register(Vm, src2);
4142 for (int i = 0; i < 4; i++) { 4370 for (int i = 0; i < 4; i++) {
4143 src1[i] *= src2[i]; 4371 if (instr->Bit(21) == 0) {
4372 // vadd.f32 Qd, Qm, Qn.
4373 src1[i] = src1[i] + src2[i];
4374 } else {
4375 // vsub.f32 Qd, Qm, Qn.
4376 src1[i] = src1[i] - src2[i];
4377 }
4144 } 4378 }
4145 set_q_register(Vd, src1); 4379 set_q_register(Vd, src1);
4146 break; 4380 } else {
4147 } 4381 UNIMPLEMENTED();
4148 default: 4382 }
4149 UNIMPLEMENTED(); 4383 break;
4150 break; 4384 }
4151 } 4385 case 0xe: {
4152 } else if (instr->Bits(11, 8) == 0xe && instr->Bits(21, 20) == 0 && 4386 if (instr->Bits(21, 20) == 0 && instr->Bit(4) == 0) {
4153 instr->Bit(4) == 0) { 4387 // vceq.f32.
4154 // vceq.f32. 4388 float src1[4], src2[4];
4155 int Vd = instr->VFPDRegValue(kSimd128Precision);
4156 int Vm = instr->VFPMRegValue(kSimd128Precision);
4157 int Vn = instr->VFPNRegValue(kSimd128Precision);
4158 float src1[4], src2[4];
4159 get_q_register(Vn, src1);
4160 get_q_register(Vm, src2);
4161 uint32_t dst[4];
4162 for (int i = 0; i < 4; i++) {
4163 dst[i] = (src1[i] == src2[i]) ? 0xFFFFFFFF : 0;
4164 }
4165 set_q_register(Vd, dst);
4166 } else if (instr->Bits(11, 8) == 1 && instr->Bits(21, 20) == 0 &&
4167 instr->Bit(6) == 1 && instr->Bit(4) == 1) {
4168 int Vd = instr->VFPDRegValue(kSimd128Precision);
4169 int Vm = instr->VFPMRegValue(kSimd128Precision);
4170 int Vn = instr->VFPNRegValue(kSimd128Precision);
4171 // vand Qd, Qm, Qn.
4172 uint32_t src1[4], src2[4];
4173 get_q_register(Vn, src1);
4174 get_q_register(Vm, src2);
4175 for (int i = 0; i < 4; i++) {
4176 src1[i] = src1[i] & src2[i];
4177 }
4178 set_q_register(Vd, src1);
4179 } else if (instr->Bits(11, 8) == 0x3) {
4180 // vcge/vcgt.s<size> Qd, Qm, Qn.
4181 bool ge = instr->Bit(4) == 1;
4182 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4183 int Vd = instr->VFPDRegValue(kSimd128Precision);
4184 int Vm = instr->VFPMRegValue(kSimd128Precision);
4185 int Vn = instr->VFPNRegValue(kSimd128Precision);
4186 switch (size) {
4187 case Neon8: {
4188 int8_t src1[16], src2[16];
4189 get_q_register(Vn, src1); 4389 get_q_register(Vn, src1);
4190 get_q_register(Vm, src2); 4390 get_q_register(Vm, src2);
4191 for (int i = 0; i < 16; i++) { 4391 uint32_t dst[4];
4192 if (ge) 4392 for (int i = 0; i < 4; i++) {
4193 src1[i] = src1[i] >= src2[i] ? 0xFF : 0; 4393 dst[i] = (src1[i] == src2[i]) ? 0xFFFFFFFF : 0;
4194 else 4394 }
4195 src1[i] = src1[i] > src2[i] ? 0xFF : 0; 4395 set_q_register(Vd, dst);
4196 } 4396 } else {
4197 set_q_register(Vd, src1); 4397 UNIMPLEMENTED();
4198 break; 4398 }
4199 } 4399 break;
4200 case Neon16: { 4400 }
4201 int16_t src1[8], src2[8]; 4401 case 0xf: {
4402 if (instr->Bit(20) == 0 && instr->Bit(6) == 1) {
4403 float src1[4], src2[4];
4202 get_q_register(Vn, src1); 4404 get_q_register(Vn, src1);
4203 get_q_register(Vm, src2); 4405 get_q_register(Vm, src2);
4204 for (int i = 0; i < 8; i++) { 4406 if (instr->Bit(4) == 1) {
4205 if (ge) 4407 if (instr->Bit(21) == 0) {
4206 src1[i] = src1[i] >= src2[i] ? 0xFFFF : 0; 4408 // vrecps.f32 Qd, Qm, Qn.
4207 else 4409 for (int i = 0; i < 4; i++) {
4208 src1[i] = src1[i] > src2[i] ? 0xFFFF : 0; 4410 src1[i] = 2.0f - src1[i] * src2[i];
4411 }
4412 } else {
4413 // vrsqrts.f32 Qd, Qm, Qn.
4414 for (int i = 0; i < 4; i++) {
4415 src1[i] = (3.0f - src1[i] * src2[i]) * 0.5f;
4416 }
4417 }
4418 } else {
4419 if (instr->Bit(21) == 1) {
4420 // vmin.f32 Qd, Qm, Qn.
4421 for (int i = 0; i < 4; i++) {
4422 src1[i] = std::min(src1[i], src2[i]);
4423 }
4424 } else {
4425 // vmax.f32 Qd, Qm, Qn.
4426 for (int i = 0; i < 4; i++) {
4427 src1[i] = std::max(src1[i], src2[i]);
4428 }
4429 }
4209 } 4430 }
4210 set_q_register(Vd, src1); 4431 set_q_register(Vd, src1);
4211 break; 4432 } else {
4212 } 4433 UNIMPLEMENTED();
4213 case Neon32: { 4434 }
4214 int32_t src1[4], src2[4]; 4435 break;
4215 get_q_register(Vn, src1); 4436 }
4216 get_q_register(Vm, src2); 4437 default:
4217 for (int i = 0; i < 4; i++) { 4438 UNIMPLEMENTED();
4218 if (ge) 4439 break;
4219 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFF : 0;
4220 else
4221 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFF : 0;
4222 }
4223 set_q_register(Vd, src1);
4224 break;
4225 }
4226 default:
4227 UNREACHABLE();
4228 break;
4229 }
4230 } else if (instr->Bits(11, 8) == 0xf && instr->Bit(20) == 0 &&
4231 instr->Bit(6) == 1) {
4232 int Vd = instr->VFPDRegValue(kSimd128Precision);
4233 int Vm = instr->VFPMRegValue(kSimd128Precision);
4234 int Vn = instr->VFPNRegValue(kSimd128Precision);
4235 float src1[4], src2[4];
4236 get_q_register(Vn, src1);
4237 get_q_register(Vm, src2);
4238 if (instr->Bit(4) == 1) {
4239 if (instr->Bit(21) == 0) {
4240 // vrecps.f32 Qd, Qm, Qn.
4241 for (int i = 0; i < 4; i++) {
4242 src1[i] = 2.0f - src1[i] * src2[i];
4243 }
4244 } else {
4245 // vrsqrts.f32 Qd, Qm, Qn.
4246 for (int i = 0; i < 4; i++) {
4247 src1[i] = (3.0f - src1[i] * src2[i]) * 0.5f;
4248 }
4249 }
4250 } else {
4251 if (instr->Bit(21) == 1) {
4252 // vmin.f32 Qd, Qm, Qn.
4253 for (int i = 0; i < 4; i++) {
4254 src1[i] = std::min(src1[i], src2[i]);
4255 }
4256 } else {
4257 // vmax.f32 Qd, Qm, Qn.
4258 for (int i = 0; i < 4; i++) {
4259 src1[i] = std::max(src1[i], src2[i]);
4260 }
4261 }
4262 }
4263 set_q_register(Vd, src1);
4264 } else if (instr->Bits(11, 8) == 0x6) {
4265 // vmin/vmax.s<size> Qd, Qm, Qn.
4266 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4267 int Vd = instr->VFPDRegValue(kSimd128Precision);
4268 int Vm = instr->VFPMRegValue(kSimd128Precision);
4269 int Vn = instr->VFPNRegValue(kSimd128Precision);
4270 bool min = instr->Bit(4) != 0;
4271 switch (size) {
4272 case Neon8: {
4273 int8_t src1[16], src2[16];
4274 get_q_register(Vn, src1);
4275 get_q_register(Vm, src2);
4276 for (int i = 0; i < 16; i++) {
4277 if (min)
4278 src1[i] = std::min(src1[i], src2[i]);
4279 else
4280 src1[i] = std::max(src1[i], src2[i]);
4281 }
4282 set_q_register(Vd, src1);
4283 break;
4284 }
4285 case Neon16: {
4286 int16_t src1[8], src2[8];
4287 get_q_register(Vn, src1);
4288 get_q_register(Vm, src2);
4289 for (int i = 0; i < 8; i++) {
4290 if (min)
4291 src1[i] = std::min(src1[i], src2[i]);
4292 else
4293 src1[i] = std::max(src1[i], src2[i]);
4294 }
4295 set_q_register(Vd, src1);
4296 break;
4297 }
4298 case Neon32: {
4299 int32_t src1[4], src2[4];
4300 get_q_register(Vn, src1);
4301 get_q_register(Vm, src2);
4302 for (int i = 0; i < 4; i++) {
4303 if (min)
4304 src1[i] = std::min(src1[i], src2[i]);
4305 else
4306 src1[i] = std::max(src1[i], src2[i]);
4307 }
4308 set_q_register(Vd, src1);
4309 break;
4310 }
4311 default:
4312 UNREACHABLE();
4313 break;
4314 }
4315 } else {
4316 UNIMPLEMENTED();
4317 } 4440 }
4318 break; 4441 break;
4442 }
4319 case 5: 4443 case 5:
4320 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 4444 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
4321 (instr->Bit(4) == 1)) { 4445 (instr->Bit(4) == 1)) {
4322 // vmovl signed 4446 // vmovl signed
4323 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); 4447 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED();
4324 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 4448 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
4325 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 4449 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
4326 int imm3 = instr->Bits(21, 19); 4450 int imm3 = instr->Bits(21, 19);
4327 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); 4451 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
4328 int esize = 8 * imm3; 4452 int esize = 8 * imm3;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
4429 break; 4553 break;
4430 } 4554 }
4431 default: 4555 default:
4432 UNREACHABLE(); 4556 UNREACHABLE();
4433 break; 4557 break;
4434 } 4558 }
4435 } else { 4559 } else {
4436 UNIMPLEMENTED(); 4560 UNIMPLEMENTED();
4437 } 4561 }
4438 break; 4562 break;
4439 case 6: 4563 case 6: {
4440 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { 4564 int Vd, Vm, Vn;
4441 // vsub.size Qd, Qm, Qn. 4565 if (instr->Bit(6) == 0) {
4442 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); 4566 Vd = instr->VFPDRegValue(kDoublePrecision);
4443 int Vd = instr->VFPDRegValue(kSimd128Precision); 4567 Vm = instr->VFPMRegValue(kDoublePrecision);
4444 int Vm = instr->VFPMRegValue(kSimd128Precision); 4568 Vn = instr->VFPNRegValue(kDoublePrecision);
4445 int Vn = instr->VFPNRegValue(kSimd128Precision); 4569 } else {
4446 switch (size) { 4570 Vd = instr->VFPDRegValue(kSimd128Precision);
4447 case Neon8: { 4571 Vm = instr->VFPMRegValue(kSimd128Precision);
4448 uint8_t src1[16], src2[16]; 4572 Vn = instr->VFPNRegValue(kSimd128Precision);
4449 get_q_register(Vn, src1); 4573 }
4450 get_q_register(Vm, src2); 4574 switch (instr->Bits(11, 8)) {
4451 for (int i = 0; i < 16; i++) { 4575 case 0x0: {
4452 src1[i] -= src2[i]; 4576 if (instr->Bit(4) == 1) {
4453 } 4577 // vqadd.u<size> Qd, Qm, Qn.
4454 set_q_register(Vd, src1); 4578 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4455 break; 4579 switch (size) {
4456 } 4580 case Neon8: {
4457 case Neon16: { 4581 uint8_t src1[16], src2[16];
4458 uint16_t src1[8], src2[8]; 4582 get_q_register(Vn, src1);
4459 get_q_register(Vn, src1); 4583 get_q_register(Vm, src2);
4460 get_q_register(Vm, src2); 4584 for (int i = 0; i < 16; i++) {
4461 for (int i = 0; i < 8; i++) { 4585 uint16_t sum = std::min(0x7f, src1[i] + src2[i]);
4462 src1[i] -= src2[i]; 4586 src1[i] = static_cast<uint8_t>(sum);
4463 } 4587 }
4464 set_q_register(Vd, src1); 4588 set_q_register(Vd, src1);
4465 break; 4589 break;
4466 } 4590 }
4467 case Neon32: { 4591 case Neon16: {
4468 uint32_t src1[4], src2[4]; 4592 uint16_t src1[8], src2[8];
4593 get_q_register(Vn, src1);
4594 get_q_register(Vm, src2);
4595 for (int i = 0; i < 8; i++) {
4596 uint32_t sum = std::min(0x7fff, src1[i] + src2[i]);
4597 src1[i] = static_cast<uint16_t>(sum);
4598 }
4599 set_q_register(Vd, src1);
4600 break;
4601 }
4602 case Neon32: {
4603 uint32_t src1[4], src2[4];
4604 get_q_register(Vn, src1);
4605 get_q_register(Vm, src2);
4606 for (int i = 0; i < 4; i++) {
4607 uint64_t s1 = src1[i];
4608 uint64_t s2 = src2[i];
4609 uint64_t sum = std::min(0x7fffffffULL, s1 + s2);
4610 src1[i] = static_cast<uint32_t>(sum);
4611 }
4612 set_q_register(Vd, src1);
4613 break;
4614 }
4615 default:
4616 UNREACHABLE();
4617 break;
4618 }
4619 } else {
4620 UNIMPLEMENTED();
4621 }
4622 break;
4623 }
4624 case 0x1: {
4625 if (instr->Bits(21, 20) == 1 && instr->Bit(4) == 1) {
4626 // vbsl.size Qd, Qm, Qn.
4627 uint32_t dst[4], src1[4], src2[4];
4628 get_q_register(Vd, dst);
4469 get_q_register(Vn, src1); 4629 get_q_register(Vn, src1);
4470 get_q_register(Vm, src2); 4630 get_q_register(Vm, src2);
4471 for (int i = 0; i < 4; i++) { 4631 for (int i = 0; i < 4; i++) {
4472 src1[i] -= src2[i]; 4632 dst[i] = (dst[i] & src1[i]) | (~dst[i] & src2[i]);
4473 } 4633 }
4474 set_q_register(Vd, src1); 4634 set_q_register(Vd, dst);
4475 break; 4635 } else if (instr->Bits(21, 20) == 0 && instr->Bit(4) == 1) {
4476 } 4636 if (instr->Bit(6) == 0) {
4477 default: 4637 // veor Dd, Dn, Dm
4478 UNREACHABLE(); 4638 uint64_t src1, src2;
4479 break; 4639 get_d_register(Vn, &src1);
4480 } 4640 get_d_register(Vm, &src2);
4481 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { 4641 src1 ^= src2;
4482 // vceq.size Qd, Qm, Qn. 4642 set_d_register(Vd, &src1);
4483 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); 4643
4484 int Vd = instr->VFPDRegValue(kSimd128Precision); 4644 } else {
4485 int Vm = instr->VFPMRegValue(kSimd128Precision); 4645 // veor Qd, Qn, Qm
4486 int Vn = instr->VFPNRegValue(kSimd128Precision); 4646 uint32_t src1[4], src2[4];
4487 switch (size) { 4647 get_q_register(Vn, src1);
4488 case Neon8: { 4648 get_q_register(Vm, src2);
4489 uint8_t src1[16], src2[16]; 4649 for (int i = 0; i < 4; i++) src1[i] ^= src2[i];
4490 get_q_register(Vn, src1); 4650 set_q_register(Vd, src1);
4491 get_q_register(Vm, src2); 4651 }
4492 for (int i = 0; i < 16; i++) { 4652 } else {
4493 src1[i] = (src1[i] == src2[i]) ? 0xFFu : 0; 4653 UNIMPLEMENTED();
4494 } 4654 }
4495 set_q_register(Vd, src1); 4655 break;
4496 break; 4656 }
4497 } 4657 case 0x2: {
4498 case Neon16: { 4658 if (instr->Bit(4) == 1) {
4499 uint16_t src1[8], src2[8]; 4659 // vqsub.u<size> Qd, Qm, Qn.
4500 get_q_register(Vn, src1); 4660 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4501 get_q_register(Vm, src2); 4661 switch (size) {
4502 for (int i = 0; i < 8; i++) { 4662 case Neon8: {
4503 src1[i] = (src1[i] == src2[i]) ? 0xFFFFu : 0; 4663 uint8_t src1[16], src2[16];
4504 } 4664 get_q_register(Vn, src1);
4505 set_q_register(Vd, src1); 4665 get_q_register(Vm, src2);
4506 break; 4666 for (int i = 0; i < 16; i++) {
4507 } 4667 int16_t diff = src1[i] - src2[i];
4508 case Neon32: { 4668 diff = std::max(0, std::min(0x7f, s1 - s2));
4509 uint32_t src1[4], src2[4]; 4669 src1[i] = static_cast<uint8_t>(diff);
4670 }
4671 set_q_register(Vd, src1);
4672 break;
4673 }
4674 case Neon16: {
4675 uint16_t src1[8], src2[8];
4676 get_q_register(Vn, src1);
4677 get_q_register(Vm, src2);
4678 for (int i = 0; i < 8; i++) {
4679 int32_t diff = src1[i] - src2[i];
4680 diff = std::max(0, std::min(0x7fff, s1 - s2));
4681 src1[i] = static_cast<uint16_t>(diff);
4682 }
4683 set_q_register(Vd, src1);
4684 break;
4685 }
4686 case Neon32: {
4687 uint32_t src1[4], src2[4];
4688 get_q_register(Vn, src1);
4689 get_q_register(Vm, src2);
4690 for (int i = 0; i < 4; i++) {
4691 int64_t diff = src1[i] - src2[i];
4692 diff = std::max(0, std::min(0x7fffffff, s1 - s2));
4693 src1[i] = static_cast<uint16_t>(diff);
4694 }
4695 set_q_register(Vd, src1);
4696 break;
4697 }
4698 default:
4699 UNREACHABLE();
4700 break;
4701 }
4702 } else {
4703 UNIMPLEMENTED();
4704 }
4705 break;
4706 }
4707 case 0x3: {
4708 // vcge/vcgt.u<size> Qd, Qm, Qn.
4709 bool ge = instr->Bit(4) == 1;
4710 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4711 switch (size) {
4712 case Neon8: {
4713 uint8_t src1[16], src2[16];
4714 get_q_register(Vn, src1);
4715 get_q_register(Vm, src2);
4716 for (int i = 0; i < 16; i++) {
4717 if (ge)
4718 src1[i] = src1[i] >= src2[i] ? 0xFFu : 0;
4719 else
4720 src1[i] = src1[i] > src2[i] ? 0xFFu : 0;
4721 }
4722 set_q_register(Vd, src1);
4723 break;
4724 }
4725 case Neon16: {
4726 uint16_t src1[8], src2[8];
4727 get_q_register(Vn, src1);
4728 get_q_register(Vm, src2);
4729 for (int i = 0; i < 8; i++) {
4730 if (ge)
4731 src1[i] = src1[i] >= src2[i] ? 0xFFFFu : 0;
4732 else
4733 src1[i] = src1[i] > src2[i] ? 0xFFFFu : 0;
4734 }
4735 set_q_register(Vd, src1);
4736 break;
4737 }
4738 case Neon32: {
4739 uint32_t src1[4], src2[4];
4740 get_q_register(Vn, src1);
4741 get_q_register(Vm, src2);
4742 for (int i = 0; i < 4; i++) {
4743 if (ge)
4744 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0;
4745 else
4746 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0;
4747 }
4748 set_q_register(Vd, src1);
4749 break;
4750 }
4751 default:
4752 UNREACHABLE();
4753 break;
4754 }
4755 break;
4756 }
4757 case 0x6: {
4758 // vmin/vmax.u<size> Qd, Qm, Qn.
4759 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4760 bool min = instr->Bit(4) != 0;
4761 switch (size) {
4762 case Neon8: {
4763 uint8_t src1[16], src2[16];
4764 get_q_register(Vn, src1);
4765 get_q_register(Vm, src2);
4766 for (int i = 0; i < 16; i++) {
4767 if (min)
4768 src1[i] = std::min(src1[i], src2[i]);
4769 else
4770 src1[i] = std::max(src1[i], src2[i]);
4771 }
4772 set_q_register(Vd, src1);
4773 break;
4774 }
4775 case Neon16: {
4776 uint16_t src1[8], src2[8];
4777 get_q_register(Vn, src1);
4778 get_q_register(Vm, src2);
4779 for (int i = 0; i < 8; i++) {
4780 if (min)
4781 src1[i] = std::min(src1[i], src2[i]);
4782 else
4783 src1[i] = std::max(src1[i], src2[i]);
4784 }
4785 set_q_register(Vd, src1);
4786 break;
4787 }
4788 case Neon32: {
4789 uint32_t src1[4], src2[4];
4790 get_q_register(Vn, src1);
4791 get_q_register(Vm, src2);
4792 for (int i = 0; i < 4; i++) {
4793 if (min)
4794 src1[i] = std::min(src1[i], src2[i]);
4795 else
4796 src1[i] = std::max(src1[i], src2[i]);
4797 }
4798 set_q_register(Vd, src1);
4799 break;
4800 }
4801 default:
4802 UNREACHABLE();
4803 break;
4804 }
4805 break;
4806 }
4807 case 0x8: {
4808 if (instr->Bit(4) == 0) {
4809 // vsub.size Qd, Qm, Qn.
4810 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4811 switch (size) {
4812 case Neon8: {
4813 uint8_t src1[16], src2[16];
4814 get_q_register(Vn, src1);
4815 get_q_register(Vm, src2);
4816 for (int i = 0; i < 16; i++) {
4817 src1[i] -= src2[i];
4818 }
4819 set_q_register(Vd, src1);
4820 break;
4821 }
4822 case Neon16: {
4823 uint16_t src1[8], src2[8];
4824 get_q_register(Vn, src1);
4825 get_q_register(Vm, src2);
4826 for (int i = 0; i < 8; i++) {
4827 src1[i] -= src2[i];
4828 }
4829 set_q_register(Vd, src1);
4830 break;
4831 }
4832 case Neon32: {
4833 uint32_t src1[4], src2[4];
4834 get_q_register(Vn, src1);
4835 get_q_register(Vm, src2);
4836 for (int i = 0; i < 4; i++) {
4837 src1[i] -= src2[i];
4838 }
4839 set_q_register(Vd, src1);
4840 break;
4841 }
4842 default:
4843 UNREACHABLE();
4844 break;
4845 }
4846 } else {
4847 // vceq.size Qd, Qm, Qn.
4848 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4849 switch (size) {
4850 case Neon8: {
4851 uint8_t src1[16], src2[16];
4852 get_q_register(Vn, src1);
4853 get_q_register(Vm, src2);
4854 for (int i = 0; i < 16; i++) {
4855 src1[i] = (src1[i] == src2[i]) ? 0xFFu : 0;
4856 }
4857 set_q_register(Vd, src1);
4858 break;
4859 }
4860 case Neon16: {
4861 uint16_t src1[8], src2[8];
4862 get_q_register(Vn, src1);
4863 get_q_register(Vm, src2);
4864 for (int i = 0; i < 8; i++) {
4865 src1[i] = (src1[i] == src2[i]) ? 0xFFFFu : 0;
4866 }
4867 set_q_register(Vd, src1);
4868 break;
4869 }
4870 case Neon32: {
4871 uint32_t src1[4], src2[4];
4872 get_q_register(Vn, src1);
4873 get_q_register(Vm, src2);
4874 for (int i = 0; i < 4; i++) {
4875 src1[i] = (src1[i] == src2[i]) ? 0xFFFFFFFFu : 0;
4876 }
4877 set_q_register(Vd, src1);
4878 break;
4879 }
4880 default:
4881 UNREACHABLE();
4882 break;
4883 }
4884 }
4885 break;
4886 }
4887 case 0xd: {
4888 if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) {
4889 // vmul.f32 Qd, Qn, Qm
4890 float src1[4], src2[4];
4510 get_q_register(Vn, src1); 4891 get_q_register(Vn, src1);
4511 get_q_register(Vm, src2); 4892 get_q_register(Vm, src2);
4512 for (int i = 0; i < 4; i++) { 4893 for (int i = 0; i < 4; i++) {
4513 src1[i] = (src1[i] == src2[i]) ? 0xFFFFFFFFu : 0; 4894 src1[i] = src1[i] * src2[i];
4514 } 4895 }
4515 set_q_register(Vd, src1); 4896 set_q_register(Vd, src1);
4516 break; 4897 } else {
4517 } 4898 UNIMPLEMENTED();
4518 default: 4899 }
4519 UNREACHABLE(); 4900 break;
4520 break; 4901 }
4521 } 4902 case 0xe: {
4522 } else if (instr->Bits(11, 8) == 1 && instr->Bits(21, 20) == 1 && 4903 if (instr->Bit(20) == 0 && instr->Bit(4) == 0) {
4523 instr->Bit(4) == 1) { 4904 // vcge/vcgt.f32 Qd, Qm, Qn
4524 // vbsl.size Qd, Qm, Qn. 4905 bool ge = instr->Bit(21) == 0;
4525 int Vd = instr->VFPDRegValue(kSimd128Precision); 4906 float src1[4], src2[4];
4526 int Vm = instr->VFPMRegValue(kSimd128Precision);
4527 int Vn = instr->VFPNRegValue(kSimd128Precision);
4528 uint32_t dst[4], src1[4], src2[4];
4529 get_q_register(Vd, dst);
4530 get_q_register(Vn, src1);
4531 get_q_register(Vm, src2);
4532 for (int i = 0; i < 4; i++) {
4533 dst[i] = (dst[i] & src1[i]) | (~dst[i] & src2[i]);
4534 }
4535 set_q_register(Vd, dst);
4536 } else if (instr->Bits(11, 8) == 1 && instr->Bits(21, 20) == 0 &&
4537 instr->Bit(4) == 1) {
4538 if (instr->Bit(6) == 0) {
4539 // veor Dd, Dn, Dm
4540 int Vd = instr->VFPDRegValue(kDoublePrecision);
4541 int Vn = instr->VFPNRegValue(kDoublePrecision);
4542 int Vm = instr->VFPMRegValue(kDoublePrecision);
4543 uint64_t src1, src2;
4544 get_d_register(Vn, &src1);
4545 get_d_register(Vm, &src2);
4546 src1 ^= src2;
4547 set_d_register(Vd, &src1);
4548
4549 } else {
4550 // veor Qd, Qn, Qm
4551 int Vd = instr->VFPDRegValue(kSimd128Precision);
4552 int Vn = instr->VFPNRegValue(kSimd128Precision);
4553 int Vm = instr->VFPMRegValue(kSimd128Precision);
4554 uint32_t src1[4], src2[4];
4555 get_q_register(Vn, src1);
4556 get_q_register(Vm, src2);
4557 for (int i = 0; i < 4; i++) src1[i] ^= src2[i];
4558 set_q_register(Vd, src1);
4559 }
4560 } else if (instr->Bits(11, 8) == 0xd && instr->Bit(21) == 0 &&
4561 instr->Bit(6) == 1 && instr->Bit(4) == 1) {
4562 // vmul.f32 Qd, Qn, Qm
4563 int Vd = instr->VFPDRegValue(kSimd128Precision);
4564 int Vn = instr->VFPNRegValue(kSimd128Precision);
4565 int Vm = instr->VFPMRegValue(kSimd128Precision);
4566 float src1[4], src2[4];
4567 get_q_register(Vn, src1);
4568 get_q_register(Vm, src2);
4569 for (int i = 0; i < 4; i++) {
4570 src1[i] = src1[i] * src2[i];
4571 }
4572 set_q_register(Vd, src1);
4573 } else if (instr->Bits(11, 8) == 0xe && instr->Bit(20) == 0 &&
4574 instr->Bit(4) == 0) {
4575 // vcge/vcgt.f32 Qd, Qm, Qn
4576 bool ge = instr->Bit(21) == 0;
4577 int Vd = instr->VFPDRegValue(kSimd128Precision);
4578 int Vm = instr->VFPMRegValue(kSimd128Precision);
4579 int Vn = instr->VFPNRegValue(kSimd128Precision);
4580 float src1[4], src2[4];
4581 get_q_register(Vn, src1);
4582 get_q_register(Vm, src2);
4583 uint32_t dst[4];
4584 for (int i = 0; i < 4; i++) {
4585 if (ge) {
4586 dst[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0;
4587 } else {
4588 dst[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0;
4589 }
4590 }
4591 set_q_register(Vd, dst);
4592 } else if (instr->Bits(11, 8) == 0x3) {
4593 // vcge/vcgt.u<size> Qd, Qm, Qn.
4594 bool ge = instr->Bit(4) == 1;
4595 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
4596 int Vd = instr->VFPDRegValue(kSimd128Precision);
4597 int Vm = instr->VFPMRegValue(kSimd128Precision);
4598 int Vn = instr->VFPNRegValue(kSimd128Precision);
4599 switch (size) {
4600 case Neon8: {
4601 uint8_t src1[16], src2[16];
4602 get_q_register(Vn, src1); 4907 get_q_register(Vn, src1);
4603 get_q_register(Vm, src2); 4908 get_q_register(Vm, src2);
4604 for (int i = 0; i < 16; i++) { 4909 uint32_t dst[4];
4605 if (ge)
4606 src1[i] = src1[i] >= src2[i] ? 0xFFu : 0;
4607 else
4608 src1[i] = src1[i] > src2[i] ? 0xFFu : 0;
4609 }
4610 set_q_register(Vd, src1);
4611 break;
4612 }
4613 case Neon16: {
4614 uint16_t src1[8], src2[8];
4615 get_q_register(Vn, src1);
4616 get_q_register(Vm, src2);
4617 for (int i = 0; i < 8; i++) {
4618 if (ge)
4619 src1[i] = src1[i] >= src2[i] ? 0xFFFFu : 0;
4620 else
4621 src1[i] = src1[i] > src2[i] ? 0xFFFFu : 0;
4622 }
4623 set_q_register(Vd, src1);
4624 break;
4625 }
4626 case Neon32: {
4627 uint32_t src1[4], src2[4];
4628 get_q_register(Vn, src1);
4629 get_q_register(Vm, src2);
4630 for (int i = 0; i < 4; i++) { 4910 for (int i = 0; i < 4; i++) {
4631 if (ge) 4911 if (ge) {
4632 src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0; 4912 dst[i] = src1[i] >= src2[i] ? 0xFFFFFFFFu : 0;
4633 else 4913 } else {
4634 src1[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0; 4914 dst[i] = src1[i] > src2[i] ? 0xFFFFFFFFu : 0;
4635 } 4915 }
4636 set_q_register(Vd, src1); 4916 }
4637 break; 4917 set_q_register(Vd, dst);
4638 } 4918 } else {
4639 default: 4919 UNIMPLEMENTED();
4640 UNREACHABLE(); 4920 }
4641 break; 4921 break;
4642 } 4922 }
4643 } else if (instr->Bits(11, 8) == 0x6) { 4923 default:
4644 // vmin/vmax.u<size> Qd, Qm, Qn. 4924 UNREACHABLE();
4645 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); 4925 break;
4646 int Vd = instr->VFPDRegValue(kSimd128Precision);
4647 int Vm = instr->VFPMRegValue(kSimd128Precision);
4648 int Vn = instr->VFPNRegValue(kSimd128Precision);
4649 bool min = instr->Bit(4) != 0;
4650 switch (size) {
4651 case Neon8: {
4652 uint8_t src1[16], src2[16];
4653 get_q_register(Vn, src1);
4654 get_q_register(Vm, src2);
4655 for (int i = 0; i < 16; i++) {
4656 if (min)
4657 src1[i] = std::min(src1[i], src2[i]);
4658 else
4659 src1[i] = std::max(src1[i], src2[i]);
4660 }
4661 set_q_register(Vd, src1);
4662 break;
4663 }
4664 case Neon16: {
4665 uint16_t src1[8], src2[8];
4666 get_q_register(Vn, src1);
4667 get_q_register(Vm, src2);
4668 for (int i = 0; i < 8; i++) {
4669 if (min)
4670 src1[i] = std::min(src1[i], src2[i]);
4671 else
4672 src1[i] = std::max(src1[i], src2[i]);
4673 }
4674 set_q_register(Vd, src1);
4675 break;
4676 }
4677 case Neon32: {
4678 uint32_t src1[4], src2[4];
4679 get_q_register(Vn, src1);
4680 get_q_register(Vm, src2);
4681 for (int i = 0; i < 4; i++) {
4682 if (min)
4683 src1[i] = std::min(src1[i], src2[i]);
4684 else
4685 src1[i] = std::max(src1[i], src2[i]);
4686 }
4687 set_q_register(Vd, src1);
4688 break;
4689 }
4690 default:
4691 UNREACHABLE();
4692 break;
4693 }
4694 } else {
4695 UNIMPLEMENTED();
4696 } 4926 }
4697 break; 4927 break;
4928 }
4698 case 7: 4929 case 7:
4699 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 4930 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
4700 (instr->Bit(4) == 1)) { 4931 (instr->Bit(4) == 1)) {
4701 // vmovl unsigned 4932 // vmovl unsigned
4702 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); 4933 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED();
4703 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 4934 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
4704 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 4935 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
4705 int imm3 = instr->Bits(21, 19); 4936 int imm3 = instr->Bits(21, 19);
4706 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); 4937 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
4707 int esize = 8 * imm3; 4938 int esize = 8 * imm3;
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after
5823 processor->prev_ = nullptr; 6054 processor->prev_ = nullptr;
5824 processor->next_ = nullptr; 6055 processor->next_ = nullptr;
5825 } 6056 }
5826 6057
5827 } // namespace internal 6058 } // namespace internal
5828 } // namespace v8 6059 } // namespace v8
5829 6060
5830 #endif // USE_SIMULATOR 6061 #endif // USE_SIMULATOR
5831 6062
5832 #endif // V8_TARGET_ARCH_ARM 6063 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/disasm-arm.cc ('k') | test/cctest/test-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698