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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: src/arm64/instructions-arm64.cc
diff --git a/src/arm64/instructions-arm64.cc b/src/arm64/instructions-arm64.cc
index d23533d8bc7ce629cea809867d1eaa71e0179308..da16826eb2987fe7244e3702a8b27536af676b6d 100644
--- a/src/arm64/instructions-arm64.cc
+++ b/src/arm64/instructions-arm64.cc
@@ -21,7 +21,7 @@ bool Instruction::IsLoad() const {
if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) {
return Mask(LoadStorePairLBit) != 0;
} else {
- LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask));
+ LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask));
switch (op) {
case LDRB_w:
case LDRH_w:
@@ -32,8 +32,12 @@ bool Instruction::IsLoad() const {
case LDRSH_w:
case LDRSH_x:
case LDRSW_x:
+ case LDR_b:
+ case LDR_h:
case LDR_s:
- case LDR_d: return true;
+ case LDR_d:
+ case LDR_q:
+ return true;
default: return false;
}
}
@@ -48,14 +52,18 @@ bool Instruction::IsStore() const {
if (Mask(LoadStorePairAnyFMask) == LoadStorePairAnyFixed) {
return Mask(LoadStorePairLBit) == 0;
} else {
- LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreOpMask));
+ LoadStoreOp op = static_cast<LoadStoreOp>(Mask(LoadStoreMask));
switch (op) {
case STRB_w:
case STRH_w:
case STR_w:
case STR_x:
+ case STR_b:
+ case STR_h:
case STR_s:
- case STR_d: return true;
+ case STR_d:
+ case STR_q:
+ return true;
default: return false;
}
}
@@ -139,43 +147,48 @@ uint64_t Instruction::ImmLogical() {
return 0;
}
-
-float Instruction::ImmFP32() {
- // ImmFP: abcdefgh (8 bits)
- // Single: aBbb.bbbc.defg.h000.0000.0000.0000.0000 (32 bits)
- // where B is b ^ 1
- uint32_t bits = ImmFP();
- uint32_t bit7 = (bits >> 7) & 0x1;
- uint32_t bit6 = (bits >> 6) & 0x1;
- uint32_t bit5_to_0 = bits & 0x3f;
- uint32_t result = (bit7 << 31) | ((32 - bit6) << 25) | (bit5_to_0 << 19);
-
- return rawbits_to_float(result);
+uint32_t Instruction::ImmNEONabcdefgh() const {
+ return ImmNEONabc() << 5 | ImmNEONdefgh();
}
+float Instruction::ImmFP32() { return Imm8ToFP32(ImmFP()); }
-double Instruction::ImmFP64() {
- // ImmFP: abcdefgh (8 bits)
- // Double: aBbb.bbbb.bbcd.efgh.0000.0000.0000.0000
- // 0000.0000.0000.0000.0000.0000.0000.0000 (64 bits)
- // where B is b ^ 1
- uint32_t bits = ImmFP();
- uint64_t bit7 = (bits >> 7) & 0x1;
- uint64_t bit6 = (bits >> 6) & 0x1;
- uint64_t bit5_to_0 = bits & 0x3f;
- uint64_t result = (bit7 << 63) | ((256 - bit6) << 54) | (bit5_to_0 << 48);
+double Instruction::ImmFP64() { return Imm8ToFP64(ImmFP()); }
- return rawbits_to_double(result);
+float Instruction::ImmNEONFP32() const { return Imm8ToFP32(ImmNEONabcdefgh()); }
+
+double Instruction::ImmNEONFP64() const {
+ return Imm8ToFP64(ImmNEONabcdefgh());
}
+unsigned CalcLSDataSize(LoadStoreOp op) {
+ DCHECK_EQ(static_cast<unsigned>(LSSize_offset + LSSize_width),
+ kInstructionSize * 8);
+ unsigned size = static_cast<Instr>(op) >> LSSize_offset;
+ if ((op & LSVector_mask) != 0) {
+ // Vector register memory operations encode the access size in the "size"
+ // and "opc" fields.
+ if ((size == 0) && ((op & LSOpc_mask) >> LSOpc_offset) >= 2) {
+ size = kQRegSizeLog2;
+ }
+ }
+ return size;
+}
-LSDataSize CalcLSPairDataSize(LoadStorePairOp op) {
+unsigned CalcLSPairDataSize(LoadStorePairOp op) {
+ static_assert(kXRegSize == kDRegSize, "X and D registers must be same size.");
+ static_assert(kWRegSize == kSRegSize, "W and S registers must be same size.");
switch (op) {
+ case STP_q:
+ case LDP_q:
+ return kQRegSizeLog2;
case STP_x:
case LDP_x:
case STP_d:
- case LDP_d: return LSDoubleWord;
- default: return LSWord;
+ case LDP_d:
+ return kXRegSizeLog2;
+ default:
+ return kWRegSizeLog2;
}
}
@@ -335,7 +348,299 @@ uint64_t InstructionSequence::InlineData() const {
return payload;
}
+VectorFormat VectorFormatHalfWidth(VectorFormat vform) {
+ DCHECK(vform == kFormat8H || vform == kFormat4S || vform == kFormat2D ||
+ vform == kFormatH || vform == kFormatS || vform == kFormatD);
+ switch (vform) {
+ case kFormat8H:
+ return kFormat8B;
+ case kFormat4S:
+ return kFormat4H;
+ case kFormat2D:
+ return kFormat2S;
+ case kFormatH:
+ return kFormatB;
+ case kFormatS:
+ return kFormatH;
+ case kFormatD:
+ return kFormatS;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat VectorFormatDoubleWidth(VectorFormat vform) {
+ DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S ||
+ vform == kFormatB || vform == kFormatH || vform == kFormatS);
+ switch (vform) {
+ case kFormat8B:
+ return kFormat8H;
+ case kFormat4H:
+ return kFormat4S;
+ case kFormat2S:
+ return kFormat2D;
+ case kFormatB:
+ return kFormatH;
+ case kFormatH:
+ return kFormatS;
+ case kFormatS:
+ return kFormatD;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat VectorFormatFillQ(VectorFormat vform) {
+ switch (vform) {
+ case kFormatB:
+ case kFormat8B:
+ case kFormat16B:
+ return kFormat16B;
+ case kFormatH:
+ case kFormat4H:
+ case kFormat8H:
+ return kFormat8H;
+ case kFormatS:
+ case kFormat2S:
+ case kFormat4S:
+ return kFormat4S;
+ case kFormatD:
+ case kFormat1D:
+ case kFormat2D:
+ return kFormat2D;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat VectorFormatHalfWidthDoubleLanes(VectorFormat vform) {
+ switch (vform) {
+ case kFormat4H:
+ return kFormat8B;
+ case kFormat8H:
+ return kFormat16B;
+ case kFormat2S:
+ return kFormat4H;
+ case kFormat4S:
+ return kFormat8H;
+ case kFormat1D:
+ return kFormat2S;
+ case kFormat2D:
+ return kFormat4S;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat VectorFormatDoubleLanes(VectorFormat vform) {
+ DCHECK(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S);
+ switch (vform) {
+ case kFormat8B:
+ return kFormat16B;
+ case kFormat4H:
+ return kFormat8H;
+ case kFormat2S:
+ return kFormat4S;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat VectorFormatHalfLanes(VectorFormat vform) {
+ DCHECK(vform == kFormat16B || vform == kFormat8H || vform == kFormat4S);
+ switch (vform) {
+ case kFormat16B:
+ return kFormat8B;
+ case kFormat8H:
+ return kFormat4H;
+ case kFormat4S:
+ return kFormat2S;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat ScalarFormatFromLaneSize(int laneSize) {
+ switch (laneSize) {
+ case 8:
+ return kFormatB;
+ case 16:
+ return kFormatH;
+ case 32:
+ return kFormatS;
+ case 64:
+ return kFormatD;
+ default:
+ UNREACHABLE();
+ return kFormatUndefined;
+ }
+}
+
+VectorFormat ScalarFormatFromFormat(VectorFormat vform) {
+ return ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
+}
+
+unsigned RegisterSizeInBytesFromFormat(VectorFormat vform) {
+ return RegisterSizeInBitsFromFormat(vform) / 8;
+}
+
+unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormatB:
+ return kBRegSizeInBits;
+ case kFormatH:
+ return kHRegSizeInBits;
+ case kFormatS:
+ return kSRegSizeInBits;
+ case kFormatD:
+ return kDRegSizeInBits;
+ case kFormat8B:
+ case kFormat4H:
+ case kFormat2S:
+ case kFormat1D:
+ return kDRegSizeInBits;
+ default:
+ return kQRegSizeInBits;
+ }
+}
+
+unsigned LaneSizeInBitsFromFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormatB:
+ case kFormat8B:
+ case kFormat16B:
+ return 8;
+ case kFormatH:
+ case kFormat4H:
+ case kFormat8H:
+ return 16;
+ case kFormatS:
+ case kFormat2S:
+ case kFormat4S:
+ return 32;
+ case kFormatD:
+ case kFormat1D:
+ case kFormat2D:
+ return 64;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int LaneSizeInBytesFromFormat(VectorFormat vform) {
+ return LaneSizeInBitsFromFormat(vform) / 8;
+}
+
+int LaneSizeInBytesLog2FromFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormatB:
+ case kFormat8B:
+ case kFormat16B:
+ return 0;
+ case kFormatH:
+ case kFormat4H:
+ case kFormat8H:
+ return 1;
+ case kFormatS:
+ case kFormat2S:
+ case kFormat4S:
+ return 2;
+ case kFormatD:
+ case kFormat1D:
+ case kFormat2D:
+ return 3;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int LaneCountFromFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormat16B:
+ return 16;
+ case kFormat8B:
+ case kFormat8H:
+ return 8;
+ case kFormat4H:
+ case kFormat4S:
+ return 4;
+ case kFormat2S:
+ case kFormat2D:
+ return 2;
+ case kFormat1D:
+ case kFormatB:
+ case kFormatH:
+ case kFormatS:
+ case kFormatD:
+ return 1;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int MaxLaneCountFromFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormatB:
+ case kFormat8B:
+ case kFormat16B:
+ return 16;
+ case kFormatH:
+ case kFormat4H:
+ case kFormat8H:
+ return 8;
+ case kFormatS:
+ case kFormat2S:
+ case kFormat4S:
+ return 4;
+ case kFormatD:
+ case kFormat1D:
+ case kFormat2D:
+ return 2;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+// Does 'vform' indicate a vector format or a scalar format?
+bool IsVectorFormat(VectorFormat vform) {
+ DCHECK_NE(vform, kFormatUndefined);
+ switch (vform) {
+ case kFormatB:
+ case kFormatH:
+ case kFormatS:
+ case kFormatD:
+ return false;
+ default:
+ return true;
+ }
+}
+
+int64_t MaxIntFromFormat(VectorFormat vform) {
+ return INT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform));
+}
+
+int64_t MinIntFromFormat(VectorFormat vform) {
+ return INT64_MIN >> (64 - LaneSizeInBitsFromFormat(vform));
+}
+
+uint64_t MaxUintFromFormat(VectorFormat vform) {
+ return UINT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform));
+}
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698