| OLD | NEW | 
|    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  Loading... | 
|  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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  327 // xzr and Register are not defined in that header. Consider adding |  340 // xzr and Register are not defined in that header. Consider adding | 
|  328 // instructions-arm64-inl.h to work around this. |  341 // instructions-arm64-inl.h to work around this. | 
|  329 uint64_t InstructionSequence::InlineData() const { |  342 uint64_t InstructionSequence::InlineData() const { | 
|  330   DCHECK(IsInlineData()); |  343   DCHECK(IsInlineData()); | 
|  331   uint64_t payload = ImmMoveWide(); |  344   uint64_t payload = ImmMoveWide(); | 
|  332   // TODO(all): If we extend ::InlineData() to support bigger data, we need |  345   // TODO(all): If we extend ::InlineData() to support bigger data, we need | 
|  333   // to update this method too. |  346   // to update this method too. | 
|  334   return payload; |  347   return payload; | 
|  335 } |  348 } | 
|  336  |  349  | 
|  337  |  350 VectorFormat VectorFormatHalfWidth(VectorFormat vform) { | 
 |  351   DCHECK(vform == kFormat8H || vform == kFormat4S || vform == kFormat2D || | 
 |  352          vform == kFormatH || vform == kFormatS || vform == kFormatD); | 
 |  353   switch (vform) { | 
 |  354     case kFormat8H: | 
 |  355       return kFormat8B; | 
 |  356     case kFormat4S: | 
 |  357       return kFormat4H; | 
 |  358     case kFormat2D: | 
 |  359       return kFormat2S; | 
 |  360     case kFormatH: | 
 |  361       return kFormatB; | 
 |  362     case kFormatS: | 
 |  363       return kFormatH; | 
 |  364     case kFormatD: | 
 |  365       return kFormatS; | 
 |  366     default: | 
 |  367       UNREACHABLE(); | 
 |  368       return kFormatUndefined; | 
 |  369   } | 
 |  370 } | 
 |  371  | 
 |  372 VectorFormat VectorFormatDoubleWidth(VectorFormat vform) { | 
 |  373   DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S || | 
 |  374          vform == kFormatB || vform == kFormatH || vform == kFormatS); | 
 |  375   switch (vform) { | 
 |  376     case kFormat8B: | 
 |  377       return kFormat8H; | 
 |  378     case kFormat4H: | 
 |  379       return kFormat4S; | 
 |  380     case kFormat2S: | 
 |  381       return kFormat2D; | 
 |  382     case kFormatB: | 
 |  383       return kFormatH; | 
 |  384     case kFormatH: | 
 |  385       return kFormatS; | 
 |  386     case kFormatS: | 
 |  387       return kFormatD; | 
 |  388     default: | 
 |  389       UNREACHABLE(); | 
 |  390       return kFormatUndefined; | 
 |  391   } | 
 |  392 } | 
 |  393  | 
 |  394 VectorFormat VectorFormatFillQ(VectorFormat vform) { | 
 |  395   switch (vform) { | 
 |  396     case kFormatB: | 
 |  397     case kFormat8B: | 
 |  398     case kFormat16B: | 
 |  399       return kFormat16B; | 
 |  400     case kFormatH: | 
 |  401     case kFormat4H: | 
 |  402     case kFormat8H: | 
 |  403       return kFormat8H; | 
 |  404     case kFormatS: | 
 |  405     case kFormat2S: | 
 |  406     case kFormat4S: | 
 |  407       return kFormat4S; | 
 |  408     case kFormatD: | 
 |  409     case kFormat1D: | 
 |  410     case kFormat2D: | 
 |  411       return kFormat2D; | 
 |  412     default: | 
 |  413       UNREACHABLE(); | 
 |  414       return kFormatUndefined; | 
 |  415   } | 
 |  416 } | 
 |  417  | 
 |  418 VectorFormat VectorFormatHalfWidthDoubleLanes(VectorFormat vform) { | 
 |  419   switch (vform) { | 
 |  420     case kFormat4H: | 
 |  421       return kFormat8B; | 
 |  422     case kFormat8H: | 
 |  423       return kFormat16B; | 
 |  424     case kFormat2S: | 
 |  425       return kFormat4H; | 
 |  426     case kFormat4S: | 
 |  427       return kFormat8H; | 
 |  428     case kFormat1D: | 
 |  429       return kFormat2S; | 
 |  430     case kFormat2D: | 
 |  431       return kFormat4S; | 
 |  432     default: | 
 |  433       UNREACHABLE(); | 
 |  434       return kFormatUndefined; | 
 |  435   } | 
 |  436 } | 
 |  437  | 
 |  438 VectorFormat VectorFormatDoubleLanes(VectorFormat vform) { | 
 |  439   DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S); | 
 |  440   switch (vform) { | 
 |  441     case kFormat8B: | 
 |  442       return kFormat16B; | 
 |  443     case kFormat4H: | 
 |  444       return kFormat8H; | 
 |  445     case kFormat2S: | 
 |  446       return kFormat4S; | 
 |  447     default: | 
 |  448       UNREACHABLE(); | 
 |  449       return kFormatUndefined; | 
 |  450   } | 
 |  451 } | 
 |  452  | 
 |  453 VectorFormat VectorFormatHalfLanes(VectorFormat vform) { | 
 |  454   DCHECK(vform == kFormat16B || vform == kFormat8H || vform == kFormat4S); | 
 |  455   switch (vform) { | 
 |  456     case kFormat16B: | 
 |  457       return kFormat8B; | 
 |  458     case kFormat8H: | 
 |  459       return kFormat4H; | 
 |  460     case kFormat4S: | 
 |  461       return kFormat2S; | 
 |  462     default: | 
 |  463       UNREACHABLE(); | 
 |  464       return kFormatUndefined; | 
 |  465   } | 
 |  466 } | 
 |  467  | 
 |  468 VectorFormat ScalarFormatFromLaneSize(int laneSize) { | 
 |  469   switch (laneSize) { | 
 |  470     case 8: | 
 |  471       return kFormatB; | 
 |  472     case 16: | 
 |  473       return kFormatH; | 
 |  474     case 32: | 
 |  475       return kFormatS; | 
 |  476     case 64: | 
 |  477       return kFormatD; | 
 |  478     default: | 
 |  479       UNREACHABLE(); | 
 |  480       return kFormatUndefined; | 
 |  481   } | 
 |  482 } | 
 |  483  | 
 |  484 VectorFormat ScalarFormatFromFormat(VectorFormat vform) { | 
 |  485   return ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform)); | 
 |  486 } | 
 |  487  | 
 |  488 unsigned RegisterSizeInBytesFromFormat(VectorFormat vform) { | 
 |  489   return RegisterSizeInBitsFromFormat(vform) / 8; | 
 |  490 } | 
 |  491  | 
 |  492 unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) { | 
 |  493   DCHECK_NE(vform, kFormatUndefined); | 
 |  494   switch (vform) { | 
 |  495     case kFormatB: | 
 |  496       return kBRegSizeInBits; | 
 |  497     case kFormatH: | 
 |  498       return kHRegSizeInBits; | 
 |  499     case kFormatS: | 
 |  500       return kSRegSizeInBits; | 
 |  501     case kFormatD: | 
 |  502       return kDRegSizeInBits; | 
 |  503     case kFormat8B: | 
 |  504     case kFormat4H: | 
 |  505     case kFormat2S: | 
 |  506     case kFormat1D: | 
 |  507       return kDRegSizeInBits; | 
 |  508     default: | 
 |  509       return kQRegSizeInBits; | 
 |  510   } | 
 |  511 } | 
 |  512  | 
 |  513 unsigned LaneSizeInBitsFromFormat(VectorFormat vform) { | 
 |  514   DCHECK_NE(vform, kFormatUndefined); | 
 |  515   switch (vform) { | 
 |  516     case kFormatB: | 
 |  517     case kFormat8B: | 
 |  518     case kFormat16B: | 
 |  519       return 8; | 
 |  520     case kFormatH: | 
 |  521     case kFormat4H: | 
 |  522     case kFormat8H: | 
 |  523       return 16; | 
 |  524     case kFormatS: | 
 |  525     case kFormat2S: | 
 |  526     case kFormat4S: | 
 |  527       return 32; | 
 |  528     case kFormatD: | 
 |  529     case kFormat1D: | 
 |  530     case kFormat2D: | 
 |  531       return 64; | 
 |  532     default: | 
 |  533       UNREACHABLE(); | 
 |  534       return 0; | 
 |  535   } | 
 |  536 } | 
 |  537  | 
 |  538 int LaneSizeInBytesFromFormat(VectorFormat vform) { | 
 |  539   return LaneSizeInBitsFromFormat(vform) / 8; | 
 |  540 } | 
 |  541  | 
 |  542 int LaneSizeInBytesLog2FromFormat(VectorFormat vform) { | 
 |  543   DCHECK_NE(vform, kFormatUndefined); | 
 |  544   switch (vform) { | 
 |  545     case kFormatB: | 
 |  546     case kFormat8B: | 
 |  547     case kFormat16B: | 
 |  548       return 0; | 
 |  549     case kFormatH: | 
 |  550     case kFormat4H: | 
 |  551     case kFormat8H: | 
 |  552       return 1; | 
 |  553     case kFormatS: | 
 |  554     case kFormat2S: | 
 |  555     case kFormat4S: | 
 |  556       return 2; | 
 |  557     case kFormatD: | 
 |  558     case kFormat1D: | 
 |  559     case kFormat2D: | 
 |  560       return 3; | 
 |  561     default: | 
 |  562       UNREACHABLE(); | 
 |  563       return 0; | 
 |  564   } | 
 |  565 } | 
 |  566  | 
 |  567 int LaneCountFromFormat(VectorFormat vform) { | 
 |  568   DCHECK_NE(vform, kFormatUndefined); | 
 |  569   switch (vform) { | 
 |  570     case kFormat16B: | 
 |  571       return 16; | 
 |  572     case kFormat8B: | 
 |  573     case kFormat8H: | 
 |  574       return 8; | 
 |  575     case kFormat4H: | 
 |  576     case kFormat4S: | 
 |  577       return 4; | 
 |  578     case kFormat2S: | 
 |  579     case kFormat2D: | 
 |  580       return 2; | 
 |  581     case kFormat1D: | 
 |  582     case kFormatB: | 
 |  583     case kFormatH: | 
 |  584     case kFormatS: | 
 |  585     case kFormatD: | 
 |  586       return 1; | 
 |  587     default: | 
 |  588       UNREACHABLE(); | 
 |  589       return 0; | 
 |  590   } | 
 |  591 } | 
 |  592  | 
 |  593 int MaxLaneCountFromFormat(VectorFormat vform) { | 
 |  594   DCHECK_NE(vform, kFormatUndefined); | 
 |  595   switch (vform) { | 
 |  596     case kFormatB: | 
 |  597     case kFormat8B: | 
 |  598     case kFormat16B: | 
 |  599       return 16; | 
 |  600     case kFormatH: | 
 |  601     case kFormat4H: | 
 |  602     case kFormat8H: | 
 |  603       return 8; | 
 |  604     case kFormatS: | 
 |  605     case kFormat2S: | 
 |  606     case kFormat4S: | 
 |  607       return 4; | 
 |  608     case kFormatD: | 
 |  609     case kFormat1D: | 
 |  610     case kFormat2D: | 
 |  611       return 2; | 
 |  612     default: | 
 |  613       UNREACHABLE(); | 
 |  614       return 0; | 
 |  615   } | 
 |  616 } | 
 |  617  | 
 |  618 // Does 'vform' indicate a vector format or a scalar format? | 
 |  619 bool IsVectorFormat(VectorFormat vform) { | 
 |  620   DCHECK_NE(vform, kFormatUndefined); | 
 |  621   switch (vform) { | 
 |  622     case kFormatB: | 
 |  623     case kFormatH: | 
 |  624     case kFormatS: | 
 |  625     case kFormatD: | 
 |  626       return false; | 
 |  627     default: | 
 |  628       return true; | 
 |  629   } | 
 |  630 } | 
 |  631  | 
 |  632 int64_t MaxIntFromFormat(VectorFormat vform) { | 
 |  633   return INT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform)); | 
 |  634 } | 
 |  635  | 
 |  636 int64_t MinIntFromFormat(VectorFormat vform) { | 
 |  637   return INT64_MIN >> (64 - LaneSizeInBitsFromFormat(vform)); | 
 |  638 } | 
 |  639  | 
 |  640 uint64_t MaxUintFromFormat(VectorFormat vform) { | 
 |  641   return UINT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform)); | 
 |  642 } | 
 |  643  | 
 |  644 NEONFormatDecoder::NEONFormatDecoder(const Instruction* instr) { | 
 |  645   instrbits_ = instr->InstructionBits(); | 
 |  646   SetFormatMaps(IntegerFormatMap()); | 
 |  647 } | 
 |  648  | 
 |  649 NEONFormatDecoder::NEONFormatDecoder(const Instruction* instr, | 
 |  650                                      const NEONFormatMap* format) { | 
 |  651   instrbits_ = instr->InstructionBits(); | 
 |  652   SetFormatMaps(format); | 
 |  653 } | 
 |  654  | 
 |  655 NEONFormatDecoder::NEONFormatDecoder(const Instruction* instr, | 
 |  656                                      const NEONFormatMap* format0, | 
 |  657                                      const NEONFormatMap* format1) { | 
 |  658   instrbits_ = instr->InstructionBits(); | 
 |  659   SetFormatMaps(format0, format1); | 
 |  660 } | 
 |  661  | 
 |  662 NEONFormatDecoder::NEONFormatDecoder(const Instruction* instr, | 
 |  663                                      const NEONFormatMap* format0, | 
 |  664                                      const NEONFormatMap* format1, | 
 |  665                                      const NEONFormatMap* format2) { | 
 |  666   instrbits_ = instr->InstructionBits(); | 
 |  667   SetFormatMaps(format0, format1, format2); | 
 |  668 } | 
 |  669  | 
 |  670 void NEONFormatDecoder::SetFormatMaps(const NEONFormatMap* format0, | 
 |  671                                       const NEONFormatMap* format1, | 
 |  672                                       const NEONFormatMap* format2) { | 
 |  673   DCHECK_NOT_NULL(format0); | 
 |  674   formats_[0] = format0; | 
 |  675   formats_[1] = (format1 == NULL) ? formats_[0] : format1; | 
 |  676   formats_[2] = (format2 == NULL) ? formats_[1] : format2; | 
 |  677 } | 
 |  678  | 
 |  679 void NEONFormatDecoder::SetFormatMap(unsigned index, | 
 |  680                                      const NEONFormatMap* format) { | 
 |  681   DCHECK_LT(index, arraysize(formats_)); | 
 |  682   DCHECK_NOT_NULL(format); | 
 |  683   formats_[index] = format; | 
 |  684 } | 
 |  685  | 
 |  686 const char* NEONFormatDecoder::SubstitutePlaceholders(const char* string) { | 
 |  687   return Substitute(string, kPlaceholder, kPlaceholder, kPlaceholder); | 
 |  688 } | 
 |  689  | 
 |  690 const char* NEONFormatDecoder::Substitute(const char* string, | 
 |  691                                           SubstitutionMode mode0, | 
 |  692                                           SubstitutionMode mode1, | 
 |  693                                           SubstitutionMode mode2) { | 
 |  694   snprintf(form_buffer_, sizeof(form_buffer_), string, GetSubstitute(0, mode0), | 
 |  695            GetSubstitute(1, mode1), GetSubstitute(2, mode2)); | 
 |  696   return form_buffer_; | 
 |  697 } | 
 |  698  | 
 |  699 const char* NEONFormatDecoder::Mnemonic(const char* mnemonic) { | 
 |  700   if ((instrbits_ & NEON_Q) != 0) { | 
 |  701     snprintf(mne_buffer_, sizeof(mne_buffer_), "%s2", mnemonic); | 
 |  702     return mne_buffer_; | 
 |  703   } | 
 |  704   return mnemonic; | 
 |  705 } | 
 |  706  | 
 |  707 VectorFormat NEONFormatDecoder::GetVectorFormat(int format_index) { | 
 |  708   return GetVectorFormat(formats_[format_index]); | 
 |  709 } | 
 |  710  | 
 |  711 VectorFormat NEONFormatDecoder::GetVectorFormat( | 
 |  712     const NEONFormatMap* format_map) { | 
 |  713   static const VectorFormat vform[] = { | 
 |  714       kFormatUndefined, kFormat8B, kFormat16B, kFormat4H, kFormat8H, | 
 |  715       kFormat2S,        kFormat4S, kFormat1D,  kFormat2D, kFormatB, | 
 |  716       kFormatH,         kFormatS,  kFormatD}; | 
 |  717   DCHECK_LT(GetNEONFormat(format_map), arraysize(vform)); | 
 |  718   return vform[GetNEONFormat(format_map)]; | 
 |  719 } | 
 |  720  | 
 |  721 const char* NEONFormatDecoder::GetSubstitute(int index, SubstitutionMode mode) { | 
 |  722   if (mode == kFormat) { | 
 |  723     return NEONFormatAsString(GetNEONFormat(formats_[index])); | 
 |  724   } | 
 |  725   DCHECK_EQ(mode, kPlaceholder); | 
 |  726   return NEONFormatAsPlaceholder(GetNEONFormat(formats_[index])); | 
 |  727 } | 
 |  728  | 
 |  729 NEONFormat NEONFormatDecoder::GetNEONFormat(const NEONFormatMap* format_map) { | 
 |  730   return format_map->map[PickBits(format_map->bits)]; | 
 |  731 } | 
 |  732  | 
 |  733 const char* NEONFormatDecoder::NEONFormatAsString(NEONFormat format) { | 
 |  734   static const char* formats[] = {"undefined", "8b", "16b", "4h", "8h", | 
 |  735                                   "2s",        "4s", "1d",  "2d", "b", | 
 |  736                                   "h",         "s",  "d"}; | 
 |  737   DCHECK_LT(format, arraysize(formats)); | 
 |  738   return formats[format]; | 
 |  739 } | 
 |  740  | 
 |  741 const char* NEONFormatDecoder::NEONFormatAsPlaceholder(NEONFormat format) { | 
 |  742   DCHECK((format == NF_B) || (format == NF_H) || (format == NF_S) || | 
 |  743          (format == NF_D) || (format == NF_UNDEF)); | 
 |  744   static const char* formats[] = { | 
 |  745       "undefined", "undefined", "undefined", "undefined", "undefined", | 
 |  746       "undefined", "undefined", "undefined", "undefined", "'B", | 
 |  747       "'H",        "'S",        "'D"}; | 
 |  748   return formats[format]; | 
 |  749 } | 
 |  750  | 
 |  751 uint8_t NEONFormatDecoder::PickBits(const uint8_t bits[]) { | 
 |  752   uint8_t result = 0; | 
 |  753   for (unsigned b = 0; b < kNEONFormatMaxBits; b++) { | 
 |  754     if (bits[b] == 0) break; | 
 |  755     result <<= 1; | 
 |  756     result |= ((instrbits_ & (1 << bits[b])) == 0) ? 0 : 1; | 
 |  757   } | 
 |  758   return result; | 
 |  759 } | 
|  338 }  // namespace internal |  760 }  // namespace internal | 
|  339 }  // namespace v8 |  761 }  // namespace v8 | 
|  340  |  762  | 
|  341 #endif  // V8_TARGET_ARCH_ARM64 |  763 #endif  // V8_TARGET_ARCH_ARM64 | 
| OLD | NEW |