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

Side by Side Diff: src/arm64/instructions-arm64.cc

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #define ARM64_DEFINE_FP_STATICS 7 #define ARM64_DEFINE_FP_STATICS
8 8
9 #include "src/arm64/assembler-arm64-inl.h" 9 #include "src/arm64/assembler-arm64-inl.h"
10 #include "src/arm64/instructions-arm64.h" 10 #include "src/arm64/instructions-arm64.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 bool Instruction::IsLoad() const { 16 bool Instruction::IsLoad() const {
17 if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) { 17 if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) {
18 return false; 18 return false;
19 } 19 }
20 20
21 if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { 21 if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) {
22 return Mask(LoadStorePairLBit) != 0; 22 return Mask(LoadStorePairLBit) != 0;
23 } else { 23 } else {
24 LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask)); 24 LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask));
25 switch (op) { 25 switch (op) {
26 case LDRB_w: 26 case LDRB_w:
27 case LDRH_w: 27 case LDRH_w:
28 case LDR_w: 28 case LDR_w:
29 case LDR_x: 29 case LDR_x:
30 case LDRSB_w: 30 case LDRSB_w:
31 case LDRSB_x: 31 case LDRSB_x:
32 case LDRSH_w: 32 case LDRSH_w:
33 case LDRSH_x: 33 case LDRSH_x:
34 case LDRSW_x: 34 case LDRSW_x:
35 case LDR_b:
36 case LDR_h:
35 case LDR_s: 37 case LDR_s:
36 case LDR_d: return true; 38 case LDR_d:
39 case LDR_q:
40 return true;
37 default: return false; 41 default: return false;
38 } 42 }
39 } 43 }
40 } 44 }
41 45
42 46
43 bool Instruction::IsStore() const { 47 bool Instruction::IsStore() const {
44 if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) { 48 if (Mask(LoadStoreAnyFMask) != LoadStoreAnyFixed) {
45 return false; 49 return false;
46 } 50 }
47 51
48 if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) { 52 if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) {
49 return Mask(LoadStorePairLBit) == 0; 53 return Mask(LoadStorePairLBit) == 0;
50 } else { 54 } else {
51 LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask)); 55 LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask));
52 switch (op) { 56 switch (op) {
53 case STRB_w: 57 case STRB_w:
54 case STRH_w: 58 case STRH_w:
55 case STR_w: 59 case STR_w:
56 case STR_x: 60 case STR_x:
61 case STR_b:
62 case STR_h:
57 case STR_s: 63 case STR_s:
58 case STR_d: return true; 64 case STR_d:
65 case STR_q:
66 return true;
59 default: return false; 67 default: return false;
60 } 68 }
61 } 69 }
62 } 70 }
63 71
64 72
65 static uint64_t RotateRight(uint64_t value, 73 static uint64_t RotateRight(uint64_t value,
66 unsigned int rotate, 74 unsigned int rotate,
67 unsigned int width) { 75 unsigned int width) {
68 DCHECK(width <= 64); 76 DCHECK(width <= 64);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 return RepeatBitsAcrossReg(reg_size, 140 return RepeatBitsAcrossReg(reg_size,
133 RotateRight(bits, imm_r & mask, width), 141 RotateRight(bits, imm_r & mask, width),
134 width); 142 width);
135 } 143 }
136 } 144 }
137 } 145 }
138 UNREACHABLE(); 146 UNREACHABLE();
139 return 0; 147 return 0;
140 } 148 }
141 149
142 150 uint32_t Instruction::ImmNEONabcdefgh() const {
143 float Instruction::ImmFP32() { 151 return ImmNEONabc() << 5 | ImmNEONdefgh();
144 // ImmFP: abcdefgh (8 bits)
145 // Single: aBbb.bbbc.defg.h000.0000.0000.0000.0000 (32 bits)
146 // where B is b ^ 1
147 uint32_t bits = ImmFP();
148 uint32_t bit7 = (bits >> 7) & 0x1;
149 uint32_t bit6 = (bits >> 6) & 0x1;
150 uint32_t bit5_to_0 = bits & 0x3f;
151 uint32_t result = (bit7 << 31) | ((32 - bit6) << 25) | (bit5_to_0 << 19);
152
153 return rawbits_to_float(result);
154 } 152 }
155 153
154 float Instruction::ImmFP32() { return Imm8ToFP32(ImmFP()); }
156 155
157 double Instruction::ImmFP64() { 156 double Instruction::ImmFP64() { return Imm8ToFP64(ImmFP()); }
158 // ImmFP: abcdefgh (8 bits)
159 // Double: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
160 // 0000.0000.0000.0000.0000.0000.0000.0000 (64 bits)
161 // where B is b ^ 1
162 uint32_t bits = ImmFP();
163 uint64_t bit7 = (bits >> 7) & 0x1;
164 uint64_t bit6 = (bits >> 6) & 0x1;
165 uint64_t bit5_to_0 = bits & 0x3f;
166 uint64_t result = (bit7 << 63) | ((256 - bit6) << 54) | (bit5_to_0 << 48);
167 157
168 return rawbits_to_double(result); 158 float Instruction::ImmNEONFP32() const { return Imm8ToFP32(ImmNEONabcdefgh()); }
159
160 double Instruction::ImmNEONFP64() const {
161 return Imm8ToFP64(ImmNEONabcdefgh());
169 } 162 }
170 163
164 unsigned CalcLSDataSize(LoadStoreOp op) {
165 DCHECK_EQ(static_cast<unsigned>(LSSize_offset + LSSize_width),
166 kInstructionSize * 8);
167 unsigned size = static_cast<Instr>(op) >> LSSize_offset;
168 if ((op & LSVector_mask) != 0) {
169 // Vector register memory operations encode the access size in the "size"
170 // and "opc" fields.
171 if ((size == 0) && ((op & LSOpc_mask) >> LSOpc_offset) >= 2) {
172 size = kQRegSizeLog2;
173 }
174 }
175 return size;
176 }
171 177
172 LSDataSize CalcLSPairDataSize(LoadStorePairOp op) { 178 unsigned CalcLSPairDataSize(LoadStorePairOp op) {
179 static_assert(kXRegSize == kDRegSize, "X and D registers must be same size.");
180 static_assert(kWRegSize == kSRegSize, "W and S registers must be same size.");
173 switch (op) { 181 switch (op) {
182 case STP_q:
183 case LDP_q:
184 return kQRegSizeLog2;
174 case STP_x: 185 case STP_x:
175 case LDP_x: 186 case LDP_x:
176 case STP_d: 187 case STP_d:
177 case LDP_d: return LSDoubleWord; 188 case LDP_d:
178 default: return LSWord; 189 return kXRegSizeLog2;
190 default:
191 return kWRegSizeLog2;
179 } 192 }
180 } 193 }
181 194
182 195
183 int64_t Instruction::ImmPCOffset() { 196 int64_t Instruction::ImmPCOffset() {
184 int64_t offset; 197 int64_t offset;
185 if (IsPCRelAddressing()) { 198 if (IsPCRelAddressing()) {
186 // PC-relative addressing. Only ADR is supported. 199 // PC-relative addressing. Only ADR is supported.
187 offset = ImmPCRel(); 200 offset = ImmPCRel();
188 } else if (BranchType() != UnknownBranchType) { 201 } else if (BranchType() != UnknownBranchType) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // xzr and Register are not defined in that header. Consider adding 341 // xzr and Register are not defined in that header. Consider adding
329 // instructions-arm64-inl.h to work around this. 342 // instructions-arm64-inl.h to work around this.
330 uint64_t InstructionSequence::InlineData() const { 343 uint64_t InstructionSequence::InlineData() const {
331 DCHECK(IsInlineData()); 344 DCHECK(IsInlineData());
332 uint64_t payload = ImmMoveWide(); 345 uint64_t payload = ImmMoveWide();
333 // TODO(all): If we extend ::InlineData() to support bigger data, we need 346 // TODO(all): If we extend ::InlineData() to support bigger data, we need
334 // to update this method too. 347 // to update this method too.
335 return payload; 348 return payload;
336 } 349 }
337 350
338 351 VectorFormat VectorFormatHalfWidth(VectorFormat vform) {
352 DCHECK(vform == kFormat8H || vform == kFormat4S || vform == kFormat2D ||
353 vform == kFormatH || vform == kFormatS || vform == kFormatD);
354 switch (vform) {
355 case kFormat8H:
356 return kFormat8B;
357 case kFormat4S:
358 return kFormat4H;
359 case kFormat2D:
360 return kFormat2S;
361 case kFormatH:
362 return kFormatB;
363 case kFormatS:
364 return kFormatH;
365 case kFormatD:
366 return kFormatS;
367 default:
368 UNREACHABLE();
369 return kFormatUndefined;
370 }
371 }
372
373 VectorFormat VectorFormatDoubleWidth(VectorFormat vform) {
374 DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S ||
375 vform == kFormatB || vform == kFormatH || vform == kFormatS);
376 switch (vform) {
377 case kFormat8B:
378 return kFormat8H;
379 case kFormat4H:
380 return kFormat4S;
381 case kFormat2S:
382 return kFormat2D;
383 case kFormatB:
384 return kFormatH;
385 case kFormatH:
386 return kFormatS;
387 case kFormatS:
388 return kFormatD;
389 default:
390 UNREACHABLE();
391 return kFormatUndefined;
392 }
393 }
394
395 VectorFormat VectorFormatFillQ(VectorFormat vform) {
396 switch (vform) {
397 case kFormatB:
398 case kFormat8B:
399 case kFormat16B:
400 return kFormat16B;
401 case kFormatH:
402 case kFormat4H:
403 case kFormat8H:
404 return kFormat8H;
405 case kFormatS:
406 case kFormat2S:
407 case kFormat4S:
408 return kFormat4S;
409 case kFormatD:
410 case kFormat1D:
411 case kFormat2D:
412 return kFormat2D;
413 default:
414 UNREACHABLE();
415 return kFormatUndefined;
416 }
417 }
418
419 VectorFormat VectorFormatHalfWidthDoubleLanes(VectorFormat vform) {
420 switch (vform) {
421 case kFormat4H:
422 return kFormat8B;
423 case kFormat8H:
424 return kFormat16B;
425 case kFormat2S:
426 return kFormat4H;
427 case kFormat4S:
428 return kFormat8H;
429 case kFormat1D:
430 return kFormat2S;
431 case kFormat2D:
432 return kFormat4S;
433 default:
434 UNREACHABLE();
435 return kFormatUndefined;
436 }
437 }
438
439 VectorFormat VectorFormatDoubleLanes(VectorFormat vform) {
440 DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S);
441 switch (vform) {
442 case kFormat8B:
443 return kFormat16B;
444 case kFormat4H:
445 return kFormat8H;
446 case kFormat2S:
447 return kFormat4S;
448 default:
449 UNREACHABLE();
450 return kFormatUndefined;
451 }
452 }
453
454 VectorFormat VectorFormatHalfLanes(VectorFormat vform) {
455 DCHECK(vform == kFormat16B || vform == kFormat8H || vform == kFormat4S);
456 switch (vform) {
457 case kFormat16B:
458 return kFormat8B;
459 case kFormat8H:
460 return kFormat4H;
461 case kFormat4S:
462 return kFormat2S;
463 default:
464 UNREACHABLE();
465 return kFormatUndefined;
466 }
467 }
468
469 VectorFormat ScalarFormatFromLaneSize(int laneSize) {
470 switch (laneSize) {
471 case 8:
472 return kFormatB;
473 case 16:
474 return kFormatH;
475 case 32:
476 return kFormatS;
477 case 64:
478 return kFormatD;
479 default:
480 UNREACHABLE();
481 return kFormatUndefined;
482 }
483 }
484
485 VectorFormat ScalarFormatFromFormat(VectorFormat vform) {
486 return ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
487 }
488
489 unsigned RegisterSizeInBytesFromFormat(VectorFormat vform) {
490 return RegisterSizeInBitsFromFormat(vform) / 8;
491 }
492
493 unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) {
494 DCHECK_NE(vform, kFormatUndefined);
495 switch (vform) {
496 case kFormatB:
497 return kBRegSizeInBits;
498 case kFormatH:
499 return kHRegSizeInBits;
500 case kFormatS:
501 return kSRegSizeInBits;
502 case kFormatD:
503 return kDRegSizeInBits;
504 case kFormat8B:
505 case kFormat4H:
506 case kFormat2S:
507 case kFormat1D:
508 return kDRegSizeInBits;
509 default:
510 return kQRegSizeInBits;
511 }
512 }
513
514 unsigned LaneSizeInBitsFromFormat(VectorFormat vform) {
515 DCHECK_NE(vform, kFormatUndefined);
516 switch (vform) {
517 case kFormatB:
518 case kFormat8B:
519 case kFormat16B:
520 return 8;
521 case kFormatH:
522 case kFormat4H:
523 case kFormat8H:
524 return 16;
525 case kFormatS:
526 case kFormat2S:
527 case kFormat4S:
528 return 32;
529 case kFormatD:
530 case kFormat1D:
531 case kFormat2D:
532 return 64;
533 default:
534 UNREACHABLE();
535 return 0;
536 }
537 }
538
539 int LaneSizeInBytesFromFormat(VectorFormat vform) {
540 return LaneSizeInBitsFromFormat(vform) / 8;
541 }
542
543 int LaneSizeInBytesLog2FromFormat(VectorFormat vform) {
544 DCHECK_NE(vform, kFormatUndefined);
545 switch (vform) {
546 case kFormatB:
547 case kFormat8B:
548 case kFormat16B:
549 return 0;
550 case kFormatH:
551 case kFormat4H:
552 case kFormat8H:
553 return 1;
554 case kFormatS:
555 case kFormat2S:
556 case kFormat4S:
557 return 2;
558 case kFormatD:
559 case kFormat1D:
560 case kFormat2D:
561 return 3;
562 default:
563 UNREACHABLE();
564 return 0;
565 }
566 }
567
568 int LaneCountFromFormat(VectorFormat vform) {
569 DCHECK_NE(vform, kFormatUndefined);
570 switch (vform) {
571 case kFormat16B:
572 return 16;
573 case kFormat8B:
574 case kFormat8H:
575 return 8;
576 case kFormat4H:
577 case kFormat4S:
578 return 4;
579 case kFormat2S:
580 case kFormat2D:
581 return 2;
582 case kFormat1D:
583 case kFormatB:
584 case kFormatH:
585 case kFormatS:
586 case kFormatD:
587 return 1;
588 default:
589 UNREACHABLE();
590 return 0;
591 }
592 }
593
594 int MaxLaneCountFromFormat(VectorFormat vform) {
595 DCHECK_NE(vform, kFormatUndefined);
596 switch (vform) {
597 case kFormatB:
598 case kFormat8B:
599 case kFormat16B:
600 return 16;
601 case kFormatH:
602 case kFormat4H:
603 case kFormat8H:
604 return 8;
605 case kFormatS:
606 case kFormat2S:
607 case kFormat4S:
608 return 4;
609 case kFormatD:
610 case kFormat1D:
611 case kFormat2D:
612 return 2;
613 default:
614 UNREACHABLE();
615 return 0;
616 }
617 }
618
619 // Does 'vform' indicate a vector format or a scalar format?
620 bool IsVectorFormat(VectorFormat vform) {
621 DCHECK_NE(vform, kFormatUndefined);
622 switch (vform) {
623 case kFormatB:
624 case kFormatH:
625 case kFormatS:
626 case kFormatD:
627 return false;
628 default:
629 return true;
630 }
631 }
632
633 int64_t MaxIntFromFormat(VectorFormat vform) {
634 return INT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform));
635 }
636
637 int64_t MinIntFromFormat(VectorFormat vform) {
638 return INT64_MIN >> (64 - LaneSizeInBitsFromFormat(vform));
639 }
640
641 uint64_t MaxUintFromFormat(VectorFormat vform) {
642 return UINT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform));
643 }
339 } // namespace internal 644 } // namespace internal
340 } // namespace v8 645 } // namespace v8
341 646
342 #endif // V8_TARGET_ARCH_ARM64 647 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698