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

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

Issue 2868603002: [ARM] Improve VFP register moves. (Closed)
Patch Set: Rebase. Created 3 years, 7 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 3892 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 UNREACHABLE(); 3903 UNREACHABLE();
3904 break; 3904 break;
3905 } 3905 }
3906 int vd, d; 3906 int vd, d;
3907 dst.split_code(&vd, &d); 3907 dst.split_code(&vd, &d);
3908 3908
3909 emit(al | 0x1D * B23 | B * B22 | B21 | vd * B16 | src.code() * B12 | 3909 emit(al | 0x1D * B23 | B * B22 | B21 | vd * B16 | src.code() * B12 |
3910 0xB * B8 | d * B7 | E * B5 | B4); 3910 0xB * B8 | d * B7 | E * B5 | B4);
3911 } 3911 }
3912 3912
3913 void Assembler::vdup(QwNeonRegister dst, SwVfpRegister src) { 3913 enum NeonRegType { NEON_D, NEON_Q };
3914
3915 void NeonSplitCode(NeonRegType type, int code, int* vm, int* m, int* encoding) {
3916 if (type == NEON_D) {
3917 DwVfpRegister::split_code(code, vm, m);
3918 } else {
3919 DCHECK_EQ(type, NEON_Q);
3920 QwNeonRegister::split_code(code, vm, m);
3921 *encoding |= B6;
3922 }
3923 }
3924
3925 static Instr EncodeNeonDupOp(NeonSize size, NeonRegType reg_type, int dst_code,
3926 DwVfpRegister src, int index) {
3927 DCHECK_NE(Neon64, size);
3928 int sz = static_cast<int>(size);
3929 DCHECK_LE(0, index);
3930 DCHECK_GT(kSimd128Size / (1 << sz), index);
3931 int imm4 = (1 << sz) | ((index << (sz + 1)) & 0xF);
3932 int qbit = 0;
3933 int vd, d;
3934 NeonSplitCode(reg_type, dst_code, &vd, &d, &qbit);
3935 int vm, m;
3936 src.split_code(&vm, &m);
3937
3938 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | imm4 * B16 | vd * B12 |
3939 0x18 * B7 | qbit | m * B5 | vm;
3940 }
3941
3942 void Assembler::vdup(NeonSize size, DwVfpRegister dst, DwVfpRegister src,
3943 int index) {
3914 DCHECK(IsEnabled(NEON)); 3944 DCHECK(IsEnabled(NEON));
3915 // Instruction details available in ARM DDI 0406C.b, A8-884. 3945 // Instruction details available in ARM DDI 0406C.b, A8-884.
3916 int index = src.code() & 1; 3946 emit(EncodeNeonDupOp(size, NEON_D, dst.code(), src, index));
3917 int d_reg = src.code() / 2; 3947 }
3918 int imm4 = 4 | index << 3; // esize = 32, index in bit 3.
3919 int vd, d;
3920 dst.split_code(&vd, &d);
3921 int vm, m;
3922 DwVfpRegister::from_code(d_reg).split_code(&vm, &m);
3923 3948
3924 emit(0x1E7U * B23 | d * B22 | 0x3 * B20 | imm4 * B16 | vd * B12 | 0x18 * B7 | 3949 void Assembler::vdup(NeonSize size, QwNeonRegister dst, DwVfpRegister src,
3925 B6 | m * B5 | vm); 3950 int index) {
3951 // Instruction details available in ARM DDI 0406C.b, A8-884.
3952 DCHECK(IsEnabled(NEON));
3953 emit(EncodeNeonDupOp(size, NEON_Q, dst.code(), src, index));
3926 } 3954 }
3927 3955
3928 // Encode NEON vcvt.src_type.dst_type instruction. 3956 // Encode NEON vcvt.src_type.dst_type instruction.
3929 static Instr EncodeNeonVCVT(VFPType dst_type, QwNeonRegister dst, 3957 static Instr EncodeNeonVCVT(VFPType dst_type, QwNeonRegister dst,
3930 VFPType src_type, QwNeonRegister src) { 3958 VFPType src_type, QwNeonRegister src) {
3931 DCHECK(src_type != dst_type); 3959 DCHECK(src_type != dst_type);
3932 DCHECK(src_type == F32 || dst_type == F32); 3960 DCHECK(src_type == F32 || dst_type == F32);
3933 // Instruction details available in ARM DDI 0406C.b, A8.8.868. 3961 // Instruction details available in ARM DDI 0406C.b, A8.8.868.
3934 int vd, d; 3962 int vd, d;
3935 dst.split_code(&vd, &d); 3963 dst.split_code(&vd, &d);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3970 emit(EncodeNeonVCVT(S32, dst, F32, src)); 3998 emit(EncodeNeonVCVT(S32, dst, F32, src));
3971 } 3999 }
3972 4000
3973 void Assembler::vcvt_u32_f32(QwNeonRegister dst, QwNeonRegister src) { 4001 void Assembler::vcvt_u32_f32(QwNeonRegister dst, QwNeonRegister src) {
3974 DCHECK(IsEnabled(NEON)); 4002 DCHECK(IsEnabled(NEON));
3975 DCHECK(VfpRegisterIsAvailable(dst)); 4003 DCHECK(VfpRegisterIsAvailable(dst));
3976 DCHECK(VfpRegisterIsAvailable(src)); 4004 DCHECK(VfpRegisterIsAvailable(src));
3977 emit(EncodeNeonVCVT(U32, dst, F32, src)); 4005 emit(EncodeNeonVCVT(U32, dst, F32, src));
3978 } 4006 }
3979 4007
3980 enum NeonRegType { NEON_D, NEON_Q };
3981
3982 void NeonSplitCode(NeonRegType type, int code, int* vm, int* m, int* encoding) {
3983 if (type == NEON_D) {
3984 DwVfpRegister::split_code(code, vm, m);
3985 } else {
3986 DCHECK_EQ(type, NEON_Q);
3987 QwNeonRegister::split_code(code, vm, m);
3988 *encoding |= B6;
3989 }
3990 }
3991
3992 enum UnaryOp { VMVN, VSWP, VABS, VABSF, VNEG, VNEGF }; 4008 enum UnaryOp { VMVN, VSWP, VABS, VABSF, VNEG, VNEGF };
3993 4009
3994 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonRegType reg_type, NeonSize size, 4010 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonRegType reg_type, NeonSize size,
3995 int dst_code, int src_code) { 4011 int dst_code, int src_code) {
3996 int op_encoding = 0; 4012 int op_encoding = 0;
3997 switch (op) { 4013 switch (op) {
3998 case VMVN: 4014 case VMVN:
3999 DCHECK_EQ(Neon8, size); // size == 0 for vmvn 4015 DCHECK_EQ(Neon8, size); // size == 0 for vmvn
4000 op_encoding = B10 | 0x3 * B7; 4016 op_encoding = B10 | 0x3 * B7;
4001 break; 4017 break;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
4396 } 4412 }
4397 4413
4398 void Assembler::vmax(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1, 4414 void Assembler::vmax(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src1,
4399 QwNeonRegister src2) { 4415 QwNeonRegister src2) {
4400 DCHECK(IsEnabled(NEON)); 4416 DCHECK(IsEnabled(NEON));
4401 // Qd = vmax(Qn, Qm) SIMD integer MAX. 4417 // Qd = vmax(Qn, Qm) SIMD integer MAX.
4402 // Instruction details available in ARM DDI 0406C.b, A8-926. 4418 // Instruction details available in ARM DDI 0406C.b, A8-926.
4403 emit(EncodeNeonBinOp(VMAX, dt, dst, src1, src2)); 4419 emit(EncodeNeonBinOp(VMAX, dt, dst, src1, src2));
4404 } 4420 }
4405 4421
4406 enum NeonShiftOp { VSHL, VSHR }; 4422 enum NeonShiftOp { VSHL, VSHR, VSLI, VSRI };
4407 4423
4408 static Instr EncodeNeonShiftOp(NeonShiftOp op, NeonDataType dt, 4424 static Instr EncodeNeonShiftOp(NeonShiftOp op, NeonSize size, bool is_unsigned,
4409 QwNeonRegister dst, QwNeonRegister src, 4425 NeonRegType reg_type, int dst_code, int src_code,
4410 int shift) { 4426 int shift) {
4427 int imm6 = 0;
4428 int size_in_bits = kBitsPerByte << static_cast<int>(size);
4429 int op_encoding = 0;
4430 switch (op) {
4431 case VSHL: {
4432 DCHECK(shift >= 0 && size_in_bits > shift);
4433 imm6 = size_in_bits + shift;
4434 op_encoding = 0x5 * B8;
4435 break;
4436 }
4437 case VSHR: {
4438 DCHECK(shift > 0 && size_in_bits >= shift);
4439 imm6 = 2 * size_in_bits - shift;
4440 if (is_unsigned) op_encoding |= B24;
4441 break;
4442 }
4443 case VSLI: {
4444 DCHECK(shift >= 0 && size_in_bits > shift);
4445 imm6 = size_in_bits + shift;
4446 int L = imm6 >> 6;
4447 imm6 &= 0x3F;
4448 op_encoding = B24 | 0x5 * B8 | L * B7;
4449 break;
4450 }
4451 case VSRI: {
4452 DCHECK(shift > 0 && size_in_bits >= shift);
4453 imm6 = 2 * size_in_bits - shift;
4454 int L = imm6 >> 6;
4455 imm6 &= 0x3F;
4456 op_encoding = B24 | 0x4 * B8 | L * B7;
4457 break;
4458 }
4459 default:
4460 UNREACHABLE();
4461 break;
4462 }
4463
4411 int vd, d; 4464 int vd, d;
4412 dst.split_code(&vd, &d); 4465 NeonSplitCode(reg_type, dst_code, &vd, &d, &op_encoding);
4413 int vm, m; 4466 int vm, m;
4414 src.split_code(&vm, &m); 4467 NeonSplitCode(reg_type, src_code, &vm, &m, &op_encoding);
4415 int size_in_bits = kBitsPerByte << NeonSz(dt); 4468
4416 int op_encoding = 0; 4469 return 0x1E5U * B23 | d * B22 | imm6 * B16 | vd * B12 | m * B5 | B4 | vm |
4417 int imm6 = 0; 4470 op_encoding;
4418 if (op == VSHL) {
4419 DCHECK(shift >= 0 && size_in_bits > shift);
4420 imm6 = size_in_bits + shift;
4421 op_encoding = 0x5 * B8;
4422 } else {
4423 DCHECK_EQ(VSHR, op);
4424 DCHECK(shift > 0 && size_in_bits >= shift);
4425 imm6 = 2 * size_in_bits - shift;
4426 op_encoding = NeonU(dt) * B24;
4427 }
4428 return 0x1E5U * B23 | d * B22 | imm6 * B16 | vd * B12 | B6 | m * B5 | B4 |
4429 vm | op_encoding;
4430 } 4471 }
4431 4472
4432 void Assembler::vshl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, 4473 void Assembler::vshl(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src,
4433 int shift) { 4474 int shift) {
4434 DCHECK(IsEnabled(NEON)); 4475 DCHECK(IsEnabled(NEON));
4435 // Qd = vshl(Qm, bits) SIMD shift left immediate. 4476 // Qd = vshl(Qm, bits) SIMD shift left immediate.
4436 // Instruction details available in ARM DDI 0406C.b, A8-1046. 4477 // Instruction details available in ARM DDI 0406C.b, A8-1046.
4437 emit(EncodeNeonShiftOp(VSHL, dt, dst, src, shift)); 4478 emit(EncodeNeonShiftOp(VSHL, NeonDataTypeToSize(dt), false, NEON_Q,
4479 dst.code(), src.code(), shift));
4438 } 4480 }
4439 4481
4440 void Assembler::vshr(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src, 4482 void Assembler::vshr(NeonDataType dt, QwNeonRegister dst, QwNeonRegister src,
4441 int shift) { 4483 int shift) {
4442 DCHECK(IsEnabled(NEON)); 4484 DCHECK(IsEnabled(NEON));
4443 // Qd = vshl(Qm, bits) SIMD shift right immediate. 4485 // Qd = vshl(Qm, bits) SIMD shift right immediate.
4444 // Instruction details available in ARM DDI 0406C.b, A8-1052. 4486 // Instruction details available in ARM DDI 0406C.b, A8-1052.
4445 emit(EncodeNeonShiftOp(VSHR, dt, dst, src, shift)); 4487 emit(EncodeNeonShiftOp(VSHR, NeonDataTypeToSize(dt), NeonU(dt), NEON_Q,
4488 dst.code(), src.code(), shift));
4489 }
4490
4491 void Assembler::vsli(NeonSize size, DwVfpRegister dst, DwVfpRegister src,
4492 int shift) {
4493 DCHECK(IsEnabled(NEON));
4494 // Dd = vsli(Dm, bits) SIMD shift left and insert.
4495 // Instruction details available in ARM DDI 0406C.b, A8-1056.
4496 emit(EncodeNeonShiftOp(VSLI, size, false, NEON_D, dst.code(), src.code(),
4497 shift));
4498 }
4499
4500 void Assembler::vsri(NeonSize size, DwVfpRegister dst, DwVfpRegister src,
4501 int shift) {
4502 DCHECK(IsEnabled(NEON));
4503 // Dd = vsri(Dm, bits) SIMD shift right and insert.
4504 // Instruction details available in ARM DDI 0406C.b, A8-1062.
4505 emit(EncodeNeonShiftOp(VSRI, size, false, NEON_D, dst.code(), src.code(),
4506 shift));
4446 } 4507 }
4447 4508
4448 static Instr EncodeNeonEstimateOp(bool is_rsqrt, QwNeonRegister dst, 4509 static Instr EncodeNeonEstimateOp(bool is_rsqrt, QwNeonRegister dst,
4449 QwNeonRegister src) { 4510 QwNeonRegister src) {
4450 int vd, d; 4511 int vd, d;
4451 dst.split_code(&vd, &d); 4512 dst.split_code(&vd, &d);
4452 int vm, m; 4513 int vm, m;
4453 src.split_code(&vm, &m); 4514 src.split_code(&vm, &m);
4454 int rsqrt = is_rsqrt ? 1 : 0; 4515 int rsqrt = is_rsqrt ? 1 : 0;
4455 return 0x1E7U * B23 | d * B22 | 0x3B * B16 | vd * B12 | 0x5 * B8 | 4516 return 0x1E7U * B23 | d * B22 | 0x3B * B16 | vd * B12 | 0x5 * B8 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
4532 4593
4533 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 | 4594 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 |
4534 m * B5 | vm); 4595 m * B5 | vm);
4535 } 4596 }
4536 4597
4537 void Assembler::vpadd(NeonSize size, DwVfpRegister dst, DwVfpRegister src1, 4598 void Assembler::vpadd(NeonSize size, DwVfpRegister dst, DwVfpRegister src1,
4538 DwVfpRegister src2) { 4599 DwVfpRegister src2) {
4539 DCHECK(IsEnabled(NEON)); 4600 DCHECK(IsEnabled(NEON));
4540 // Dd = vpadd(Dn, Dm) SIMD integer pairwise ADD. 4601 // Dd = vpadd(Dn, Dm) SIMD integer pairwise ADD.
4541 // Instruction details available in ARM DDI 0406C.b, A8-980. 4602 // Instruction details available in ARM DDI 0406C.b, A8-980.
4542 emit(EncodeNeonPairwiseOp(VPADD, NeonSizeToDatatype(size), dst, src1, src2)); 4603 emit(EncodeNeonPairwiseOp(VPADD, NeonSizeToDataType(size), dst, src1, src2));
4543 } 4604 }
4544 4605
4545 void Assembler::vpmin(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, 4606 void Assembler::vpmin(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1,
4546 DwVfpRegister src2) { 4607 DwVfpRegister src2) {
4547 DCHECK(IsEnabled(NEON)); 4608 DCHECK(IsEnabled(NEON));
4548 // Dd = vpmin(Dn, Dm) SIMD integer pairwise MIN. 4609 // Dd = vpmin(Dn, Dm) SIMD integer pairwise MIN.
4549 // Instruction details available in ARM DDI 0406C.b, A8-986. 4610 // Instruction details available in ARM DDI 0406C.b, A8-986.
4550 emit(EncodeNeonPairwiseOp(VPMIN, dt, dst, src1, src2)); 4611 emit(EncodeNeonPairwiseOp(VPMIN, dt, dst, src1, src2));
4551 } 4612 }
4552 4613
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
5269 } 5330 }
5270 5331
5271 void PatchingAssembler::FlushICache(Isolate* isolate) { 5332 void PatchingAssembler::FlushICache(Isolate* isolate) {
5272 Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap); 5333 Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap);
5273 } 5334 }
5274 5335
5275 } // namespace internal 5336 } // namespace internal
5276 } // namespace v8 5337 } // namespace v8
5277 5338
5278 #endif // V8_TARGET_ARCH_ARM 5339 #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