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

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

Issue 2639443002: [ARM] Refactor NEON binary ops in assembler. (Closed)
Patch Set: Make NeonDataType match NeonSize. Created 3 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
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 3860 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 3871
3872 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) { 3872 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
3873 // Instruction details available in ARM DDI 0406C.b, A8.8.346. 3873 // Instruction details available in ARM DDI 0406C.b, A8.8.346.
3874 // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) | 3874 // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
3875 // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0) 3875 // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
3876 DCHECK(IsEnabled(NEON)); 3876 DCHECK(IsEnabled(NEON));
3877 int vd, d; 3877 int vd, d;
3878 dst.split_code(&vd, &d); 3878 dst.split_code(&vd, &d);
3879 int vm, m; 3879 int vm, m;
3880 src.split_code(&vm, &m); 3880 src.split_code(&vm, &m);
3881 emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 | 3881 int U = NeonU(dt);
3882 (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm); 3882 int imm3 = 1 << NeonSz(dt);
3883 emit(0xFU * B28 | B25 | U * B24 | B23 | d * B22 | imm3 * B19 | vd * B12 |
3884 0xA * B8 | m * B5 | B4 | vm);
3883 } 3885 }
3884 3886
3885 static int EncodeScalar(NeonDataType dt, int index) { 3887 static int EncodeScalar(NeonDataType dt, int index) {
3886 int opc1_opc2 = 0; 3888 int opc1_opc2 = 0;
3887 DCHECK_LE(0, index); 3889 DCHECK_LE(0, index);
3888 switch (dt) { 3890 switch (dt) {
3889 case NeonS8: 3891 case NeonS8:
3890 case NeonU8: 3892 case NeonU8:
3891 DCHECK_GT(8, index); 3893 DCHECK_GT(8, index);
3892 opc1_opc2 = 0x8 | index; 3894 opc1_opc2 = 0x8 | index;
(...skipping 28 matching lines...) Expand all
3921 } 3923 }
3922 3924
3923 void Assembler::vmov(NeonDataType dt, Register dst, DwVfpRegister src, 3925 void Assembler::vmov(NeonDataType dt, Register dst, DwVfpRegister src,
3924 int index) { 3926 int index) {
3925 // Instruction details available in ARM DDI 0406C.b, A8.8.942. 3927 // Instruction details available in ARM DDI 0406C.b, A8.8.942.
3926 // vmov Arm scalar to core register. 3928 // vmov Arm scalar to core register.
3927 DCHECK(dt == NeonS32 || dt == NeonU32 || IsEnabled(NEON)); 3929 DCHECK(dt == NeonS32 || dt == NeonU32 || IsEnabled(NEON));
3928 int vn, n; 3930 int vn, n;
3929 src.split_code(&vn, &n); 3931 src.split_code(&vn, &n);
3930 int opc1_opc2 = EncodeScalar(dt, index); 3932 int opc1_opc2 = EncodeScalar(dt, index);
3931 int u = (dt & NeonDataTypeUMask) != 0 ? 1 : 0; 3933 int u = NeonU(dt);
3932 emit(0xEEu * B24 | u * B23 | B20 | vn * B16 | dst.code() * B12 | 0xB * B8 | 3934 emit(0xEEu * B24 | u * B23 | B20 | vn * B16 | dst.code() * B12 | 0xB * B8 |
3933 n * B7 | B4 | opc1_opc2); 3935 n * B7 | B4 | opc1_opc2);
3934 } 3936 }
3935 3937
3936 void Assembler::vmov(const QwNeonRegister dst, const QwNeonRegister src) { 3938 void Assembler::vmov(const QwNeonRegister dst, const QwNeonRegister src) {
3937 // Instruction details available in ARM DDI 0406C.b, A8-938. 3939 // Instruction details available in ARM DDI 0406C.b, A8-938.
3938 // vmov is encoded as vorr. 3940 // vmov is encoded as vorr.
3939 vorr(dst, src, src); 3941 vorr(dst, src, src);
3940 } 3942 }
3941 3943
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
4202 } 4204 }
4203 4205
4204 void Assembler::vorr(QwNeonRegister dst, QwNeonRegister src1, 4206 void Assembler::vorr(QwNeonRegister dst, QwNeonRegister src1,
4205 QwNeonRegister src2) { 4207 QwNeonRegister src2) {
4206 // Qd = vorr(Qn, Qm) SIMD OR. 4208 // Qd = vorr(Qn, Qm) SIMD OR.
4207 // Instruction details available in ARM DDI 0406C.b, A8.8.976. 4209 // Instruction details available in ARM DDI 0406C.b, A8.8.976.
4208 DCHECK(IsEnabled(NEON)); 4210 DCHECK(IsEnabled(NEON));
4209 emit(EncodeNeonBinaryBitwiseOp(VORR, dst, src1, src2)); 4211 emit(EncodeNeonBinaryBitwiseOp(VORR, dst, src1, src2));
4210 } 4212 }
4211 4213
4212 void Assembler::vadd(QwNeonRegister dst, const QwNeonRegister src1, 4214 enum FPBinOp {
4213 const QwNeonRegister src2) { 4215 VADDF,
4214 DCHECK(IsEnabled(NEON)); 4216 VSUBF,
4215 // Qd = vadd(Qn, Qm) SIMD floating point addition. 4217 VMULF,
4216 // Instruction details available in ARM DDI 0406C.b, A8-830. 4218 VMINF,
4219 VMAXF,
4220 VRECPS,
4221 VRSQRTS,
4222 VCEQF,
4223 VCGEF,
4224 VCGTF
4225 };
4226
4227 static Instr EncodeNeonBinOp(FPBinOp op, QwNeonRegister dst,
4228 QwNeonRegister src1, QwNeonRegister src2) {
4229 int op_encoding = 0;
4230 switch (op) {
4231 case VADDF:
4232 op_encoding = 0xD * B8;
4233 break;
4234 case VSUBF:
4235 op_encoding = B21 | 0xD * B8;
4236 break;
4237 case VMULF:
4238 op_encoding = B24 | 0xD * B8 | B4;
4239 break;
4240 case VMINF:
4241 op_encoding = B21 | 0xF * B8;
4242 break;
4243 case VMAXF:
4244 op_encoding = 0xF * B8;
4245 break;
4246 case VRECPS:
4247 op_encoding = 0xF * B8 | B4;
4248 break;
4249 case VRSQRTS:
4250 op_encoding = B21 | 0xF * B8 | B4;
4251 break;
4252 case VCEQF:
4253 op_encoding = 0xE * B8;
4254 break;
4255 case VCGEF:
4256 op_encoding = B24 | 0xE * B8;
4257 break;
4258 case VCGTF:
4259 op_encoding = B24 | B21 | 0xE * B8;
4260 break;
4261 default:
4262 UNREACHABLE();
4263 break;
4264 }
4217 int vd, d; 4265 int vd, d;
4218 dst.split_code(&vd, &d); 4266 dst.split_code(&vd, &d);
4219 int vn, n; 4267 int vn, n;
4220 src1.split_code(&vn, &n); 4268 src1.split_code(&vn, &n);
4221 int vm, m; 4269 int vm, m;
4222 src2.split_code(&vm, &m); 4270 src2.split_code(&vm, &m);
4223 emit(0x1E4U * B23 | d * B22 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 | B6 | 4271 return 0x1E4U * B23 | d * B22 | vn * B16 | vd * B12 | n * B7 | B6 | m * B5 |
4224 m * B5 | vm); 4272 vm | op_encoding;
4225 } 4273 }
4226 4274
4227 void Assembler::vadd(NeonSize size, QwNeonRegister dst, 4275 enum IntegerBinOp { VADD, VSUB, VMUL, VMIN, VMAX, VTST, VCEQ, VCGE, VCGT };
4228 const QwNeonRegister src1, const QwNeonRegister src2) { 4276
4229 DCHECK(IsEnabled(NEON)); 4277 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonDataType dt,
4230 // Qd = vadd(Qn, Qm) SIMD integer addition. 4278 const QwNeonRegister dst,
4231 // Instruction details available in ARM DDI 0406C.b, A8-828. 4279 const QwNeonRegister src1,
4280 const QwNeonRegister src2) {
4281 int op_encoding = 0;
4282 switch (op) {
4283 case VADD:
4284 op_encoding = 0x8 * B8;
4285 break;
4286 case VSUB:
4287 op_encoding = B24 | 0x8 * B8;
4288 break;
4289 case VMUL:
4290 op_encoding = 0x9 * B8 | B4;
4291 break;
4292 case VMIN:
4293 op_encoding = 0x6 * B8 | B4;
4294 break;
4295 case VMAX:
4296 op_encoding = 0x6 * B8;
4297 break;
4298 case VTST:
4299 op_encoding = 0x8 * B8 | B4;
4300 break;
4301 case VCEQ:
4302 op_encoding = B24 | 0x8 * B8 | B4;
4303 break;
4304 case VCGE:
4305 op_encoding = 0x3 * B8 | B4;
4306 break;
4307 case VCGT:
4308 op_encoding = 0x3 * B8;
4309 break;
4310 default:
4311 UNREACHABLE();
4312 break;
4313 }
4232 int vd, d; 4314 int vd, d;
4233 dst.split_code(&vd, &d); 4315 dst.split_code(&vd, &d);
4234 int vn, n; 4316 int vn, n;
4235 src1.split_code(&vn, &n); 4317 src1.split_code(&vn, &n);
4236 int vm, m; 4318 int vm, m;
4237 src2.split_code(&vm, &m); 4319 src2.split_code(&vm, &m);
4238 int sz = static_cast<int>(size); 4320 int size = NeonSz(dt);
4239 emit(0x1E4U * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 | 4321 int u = NeonU(dt);
4240 n * B7 | B6 | m * B5 | vm); 4322 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 |
4323 n * B7 | B6 | m * B5 | vm | op_encoding;
4241 } 4324 }
4242 4325
4243 void Assembler::vsub(QwNeonRegister dst, const QwNeonRegister src1, 4326 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonSize size,
4244 const QwNeonRegister src2) { 4327 const QwNeonRegister dst,
4328 const QwNeonRegister src1,
4329 const QwNeonRegister src2) {
4330 // Map NeonSize values to the signed values in NeonDataType, so the U bit
4331 // will be 0.
4332 return EncodeNeonBinOp(op, static_cast<NeonDataType>(size), dst, src1, src2);
4333 }
4334
4335 void Assembler::vadd(QwNeonRegister dst, QwNeonRegister src1,
4336 QwNeonRegister src2) {
4337 DCHECK(IsEnabled(NEON));
4338 // Qd = vadd(Qn, Qm) SIMD floating point addition.
4339 // Instruction details available in ARM DDI 0406C.b, A8-830.
4340 emit(EncodeNeonBinOp(VADDF, dst, src1, src2));
4341 }
4342
4343 void Assembler::vadd(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
4344 QwNeonRegister src2) {
4345 DCHECK(IsEnabled(NEON));
4346 // Qd = vadd(Qn, Qm) SIMD integer addition.
4347 // Instruction details available in ARM DDI 0406C.b, A8-828.
4348 emit(EncodeNeonBinOp(VADD, size, dst, src1, src2));
4349 }
4350
4351 void Assembler::vsub(QwNeonRegister dst, QwNeonRegister src1,
4352 QwNeonRegister src2) {
4245 DCHECK(IsEnabled(NEON)); 4353 DCHECK(IsEnabled(NEON));
4246 // Qd = vsub(Qn, Qm) SIMD floating point subtraction. 4354 // Qd = vsub(Qn, Qm) SIMD floating point subtraction.
4247 // Instruction details available in ARM DDI 0406C.b, A8-1086. 4355 // Instruction details available in ARM DDI 0406C.b, A8-1086.
4248 int vd, d; 4356 emit(EncodeNeonBinOp(VSUBF, dst, src1, src2));
4249 dst.split_code(&vd, &d);
4250 int vn, n;
4251 src1.split_code(&vn, &n);
4252 int vm, m;
4253 src2.split_code(&vm, &m);
4254 emit(0x1E4U * B23 | d * B22 | B21 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 |
4255 B6 | m * B5 | vm);
4256 } 4357 }
4257 4358
4258 void Assembler::vsub(NeonSize size, QwNeonRegister dst, 4359 void Assembler::vsub(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
4259 const QwNeonRegister src1, const QwNeonRegister src2) { 4360 QwNeonRegister src2) {
4260 DCHECK(IsEnabled(NEON)); 4361 DCHECK(IsEnabled(NEON));
4261 // Qd = vsub(Qn, Qm) SIMD integer subtraction. 4362 // Qd = vsub(Qn, Qm) SIMD integer subtraction.
4262 // Instruction details available in ARM DDI 0406C.b, A8-1084. 4363 // Instruction details available in ARM DDI 0406C.b, A8-1084.
4263 int vd, d; 4364 emit(EncodeNeonBinOp(VSUB, size, dst, src1, src2));
4264 dst.split_code(&vd, &d);
4265 int vn, n;
4266 src1.split_code(&vn, &n);
4267 int vm, m;
4268 src2.split_code(&vm, &m);
4269 int sz = static_cast<int>(size);
4270 emit(0x1E6U * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 |
4271 n * B7 | B6 | m * B5 | vm);
4272 } 4365 }
4273 4366
4274 void Assembler::vmul(QwNeonRegister dst, const QwNeonRegister src1, 4367 void Assembler::vmul(QwNeonRegister dst, QwNeonRegister src1,
4275 const QwNeonRegister src2) { 4368 QwNeonRegister src2) {
4276 DCHECK(IsEnabled(NEON)); 4369 DCHECK(IsEnabled(NEON));
4277 // Qd = vadd(Qn, Qm) SIMD floating point multiply. 4370 // Qd = vadd(Qn, Qm) SIMD floating point multiply.
4278 // Instruction details available in ARM DDI 0406C.b, A8-958. 4371 // Instruction details available in ARM DDI 0406C.b, A8-958.
4279 int vd, d; 4372 emit(EncodeNeonBinOp(VMULF, dst, src1, src2));
4280 dst.split_code(&vd, &d);
4281 int vn, n;
4282 src1.split_code(&vn, &n);
4283 int vm, m;
4284 src2.split_code(&vm, &m);
4285 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 | B6 |
4286 m * B5 | B4 | vm);
4287 } 4373 }
4288 4374
4289 void Assembler::vmul(NeonSize size, QwNeonRegister dst, 4375 void Assembler::vmul(NeonSize size, QwNeonRegister dst,
4290 const QwNeonRegister src1, const QwNeonRegister src2) { 4376 const QwNeonRegister src1, const QwNeonRegister src2) {
4291 DCHECK(IsEnabled(NEON)); 4377 DCHECK(IsEnabled(NEON));
4292 // Qd = vadd(Qn, Qm) SIMD integer multiply. 4378 // Qd = vadd(Qn, Qm) SIMD integer multiply.
4293 // Instruction details available in ARM DDI 0406C.b, A8-960. 4379 // Instruction details available in ARM DDI 0406C.b, A8-960.
4294 int vd, d; 4380 emit(EncodeNeonBinOp(VMUL, size, dst, src1, src2));
4295 dst.split_code(&vd, &d);
4296 int vn, n;
4297 src1.split_code(&vn, &n);
4298 int vm, m;
4299 src2.split_code(&vm, &m);
4300 int sz = static_cast<int>(size);
4301 emit(0x1E4U * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x9 * B8 |
4302 n * B7 | B6 | m * B5 | B4 | vm);
4303 }
4304
4305 static Instr EncodeNeonMinMax(bool is_min, QwNeonRegister dst,
4306 QwNeonRegister src1, QwNeonRegister src2) {
4307 int vd, d;
4308 dst.split_code(&vd, &d);
4309 int vn, n;
4310 src1.split_code(&vn, &n);
4311 int vm, m;
4312 src2.split_code(&vm, &m);
4313 int min = is_min ? 1 : 0;
4314 return 0x1E4U * B23 | d * B22 | min * B21 | vn * B16 | vd * B12 | 0xF * B8 |
4315 n * B7 | B6 | m * B5 | vm;
4316 }
4317
4318 static Instr EncodeNeonMinMax(bool is_min, NeonDataType dt, QwNeonRegister dst,
4319 QwNeonRegister src1, QwNeonRegister src2) {
4320 int vd, d;
4321 dst.split_code(&vd, &d);
4322 int vn, n;
4323 src1.split_code(&vn, &n);
4324 int vm, m;
4325 src2.split_code(&vm, &m);
4326 int min = is_min ? 1 : 0;
4327 int size = (dt & NeonDataTypeSizeMask) / 2;
4328 int U = dt & NeonDataTypeUMask;
4329 return 0x1E4U * B23 | U | d * B22 | size * B20 | vn * B16 | vd * B12 |
4330 0x6 * B8 | B6 | m * B5 | min * B4 | vm;
4331 } 4381 }
4332 4382
4333 void Assembler::vmin(const QwNeonRegister dst, const QwNeonRegister src1, 4383 void Assembler::vmin(const QwNeonRegister dst, const QwNeonRegister src1,
4334 const QwNeonRegister src2) { 4384 const QwNeonRegister src2) {
4335 DCHECK(IsEnabled(NEON)); 4385 DCHECK(IsEnabled(NEON));
4336 // Qd = vmin(Qn, Qm) SIMD floating point MIN. 4386 // Qd = vmin(Qn, Qm) SIMD floating point MIN.
4337 // Instruction details available in ARM DDI 0406C.b, A8-928. 4387 // Instruction details available in ARM DDI 0406C.b, A8-928.
4338 emit(EncodeNeonMinMax(true, dst, src1, src2)); 4388 emit(EncodeNeonBinOp(VMINF, dst, src1, src2));
4339 } 4389 }
4340 4390
4341 void Assembler::vmin(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 4391 void Assembler::vmin(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
4342 QwNeonRegister src2) { 4392 QwNeonRegister src2) {
4343 DCHECK(IsEnabled(NEON)); 4393 DCHECK(IsEnabled(NEON));
4344 // Qd = vmin(Qn, Qm) SIMD integer MIN. 4394 // Qd = vmin(Qn, Qm) SIMD integer MIN.
4345 // Instruction details available in ARM DDI 0406C.b, A8-926. 4395 // Instruction details available in ARM DDI 0406C.b, A8-926.
4346 emit(EncodeNeonMinMax(true, dt, dst, src1, src2)); 4396 emit(EncodeNeonBinOp(VMIN, dt, dst, src1, src2));
4347 } 4397 }
4348 4398
4349 void Assembler::vmax(QwNeonRegister dst, QwNeonRegister src1, 4399 void Assembler::vmax(QwNeonRegister dst, QwNeonRegister src1,
4350 QwNeonRegister src2) { 4400 QwNeonRegister src2) {
4351 DCHECK(IsEnabled(NEON)); 4401 DCHECK(IsEnabled(NEON));
4352 // Qd = vmax(Qn, Qm) SIMD floating point MAX. 4402 // Qd = vmax(Qn, Qm) SIMD floating point MAX.
4353 // Instruction details available in ARM DDI 0406C.b, A8-928. 4403 // Instruction details available in ARM DDI 0406C.b, A8-928.
4354 emit(EncodeNeonMinMax(false, dst, src1, src2)); 4404 emit(EncodeNeonBinOp(VMAXF, dst, src1, src2));
4355 } 4405 }
4356 4406
4357 void Assembler::vmax(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 4407 void Assembler::vmax(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
4358 QwNeonRegister src2) { 4408 QwNeonRegister src2) {
4359 DCHECK(IsEnabled(NEON)); 4409 DCHECK(IsEnabled(NEON));
4360 // Qd = vmax(Qn, Qm) SIMD integer MAX. 4410 // Qd = vmax(Qn, Qm) SIMD integer MAX.
4361 // Instruction details available in ARM DDI 0406C.b, A8-926. 4411 // Instruction details available in ARM DDI 0406C.b, A8-926.
4362 emit(EncodeNeonMinMax(false, dt, dst, src1, src2)); 4412 emit(EncodeNeonBinOp(VMAX, dt, dst, src1, src2));
4363 } 4413 }
4364 4414
4365 static Instr EncodeNeonEstimateOp(bool is_rsqrt, QwNeonRegister dst, 4415 static Instr EncodeNeonEstimateOp(bool is_rsqrt, QwNeonRegister dst,
4366 QwNeonRegister src) { 4416 QwNeonRegister src) {
4367 int vd, d; 4417 int vd, d;
4368 dst.split_code(&vd, &d); 4418 dst.split_code(&vd, &d);
4369 int vm, m; 4419 int vm, m;
4370 src.split_code(&vm, &m); 4420 src.split_code(&vm, &m);
4371 int rsqrt = is_rsqrt ? 1 : 0; 4421 int rsqrt = is_rsqrt ? 1 : 0;
4372 return 0x1E7U * B23 | d * B22 | 0x3B * B16 | vd * B12 | 0x5 * B8 | 4422 return 0x1E7U * B23 | d * B22 | 0x3B * B16 | vd * B12 | 0x5 * B8 |
4373 rsqrt * B7 | B6 | m * B5 | vm; 4423 rsqrt * B7 | B6 | m * B5 | vm;
4374 } 4424 }
4375 4425
4376 void Assembler::vrecpe(const QwNeonRegister dst, const QwNeonRegister src) { 4426 void Assembler::vrecpe(QwNeonRegister dst, QwNeonRegister src) {
4377 DCHECK(IsEnabled(NEON)); 4427 DCHECK(IsEnabled(NEON));
4378 // Qd = vrecpe(Qm) SIMD reciprocal estimate. 4428 // Qd = vrecpe(Qm) SIMD reciprocal estimate.
4379 // Instruction details available in ARM DDI 0406C.b, A8-1024. 4429 // Instruction details available in ARM DDI 0406C.b, A8-1024.
4380 emit(EncodeNeonEstimateOp(false, dst, src)); 4430 emit(EncodeNeonEstimateOp(false, dst, src));
4381 } 4431 }
4382 4432
4383 void Assembler::vrsqrte(const QwNeonRegister dst, const QwNeonRegister src) { 4433 void Assembler::vrsqrte(QwNeonRegister dst, QwNeonRegister src) {
4384 DCHECK(IsEnabled(NEON)); 4434 DCHECK(IsEnabled(NEON));
4385 // Qd = vrsqrte(Qm) SIMD reciprocal square root estimate. 4435 // Qd = vrsqrte(Qm) SIMD reciprocal square root estimate.
4386 // Instruction details available in ARM DDI 0406C.b, A8-1038. 4436 // Instruction details available in ARM DDI 0406C.b, A8-1038.
4387 emit(EncodeNeonEstimateOp(true, dst, src)); 4437 emit(EncodeNeonEstimateOp(true, dst, src));
4388 } 4438 }
4389 4439
4390 static Instr EncodeNeonRefinementOp(bool is_rsqrt, QwNeonRegister dst, 4440 void Assembler::vrecps(QwNeonRegister dst, QwNeonRegister src1,
4391 QwNeonRegister src1, QwNeonRegister src2) { 4441 QwNeonRegister src2) {
4392 int vd, d;
4393 dst.split_code(&vd, &d);
4394 int vn, n;
4395 src1.split_code(&vn, &n);
4396 int vm, m;
4397 src2.split_code(&vm, &m);
4398 int rsqrt = is_rsqrt ? 1 : 0;
4399 return 0x1E4U * B23 | d * B22 | rsqrt * B21 | vn * B16 | vd * B12 | 0xF * B8 |
4400 n * B7 | B6 | m * B5 | B4 | vm;
4401 }
4402
4403 void Assembler::vrecps(const QwNeonRegister dst, const QwNeonRegister src1,
4404 const QwNeonRegister src2) {
4405 DCHECK(IsEnabled(NEON)); 4442 DCHECK(IsEnabled(NEON));
4406 // Qd = vrecps(Qn, Qm) SIMD reciprocal refinement step. 4443 // Qd = vrecps(Qn, Qm) SIMD reciprocal refinement step.
4407 // Instruction details available in ARM DDI 0406C.b, A8-1026. 4444 // Instruction details available in ARM DDI 0406C.b, A8-1026.
4408 emit(EncodeNeonRefinementOp(false, dst, src1, src2)); 4445 emit(EncodeNeonBinOp(VRECPS, dst, src1, src2));
4409 } 4446 }
4410 4447
4411 void Assembler::vrsqrts(const QwNeonRegister dst, const QwNeonRegister src1, 4448 void Assembler::vrsqrts(QwNeonRegister dst, QwNeonRegister src1,
4412 const QwNeonRegister src2) { 4449 QwNeonRegister src2) {
4413 DCHECK(IsEnabled(NEON)); 4450 DCHECK(IsEnabled(NEON));
4414 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step. 4451 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step.
4415 // Instruction details available in ARM DDI 0406C.b, A8-1040. 4452 // Instruction details available in ARM DDI 0406C.b, A8-1040.
4416 emit(EncodeNeonRefinementOp(true, dst, src1, src2)); 4453 emit(EncodeNeonBinOp(VRSQRTS, dst, src1, src2));
4417 } 4454 }
4418 4455
4419 void Assembler::vtst(NeonSize size, QwNeonRegister dst, 4456 void Assembler::vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
4420 const QwNeonRegister src1, const QwNeonRegister src2) { 4457 QwNeonRegister src2) {
4421 DCHECK(IsEnabled(NEON)); 4458 DCHECK(IsEnabled(NEON));
4422 // Qd = vtst(Qn, Qm) SIMD test integer operands. 4459 // Qd = vtst(Qn, Qm) SIMD test integer operands.
4423 // Instruction details available in ARM DDI 0406C.b, A8-1098. 4460 // Instruction details available in ARM DDI 0406C.b, A8-1098.
4424 int vd, d; 4461 emit(EncodeNeonBinOp(VTST, size, dst, src1, src2));
4425 dst.split_code(&vd, &d);
4426 int vn, n;
4427 src1.split_code(&vn, &n);
4428 int vm, m;
4429 src2.split_code(&vm, &m);
4430 int sz = static_cast<int>(size);
4431 emit(0x1E4U * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 |
4432 n * B7 | B6 | m * B5 | B4 | vm);
4433 } 4462 }
4434 4463
4435 void Assembler::vceq(const QwNeonRegister dst, const QwNeonRegister src1, 4464 void Assembler::vceq(QwNeonRegister dst, QwNeonRegister src1,
4436 const QwNeonRegister src2) { 4465 QwNeonRegister src2) {
4437 DCHECK(IsEnabled(NEON)); 4466 DCHECK(IsEnabled(NEON));
4438 // Qd = vceq(Qn, Qm) SIMD floating point compare equal. 4467 // Qd = vceq(Qn, Qm) SIMD floating point compare equal.
4439 // Instruction details available in ARM DDI 0406C.b, A8-844. 4468 // Instruction details available in ARM DDI 0406C.b, A8-844.
4440 int vd, d; 4469 emit(EncodeNeonBinOp(VCEQF, dst, src1, src2));
4441 dst.split_code(&vd, &d);
4442 int vn, n;
4443 src1.split_code(&vn, &n);
4444 int vm, m;
4445 src2.split_code(&vm, &m);
4446 emit(0x1E4U * B23 | d * B22 | vn * B16 | vd * B12 | 0xe * B8 | n * B7 | B6 |
4447 m * B5 | vm);
4448 } 4470 }
4449 4471
4450 void Assembler::vceq(NeonSize size, QwNeonRegister dst, 4472 void Assembler::vceq(NeonSize size, QwNeonRegister dst, QwNeonRegister src1,
4451 const QwNeonRegister src1, const QwNeonRegister src2) { 4473 QwNeonRegister src2) {
4452 DCHECK(IsEnabled(NEON)); 4474 DCHECK(IsEnabled(NEON));
4453 // Qd = vceq(Qn, Qm) SIMD integer compare equal. 4475 // Qd = vceq(Qn, Qm) SIMD integer compare equal.
4454 // Instruction details available in ARM DDI 0406C.b, A8-844. 4476 // Instruction details available in ARM DDI 0406C.b, A8-844.
4455 int vd, d; 4477 emit(EncodeNeonBinOp(VCEQ, size, dst, src1, src2));
4456 dst.split_code(&vd, &d);
4457 int vn, n;
4458 src1.split_code(&vn, &n);
4459 int vm, m;
4460 src2.split_code(&vm, &m);
4461 int sz = static_cast<int>(size);
4462 emit(0x1E6U * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 |
4463 n * B7 | B6 | m * B5 | B4 | vm);
4464 } 4478 }
4465 4479
4466 static Instr EncodeNeonCompareOp(const QwNeonRegister dst, 4480 void Assembler::vcge(QwNeonRegister dst, QwNeonRegister src1,
4467 const QwNeonRegister src1, 4481 QwNeonRegister src2) {
4468 const QwNeonRegister src2, Condition cond) {
4469 DCHECK(cond == ge || cond == gt);
4470 int vd, d;
4471 dst.split_code(&vd, &d);
4472 int vn, n;
4473 src1.split_code(&vn, &n);
4474 int vm, m;
4475 src2.split_code(&vm, &m);
4476 int is_gt = (cond == gt) ? 1 : 0;
4477 return 0x1E6U * B23 | d * B22 | is_gt * B21 | vn * B16 | vd * B12 | 0xe * B8 |
4478 n * B7 | B6 | m * B5 | vm;
4479 }
4480
4481 static Instr EncodeNeonCompareOp(NeonDataType dt, const QwNeonRegister dst,
4482 const QwNeonRegister src1,
4483 const QwNeonRegister src2, Condition cond) {
4484 DCHECK(cond == ge || cond == gt);
4485 int vd, d;
4486 dst.split_code(&vd, &d);
4487 int vn, n;
4488 src1.split_code(&vn, &n);
4489 int vm, m;
4490 src2.split_code(&vm, &m);
4491 int size = (dt & NeonDataTypeSizeMask) / 2;
4492 int U = dt & NeonDataTypeUMask;
4493 int is_ge = (cond == ge) ? 1 : 0;
4494 return 0x1E4U * B23 | U | d * B22 | size * B20 | vn * B16 | vd * B12 |
4495 0x3 * B8 | n * B7 | B6 | m * B5 | is_ge * B4 | vm;
4496 }
4497
4498 void Assembler::vcge(const QwNeonRegister dst, const QwNeonRegister src1,
4499 const QwNeonRegister src2) {
4500 DCHECK(IsEnabled(NEON)); 4482 DCHECK(IsEnabled(NEON));
4501 // Qd = vcge(Qn, Qm) SIMD floating point compare greater or equal. 4483 // Qd = vcge(Qn, Qm) SIMD floating point compare greater or equal.
4502 // Instruction details available in ARM DDI 0406C.b, A8-848. 4484 // Instruction details available in ARM DDI 0406C.b, A8-848.
4503 emit(EncodeNeonCompareOp(dst, src1, src2, ge)); 4485 emit(EncodeNeonBinOp(VCGEF, dst, src1, src2));
4504 } 4486 }
4505 4487
4506 void Assembler::vcge(NeonDataType dt, QwNeonRegister dst, 4488 void Assembler::vcge(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
4507 const QwNeonRegister src1, const QwNeonRegister src2) { 4489 QwNeonRegister src2) {
4508 DCHECK(IsEnabled(NEON)); 4490 DCHECK(IsEnabled(NEON));
4509 // Qd = vcge(Qn, Qm) SIMD integer compare greater or equal. 4491 // Qd = vcge(Qn, Qm) SIMD integer compare greater or equal.
4510 // Instruction details available in ARM DDI 0406C.b, A8-848. 4492 // Instruction details available in ARM DDI 0406C.b, A8-848.
4511 emit(EncodeNeonCompareOp(dt, dst, src1, src2, ge)); 4493 emit(EncodeNeonBinOp(VCGE, dt, dst, src1, src2));
4512 } 4494 }
4513 4495
4514 void Assembler::vcgt(const QwNeonRegister dst, const QwNeonRegister src1, 4496 void Assembler::vcgt(QwNeonRegister dst, QwNeonRegister src1,
4515 const QwNeonRegister src2) { 4497 QwNeonRegister src2) {
4516 DCHECK(IsEnabled(NEON)); 4498 DCHECK(IsEnabled(NEON));
4517 // Qd = vcgt(Qn, Qm) SIMD floating point compare greater than. 4499 // Qd = vcgt(Qn, Qm) SIMD floating point compare greater than.
4518 // Instruction details available in ARM DDI 0406C.b, A8-852. 4500 // Instruction details available in ARM DDI 0406C.b, A8-852.
4519 emit(EncodeNeonCompareOp(dst, src1, src2, gt)); 4501 emit(EncodeNeonBinOp(VCGTF, dst, src1, src2));
4520 } 4502 }
4521 4503
4522 void Assembler::vcgt(NeonDataType dt, QwNeonRegister dst, 4504 void Assembler::vcgt(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
4523 const QwNeonRegister src1, const QwNeonRegister src2) { 4505 QwNeonRegister src2) {
4524 DCHECK(IsEnabled(NEON)); 4506 DCHECK(IsEnabled(NEON));
4525 // Qd = vcgt(Qn, Qm) SIMD integer compare greater than. 4507 // Qd = vcgt(Qn, Qm) SIMD integer compare greater than.
4526 // Instruction details available in ARM DDI 0406C.b, A8-852. 4508 // Instruction details available in ARM DDI 0406C.b, A8-852.
4527 emit(EncodeNeonCompareOp(dt, dst, src1, src2, gt)); 4509 emit(EncodeNeonBinOp(VCGT, dt, dst, src1, src2));
4528 } 4510 }
4529 4511
4530 void Assembler::vext(QwNeonRegister dst, const QwNeonRegister src1, 4512 void Assembler::vext(QwNeonRegister dst, const QwNeonRegister src1,
4531 const QwNeonRegister src2, int bytes) { 4513 const QwNeonRegister src2, int bytes) {
4532 DCHECK(IsEnabled(NEON)); 4514 DCHECK(IsEnabled(NEON));
4533 // Qd = vext(Qn, Qm) SIMD byte extract. 4515 // Qd = vext(Qn, Qm) SIMD byte extract.
4534 // Instruction details available in ARM DDI 0406C.b, A8-890. 4516 // Instruction details available in ARM DDI 0406C.b, A8-890.
4535 int vd, d; 4517 int vd, d;
4536 dst.split_code(&vd, &d); 4518 dst.split_code(&vd, &d);
4537 int vn, n; 4519 int vn, n;
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
5167 DCHECK(is_uint12(offset)); 5149 DCHECK(is_uint12(offset));
5168 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); 5150 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset));
5169 } 5151 }
5170 } 5152 }
5171 5153
5172 5154
5173 } // namespace internal 5155 } // namespace internal
5174 } // namespace v8 5156 } // namespace v8
5175 5157
5176 #endif // V8_TARGET_ARCH_ARM 5158 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698