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

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

Issue 2622643005: ARM64: Add NEON support (Closed)
Patch Set: Restore AreConsecutive change 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
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 #ifndef V8_ARM64_INSTRUCTIONS_ARM64_H_ 5 #ifndef V8_ARM64_INSTRUCTIONS_ARM64_H_
6 #define V8_ARM64_INSTRUCTIONS_ARM64_H_ 6 #define V8_ARM64_INSTRUCTIONS_ARM64_H_
7 7
8 #include "src/arm64/constants-arm64.h" 8 #include "src/arm64/constants-arm64.h"
9 #include "src/arm64/utils-arm64.h" 9 #include "src/arm64/utils-arm64.h"
10 #include "src/globals.h" 10 #include "src/globals.h"
11 #include "src/utils.h" 11 #include "src/utils.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 // ISA constants. -------------------------------------------------------------- 17 // ISA constants. --------------------------------------------------------------
18 18
19 typedef uint32_t Instr; 19 typedef uint32_t Instr;
20 20
21 // The following macros initialize a float/double variable with a bit pattern 21 // The following macros initialize a float/double variable with a bit pattern
22 // without using static initializers: If ARM64_DEFINE_FP_STATICS is defined, the 22 // without using static initializers: If ARM64_DEFINE_FP_STATICS is defined, the
23 // symbol is defined as uint32_t/uint64_t initialized with the desired bit 23 // symbol is defined as uint32_t/uint64_t initialized with the desired bit
24 // pattern. Otherwise, the same symbol is declared as an external float/double. 24 // pattern. Otherwise, the same symbol is declared as an external float/double.
25 #if defined(ARM64_DEFINE_FP_STATICS) 25 #if defined(ARM64_DEFINE_FP_STATICS)
26 #define DEFINE_FLOAT16(name, value) extern const uint16_t name = value
26 #define DEFINE_FLOAT(name, value) extern const uint32_t name = value 27 #define DEFINE_FLOAT(name, value) extern const uint32_t name = value
27 #define DEFINE_DOUBLE(name, value) extern const uint64_t name = value 28 #define DEFINE_DOUBLE(name, value) extern const uint64_t name = value
28 #else 29 #else
30 #define DEFINE_FLOAT16(name, value) extern const float16 name
29 #define DEFINE_FLOAT(name, value) extern const float name 31 #define DEFINE_FLOAT(name, value) extern const float name
30 #define DEFINE_DOUBLE(name, value) extern const double name 32 #define DEFINE_DOUBLE(name, value) extern const double name
31 #endif // defined(ARM64_DEFINE_FP_STATICS) 33 #endif // defined(ARM64_DEFINE_FP_STATICS)
32 34
35 DEFINE_FLOAT16(kFP16PositiveInfinity, 0x7c00);
36 DEFINE_FLOAT16(kFP16NegativeInfinity, 0xfc00);
33 DEFINE_FLOAT(kFP32PositiveInfinity, 0x7f800000); 37 DEFINE_FLOAT(kFP32PositiveInfinity, 0x7f800000);
34 DEFINE_FLOAT(kFP32NegativeInfinity, 0xff800000); 38 DEFINE_FLOAT(kFP32NegativeInfinity, 0xff800000);
35 DEFINE_DOUBLE(kFP64PositiveInfinity, 0x7ff0000000000000UL); 39 DEFINE_DOUBLE(kFP64PositiveInfinity, 0x7ff0000000000000UL);
36 DEFINE_DOUBLE(kFP64NegativeInfinity, 0xfff0000000000000UL); 40 DEFINE_DOUBLE(kFP64NegativeInfinity, 0xfff0000000000000UL);
37 41
38 // This value is a signalling NaN as both a double and as a float (taking the 42 // This value is a signalling NaN as both a double and as a float (taking the
39 // least-significant word). 43 // least-significant word).
40 DEFINE_DOUBLE(kFP64SignallingNaN, 0x7ff000007f800001); 44 DEFINE_DOUBLE(kFP64SignallingNaN, 0x7ff000007f800001);
41 DEFINE_FLOAT(kFP32SignallingNaN, 0x7f800001); 45 DEFINE_FLOAT(kFP32SignallingNaN, 0x7f800001);
42 46
43 // A similar value, but as a quiet NaN. 47 // A similar value, but as a quiet NaN.
44 DEFINE_DOUBLE(kFP64QuietNaN, 0x7ff800007fc00001); 48 DEFINE_DOUBLE(kFP64QuietNaN, 0x7ff800007fc00001);
45 DEFINE_FLOAT(kFP32QuietNaN, 0x7fc00001); 49 DEFINE_FLOAT(kFP32QuietNaN, 0x7fc00001);
46 50
47 // The default NaN values (for FPCR.DN=1). 51 // The default NaN values (for FPCR.DN=1).
48 DEFINE_DOUBLE(kFP64DefaultNaN, 0x7ff8000000000000UL); 52 DEFINE_DOUBLE(kFP64DefaultNaN, 0x7ff8000000000000UL);
49 DEFINE_FLOAT(kFP32DefaultNaN, 0x7fc00000); 53 DEFINE_FLOAT(kFP32DefaultNaN, 0x7fc00000);
54 DEFINE_FLOAT16(kFP16DefaultNaN, 0x7e00);
50 55
56 #undef DEFINE_FLOAT16
51 #undef DEFINE_FLOAT 57 #undef DEFINE_FLOAT
52 #undef DEFINE_DOUBLE 58 #undef DEFINE_DOUBLE
53 59
54 60 unsigned CalcLSDataSize(LoadStoreOp op);
55 enum LSDataSize { 61 unsigned CalcLSPairDataSize(LoadStorePairOp op);
56 LSByte = 0,
57 LSHalfword = 1,
58 LSWord = 2,
59 LSDoubleWord = 3
60 };
61
62 LSDataSize CalcLSPairDataSize(LoadStorePairOp op);
63 62
64 enum ImmBranchType { 63 enum ImmBranchType {
65 UnknownBranchType = 0, 64 UnknownBranchType = 0,
66 CondBranchType = 1, 65 CondBranchType = 1,
67 UncondBranchType = 2, 66 UncondBranchType = 2,
68 CompareBranchType = 3, 67 CompareBranchType = 3,
69 TestBranchType = 4 68 TestBranchType = 4
70 }; 69 };
71 70
72 enum AddrMode { 71 enum AddrMode {
73 Offset, 72 Offset,
74 PreIndex, 73 PreIndex,
75 PostIndex 74 PostIndex
76 }; 75 };
77 76
78 enum FPRounding { 77 enum FPRounding {
79 // The first four values are encodable directly by FPCR<RMode>. 78 // The first four values are encodable directly by FPCR<RMode>.
80 FPTieEven = 0x0, 79 FPTieEven = 0x0,
81 FPPositiveInfinity = 0x1, 80 FPPositiveInfinity = 0x1,
82 FPNegativeInfinity = 0x2, 81 FPNegativeInfinity = 0x2,
83 FPZero = 0x3, 82 FPZero = 0x3,
84 83
85 // The final rounding mode is only available when explicitly specified by the 84 // The final rounding modes are only available when explicitly specified by
86 // instruction (such as with fcvta). It cannot be set in FPCR. 85 // the instruction (such as with fcvta). They cannot be set in FPCR.
87 FPTieAway 86 FPTieAway,
87 FPRoundOdd
88 }; 88 };
89 89
90 enum Reg31Mode { 90 enum Reg31Mode {
91 Reg31IsStackPointer, 91 Reg31IsStackPointer,
92 Reg31IsZeroRegister 92 Reg31IsZeroRegister
93 }; 93 };
94 94
95 // Instructions. --------------------------------------------------------------- 95 // Instructions. ---------------------------------------------------------------
96 96
97 class Instruction { 97 class Instruction {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST), 145 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST),
146 // formed from ImmPCRelLo and ImmPCRelHi. 146 // formed from ImmPCRelLo and ImmPCRelHi.
147 int ImmPCRel() const { 147 int ImmPCRel() const {
148 DCHECK(IsPCRelAddressing()); 148 DCHECK(IsPCRelAddressing());
149 int offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo()); 149 int offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo());
150 int width = ImmPCRelLo_width + ImmPCRelHi_width; 150 int width = ImmPCRelLo_width + ImmPCRelHi_width;
151 return signed_bitextract_32(width - 1, 0, offset); 151 return signed_bitextract_32(width - 1, 0, offset);
152 } 152 }
153 153
154 uint64_t ImmLogical(); 154 uint64_t ImmLogical();
155 unsigned ImmNEONabcdefgh() const;
155 float ImmFP32(); 156 float ImmFP32();
156 double ImmFP64(); 157 double ImmFP64();
158 float ImmNEONFP32() const;
159 double ImmNEONFP64() const;
157 160
158 LSDataSize SizeLSPair() const { 161 unsigned SizeLS() const {
162 return CalcLSDataSize(static_cast<LoadStoreOp>(Mask(LoadStoreMask)));
163 }
164
165 unsigned SizeLSPair() const {
159 return CalcLSPairDataSize( 166 return CalcLSPairDataSize(
160 static_cast<LoadStorePairOp>(Mask(LoadStorePairMask))); 167 static_cast<LoadStorePairOp>(Mask(LoadStorePairMask)));
161 } 168 }
162 169
170 int NEONLSIndex(int access_size_shift) const {
171 int q = NEONQ();
172 int s = NEONS();
173 int size = NEONLSSize();
174 int index = (q << 3) | (s << 2) | size;
175 return index >> access_size_shift;
176 }
177
163 // Helpers. 178 // Helpers.
164 bool IsCondBranchImm() const { 179 bool IsCondBranchImm() const {
165 return Mask(ConditionalBranchFMask) == ConditionalBranchFixed; 180 return Mask(ConditionalBranchFMask) == ConditionalBranchFixed;
166 } 181 }
167 182
168 bool IsUncondBranchImm() const { 183 bool IsUncondBranchImm() const {
169 return Mask(UnconditionalBranchFMask) == UnconditionalBranchFixed; 184 return Mask(UnconditionalBranchFMask) == UnconditionalBranchFixed;
170 } 185 }
171 186
172 bool IsCompareBranch() const { 187 bool IsCompareBranch() const {
173 return Mask(CompareBranchFMask) == CompareBranchFixed; 188 return Mask(CompareBranchFMask) == CompareBranchFixed;
174 } 189 }
175 190
176 bool IsTestBranch() const { 191 bool IsTestBranch() const {
177 return Mask(TestBranchFMask) == TestBranchFixed; 192 return Mask(TestBranchFMask) == TestBranchFixed;
178 } 193 }
179 194
180 bool IsImmBranch() const { 195 bool IsImmBranch() const {
181 return BranchType() != UnknownBranchType; 196 return BranchType() != UnknownBranchType;
182 } 197 }
183 198
199 static float Imm8ToFP32(uint32_t imm8) {
200 // Imm8: abcdefgh (8 bits)
201 // Single: aBbb.bbbc.defg.h000.0000.0000.0000.0000 (32 bits)
202 // where B is b ^ 1
203 uint32_t bits = imm8;
204 uint32_t bit7 = (bits >> 7) & 0x1;
205 uint32_t bit6 = (bits >> 6) & 0x1;
206 uint32_t bit5_to_0 = bits & 0x3f;
207 uint32_t result = (bit7 << 31) | ((32 - bit6) << 25) | (bit5_to_0 << 19);
208
209 return bit_cast<float>(result);
210 }
211
212 static double Imm8ToFP64(uint32_t imm8) {
213 // Imm8: abcdefgh (8 bits)
214 // Double: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
215 // 0000.0000.0000.0000.0000.0000.0000.0000 (64 bits)
216 // where B is b ^ 1
217 uint32_t bits = imm8;
218 uint64_t bit7 = (bits >> 7) & 0x1;
219 uint64_t bit6 = (bits >> 6) & 0x1;
220 uint64_t bit5_to_0 = bits & 0x3f;
221 uint64_t result = (bit7 << 63) | ((256 - bit6) << 54) | (bit5_to_0 << 48);
222
223 return bit_cast<double>(result);
224 }
225
184 bool IsLdrLiteral() const { 226 bool IsLdrLiteral() const {
185 return Mask(LoadLiteralFMask) == LoadLiteralFixed; 227 return Mask(LoadLiteralFMask) == LoadLiteralFixed;
186 } 228 }
187 229
188 bool IsLdrLiteralX() const { 230 bool IsLdrLiteralX() const {
189 return Mask(LoadLiteralMask) == LDR_x_lit; 231 return Mask(LoadLiteralMask) == LDR_x_lit;
190 } 232 }
191 233
192 bool IsPCRelAddressing() const { 234 bool IsPCRelAddressing() const {
193 return Mask(PCRelAddressingFMask) == PCRelAddressingFixed; 235 return Mask(PCRelAddressingFMask) == PCRelAddressingFixed;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 return reinterpret_cast<Address>(target) - reinterpret_cast<Address>(this); 450 return reinterpret_cast<Address>(target) - reinterpret_cast<Address>(this);
409 } 451 }
410 452
411 453
412 static const int ImmPCRelRangeBitwidth = 21; 454 static const int ImmPCRelRangeBitwidth = 21;
413 static bool IsValidPCRelOffset(ptrdiff_t offset) { return is_int21(offset); } 455 static bool IsValidPCRelOffset(ptrdiff_t offset) { return is_int21(offset); }
414 void SetPCRelImmTarget(Isolate* isolate, Instruction* target); 456 void SetPCRelImmTarget(Isolate* isolate, Instruction* target);
415 void SetBranchImmTarget(Instruction* target); 457 void SetBranchImmTarget(Instruction* target);
416 }; 458 };
417 459
460 // Functions for handling NEON vector format information.
461 enum VectorFormat {
462 kFormatUndefined = 0xffffffff,
463 kFormat8B = NEON_8B,
464 kFormat16B = NEON_16B,
465 kFormat4H = NEON_4H,
466 kFormat8H = NEON_8H,
467 kFormat2S = NEON_2S,
468 kFormat4S = NEON_4S,
469 kFormat1D = NEON_1D,
470 kFormat2D = NEON_2D,
471
472 // Scalar formats. We add the scalar bit to distinguish between scalar and
473 // vector enumerations; the bit is always set in the encoding of scalar ops
474 // and always clear for vector ops. Although kFormatD and kFormat1D appear
475 // to be the same, their meaning is subtly different. The first is a scalar
476 // operation, the second a vector operation that only affects one lane.
477 kFormatB = NEON_B | NEONScalar,
478 kFormatH = NEON_H | NEONScalar,
479 kFormatS = NEON_S | NEONScalar,
480 kFormatD = NEON_D | NEONScalar
481 };
482
483 VectorFormat VectorFormatHalfWidth(VectorFormat vform);
484 VectorFormat VectorFormatDoubleWidth(VectorFormat vform);
485 VectorFormat VectorFormatDoubleLanes(VectorFormat vform);
486 VectorFormat VectorFormatHalfLanes(VectorFormat vform);
487 VectorFormat ScalarFormatFromLaneSize(int lanesize);
488 VectorFormat VectorFormatHalfWidthDoubleLanes(VectorFormat vform);
489 VectorFormat VectorFormatFillQ(VectorFormat vform);
490 VectorFormat ScalarFormatFromFormat(VectorFormat vform);
491 unsigned RegisterSizeInBitsFromFormat(VectorFormat vform);
492 unsigned RegisterSizeInBytesFromFormat(VectorFormat vform);
493 int LaneSizeInBytesFromFormat(VectorFormat vform);
494 unsigned LaneSizeInBitsFromFormat(VectorFormat vform);
495 int LaneSizeInBytesLog2FromFormat(VectorFormat vform);
496 int LaneCountFromFormat(VectorFormat vform);
497 int MaxLaneCountFromFormat(VectorFormat vform);
498 bool IsVectorFormat(VectorFormat vform);
499 int64_t MaxIntFromFormat(VectorFormat vform);
500 int64_t MinIntFromFormat(VectorFormat vform);
501 uint64_t MaxUintFromFormat(VectorFormat vform);
418 502
419 // Where Instruction looks at instructions generated by the Assembler, 503 // Where Instruction looks at instructions generated by the Assembler,
420 // InstructionSequence looks at instructions sequences generated by the 504 // InstructionSequence looks at instructions sequences generated by the
421 // MacroAssembler. 505 // MacroAssembler.
422 class InstructionSequence : public Instruction { 506 class InstructionSequence : public Instruction {
423 public: 507 public:
424 static InstructionSequence* At(Address address) { 508 static InstructionSequence* At(Address address) {
425 return reinterpret_cast<InstructionSequence*>(address); 509 return reinterpret_cast<InstructionSequence*>(address);
426 } 510 }
427 511
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 // Debug parameters. 579 // Debug parameters.
496 // Used without a TRACE_ option, the Debugger will print the arguments only 580 // Used without a TRACE_ option, the Debugger will print the arguments only
497 // once. Otherwise TRACE_ENABLE and TRACE_DISABLE will enable or disable tracing 581 // once. Otherwise TRACE_ENABLE and TRACE_DISABLE will enable or disable tracing
498 // before every instruction for the specified LOG_ parameters. 582 // before every instruction for the specified LOG_ parameters.
499 // 583 //
500 // TRACE_OVERRIDE enables the specified LOG_ parameters, and disabled any 584 // TRACE_OVERRIDE enables the specified LOG_ parameters, and disabled any
501 // others that were not specified. 585 // others that were not specified.
502 // 586 //
503 // For example: 587 // For example:
504 // 588 //
505 // __ debug("print registers and fp registers", 0, LOG_REGS | LOG_FP_REGS); 589 // __ debug("print registers and fp registers", 0, LOG_REGS | LOG_VREGS);
506 // will print the registers and fp registers only once. 590 // will print the registers and fp registers only once.
507 // 591 //
508 // __ debug("trace disasm", 1, TRACE_ENABLE | LOG_DISASM); 592 // __ debug("trace disasm", 1, TRACE_ENABLE | LOG_DISASM);
509 // starts disassembling the code. 593 // starts disassembling the code.
510 // 594 //
511 // __ debug("trace rets", 2, TRACE_ENABLE | LOG_REGS); 595 // __ debug("trace rets", 2, TRACE_ENABLE | LOG_REGS);
512 // adds the general purpose registers to the trace. 596 // adds the general purpose registers to the trace.
513 // 597 //
514 // __ debug("stop regs", 3, TRACE_DISABLE | LOG_REGS); 598 // __ debug("stop regs", 3, TRACE_DISABLE | LOG_REGS);
515 // stops tracing the registers. 599 // stops tracing the registers.
516 const unsigned kDebuggerTracingDirectivesMask = 3 << 6; 600 const unsigned kDebuggerTracingDirectivesMask = 3 << 6;
517 enum DebugParameters { 601 enum DebugParameters {
518 NO_PARAM = 0, 602 NO_PARAM = 0,
519 BREAK = 1 << 0, 603 BREAK = 1 << 0,
520 LOG_DISASM = 1 << 1, // Use only with TRACE. Disassemble the code. 604 LOG_DISASM = 1 << 1, // Use only with TRACE. Disassemble the code.
521 LOG_REGS = 1 << 2, // Log general purpose registers. 605 LOG_REGS = 1 << 2, // Log general purpose registers.
522 LOG_FP_REGS = 1 << 3, // Log floating-point registers. 606 LOG_VREGS = 1 << 3, // Log NEON and floating-point registers.
523 LOG_SYS_REGS = 1 << 4, // Log the status flags. 607 LOG_SYS_REGS = 1 << 4, // Log the status flags.
524 LOG_WRITE = 1 << 5, // Log any memory write. 608 LOG_WRITE = 1 << 5, // Log any memory write.
525 609
526 LOG_STATE = LOG_REGS | LOG_FP_REGS | LOG_SYS_REGS, 610 LOG_NONE = 0,
527 LOG_ALL = LOG_DISASM | LOG_STATE | LOG_WRITE, 611 LOG_STATE = LOG_REGS | LOG_VREGS | LOG_SYS_REGS,
612 LOG_ALL = LOG_DISASM | LOG_STATE | LOG_WRITE,
528 613
529 // Trace control. 614 // Trace control.
530 TRACE_ENABLE = 1 << 6, 615 TRACE_ENABLE = 1 << 6,
531 TRACE_DISABLE = 2 << 6, 616 TRACE_DISABLE = 2 << 6,
532 TRACE_OVERRIDE = 3 << 6 617 TRACE_OVERRIDE = 3 << 6
533 }; 618 };
534 619
535 620 enum NEONFormat {
621 NF_UNDEF = 0,
622 NF_8B = 1,
623 NF_16B = 2,
624 NF_4H = 3,
625 NF_8H = 4,
626 NF_2S = 5,
627 NF_4S = 6,
628 NF_1D = 7,
629 NF_2D = 8,
630 NF_B = 9,
631 NF_H = 10,
632 NF_S = 11,
633 NF_D = 12
634 };
635
636 static const unsigned kNEONFormatMaxBits = 6;
637
638 struct NEONFormatMap {
639 // The bit positions in the instruction to consider.
640 uint8_t bits[kNEONFormatMaxBits];
641
642 // Mapping from concatenated bits to format.
643 NEONFormat map[1 << kNEONFormatMaxBits];
644 };
645
646 class NEONFormatDecoder {
647 public:
648 enum SubstitutionMode { kPlaceholder, kFormat };
649
650 // Construct a format decoder with increasingly specific format maps for each
651 // substitution. If no format map is specified, the default is the integer
652 // format map.
653 explicit NEONFormatDecoder(const Instruction* instr);
654 NEONFormatDecoder(const Instruction* instr, const NEONFormatMap* format);
655 NEONFormatDecoder(const Instruction* instr, const NEONFormatMap* format0,
656 const NEONFormatMap* format1);
657 NEONFormatDecoder(const Instruction* instr, const NEONFormatMap* format0,
658 const NEONFormatMap* format1, const NEONFormatMap* format2);
659
660 // Set the format mapping for all or individual substitutions.
661 void SetFormatMaps(const NEONFormatMap* format0,
662 const NEONFormatMap* format1 = NULL,
663 const NEONFormatMap* format2 = NULL);
664 void SetFormatMap(unsigned index, const NEONFormatMap* format);
665
666 // Substitute %s in the input string with the placeholder string for each
667 // register, ie. "'B", "'H", etc.
668 const char* SubstitutePlaceholders(const char* string);
669
670 // Substitute %s in the input string with a new string based on the
671 // substitution mode.
672 const char* Substitute(const char* string, SubstitutionMode mode0 = kFormat,
673 SubstitutionMode mode1 = kFormat,
674 SubstitutionMode mode2 = kFormat);
675
676 // Append a "2" to a mnemonic string based of the state of the Q bit.
677 const char* Mnemonic(const char* mnemonic);
678
679 VectorFormat GetVectorFormat(int format_index = 0);
680 VectorFormat GetVectorFormat(const NEONFormatMap* format_map);
681
682 // Built in mappings for common cases.
683
684 // The integer format map uses three bits (Q, size<1:0>) to encode the
685 // "standard" set of NEON integer vector formats.
686 static const NEONFormatMap* IntegerFormatMap() {
687 static const NEONFormatMap map = {
688 {23, 22, 30},
689 {NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_UNDEF, NF_2D}};
690 return &map;
691 }
692
693 // The long integer format map uses two bits (size<1:0>) to encode the
694 // long set of NEON integer vector formats. These are used in narrow, wide
695 // and long operations.
696 static const NEONFormatMap* LongIntegerFormatMap() {
697 static const NEONFormatMap map = {{23, 22}, {NF_8H, NF_4S, NF_2D}};
698 return &map;
699 }
700
701 // The FP format map uses two bits (Q, size<0>) to encode the NEON FP vector
702 // formats: NF_2S, NF_4S, NF_2D.
703 static const NEONFormatMap* FPFormatMap() {
704 // The FP format map assumes two bits (Q, size<0>) are used to encode the
705 // NEON FP vector formats: NF_2S, NF_4S, NF_2D.
706 static const NEONFormatMap map = {{22, 30},
707 {NF_2S, NF_4S, NF_UNDEF, NF_2D}};
708 return &map;
709 }
710
711 // The load/store format map uses three bits (Q, 11, 10) to encode the
712 // set of NEON vector formats.
713 static const NEONFormatMap* LoadStoreFormatMap() {
714 static const NEONFormatMap map = {
715 {11, 10, 30},
716 {NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_1D, NF_2D}};
717 return &map;
718 }
719
720 // The logical format map uses one bit (Q) to encode the NEON vector format:
721 // NF_8B, NF_16B.
722 static const NEONFormatMap* LogicalFormatMap() {
723 static const NEONFormatMap map = {{30}, {NF_8B, NF_16B}};
724 return &map;
725 }
726
727 // The triangular format map uses between two and five bits to encode the NEON
728 // vector format:
729 // xxx10->8B, xxx11->16B, xx100->4H, xx101->8H
730 // x1000->2S, x1001->4S, 10001->2D, all others undefined.
731 static const NEONFormatMap* TriangularFormatMap() {
732 static const NEONFormatMap map = {
733 {19, 18, 17, 16, 30},
734 {NF_UNDEF, NF_UNDEF, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B,
735 NF_2S, NF_4S, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B,
736 NF_UNDEF, NF_2D, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B,
737 NF_2S, NF_4S, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B}};
738 return &map;
739 }
740
741 // The scalar format map uses two bits (size<1:0>) to encode the NEON scalar
742 // formats: NF_B, NF_H, NF_S, NF_D.
743 static const NEONFormatMap* ScalarFormatMap() {
744 static const NEONFormatMap map = {{23, 22}, {NF_B, NF_H, NF_S, NF_D}};
745 return &map;
746 }
747
748 // The long scalar format map uses two bits (size<1:0>) to encode the longer
749 // NEON scalar formats: NF_H, NF_S, NF_D.
750 static const NEONFormatMap* LongScalarFormatMap() {
751 static const NEONFormatMap map = {{23, 22}, {NF_H, NF_S, NF_D}};
752 return &map;
753 }
754
755 // The FP scalar format map assumes one bit (size<0>) is used to encode the
756 // NEON FP scalar formats: NF_S, NF_D.
757 static const NEONFormatMap* FPScalarFormatMap() {
758 static const NEONFormatMap map = {{22}, {NF_S, NF_D}};
759 return &map;
760 }
761
762 // The triangular scalar format map uses between one and four bits to encode
763 // the NEON FP scalar formats:
764 // xxx1->B, xx10->H, x100->S, 1000->D, all others undefined.
765 static const NEONFormatMap* TriangularScalarFormatMap() {
766 static const NEONFormatMap map = {
767 {19, 18, 17, 16},
768 {NF_UNDEF, NF_B, NF_H, NF_B, NF_S, NF_B, NF_H, NF_B, NF_D, NF_B, NF_H,
769 NF_B, NF_S, NF_B, NF_H, NF_B}};
770 return &map;
771 }
772
773 private:
774 // Get a pointer to a string that represents the format or placeholder for
775 // the specified substitution index, based on the format map and instruction.
776 const char* GetSubstitute(int index, SubstitutionMode mode);
777
778 // Get the NEONFormat enumerated value for bits obtained from the
779 // instruction based on the specified format mapping.
780 NEONFormat GetNEONFormat(const NEONFormatMap* format_map);
781
782 // Convert a NEONFormat into a string.
783 static const char* NEONFormatAsString(NEONFormat format);
784
785 // Convert a NEONFormat into a register placeholder string.
786 static const char* NEONFormatAsPlaceholder(NEONFormat format);
787
788 // Select bits from instrbits_ defined by the bits array, concatenate them,
789 // and return the value.
790 uint8_t PickBits(const uint8_t bits[]);
791
792 Instr instrbits_;
793 const NEONFormatMap* formats_[3];
794 char form_buffer_[64];
795 char mne_buffer_[16];
796 };
536 } // namespace internal 797 } // namespace internal
537 } // namespace v8 798 } // namespace v8
538 799
539 800
540 #endif // V8_ARM64_INSTRUCTIONS_ARM64_H_ 801 #endif // V8_ARM64_INSTRUCTIONS_ARM64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698