Index: src/arm64/decoder-arm64-inl.h |
diff --git a/src/arm64/decoder-arm64-inl.h b/src/arm64/decoder-arm64-inl.h |
index 2405f8783000751dbc5f030772d36ff7486bfe6f..6718bd3d6899942216f547f51be6066b0d6f7d87 100644 |
--- a/src/arm64/decoder-arm64-inl.h |
+++ b/src/arm64/decoder-arm64-inl.h |
@@ -213,6 +213,11 @@ void Decoder<V>::DecodeLoadStore(Instruction* instr) { |
(instr->Bits(27, 24) == 0xC) || |
(instr->Bits(27, 24) == 0xD) ); |
+ if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) { |
+ DecodeNEONLoadStore(instr); |
+ return; |
+ } |
+ |
if (instr->Bit(24) == 0) { |
if (instr->Bit(28) == 0) { |
if (instr->Bit(29) == 0) { |
@@ -226,8 +231,6 @@ void Decoder<V>::DecodeLoadStore(Instruction* instr) { |
} else { |
V::VisitLoadStoreAcquireRelease(instr); |
} |
- } else { |
- DecodeAdvSIMDLoadStore(instr); |
} |
} else { |
if ((instr->Bits(31, 30) == 0x3) || |
@@ -513,16 +516,14 @@ void Decoder<V>::DecodeFP(Instruction* instr) { |
(instr->Bits(27, 24) == 0xF) ); |
if (instr->Bit(28) == 0) { |
- DecodeAdvSIMDDataProcessing(instr); |
+ DecodeNEONVectorDataProcessing(instr); |
} else { |
- if (instr->Bit(29) == 1) { |
+ if (instr->Bits(31, 30) == 0x3) { |
V::VisitUnallocated(instr); |
+ } else if (instr->Bits(31, 30) == 0x1) { |
+ DecodeNEONScalarDataProcessing(instr); |
} else { |
- if (instr->Bits(31, 30) == 0x3) { |
- V::VisitUnallocated(instr); |
- } else if (instr->Bits(31, 30) == 0x1) { |
- DecodeAdvSIMDDataProcessing(instr); |
- } else { |
+ if (instr->Bit(29) == 0) { |
if (instr->Bit(24) == 0) { |
if (instr->Bit(21) == 0) { |
if ((instr->Bit(23) == 1) || |
@@ -629,25 +630,190 @@ void Decoder<V>::DecodeFP(Instruction* instr) { |
V::VisitFPDataProcessing3Source(instr); |
} |
} |
+ } else { |
+ V::VisitUnallocated(instr); |
} |
} |
} |
} |
- |
-template<typename V> |
-void Decoder<V>::DecodeAdvSIMDLoadStore(Instruction* instr) { |
- // TODO(all): Implement Advanced SIMD load/store instruction decode. |
+template <typename V> |
+void Decoder<V>::DecodeNEONLoadStore(Instruction* instr) { |
DCHECK(instr->Bits(29, 25) == 0x6); |
- V::VisitUnimplemented(instr); |
+ if (instr->Bit(31) == 0) { |
+ if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) { |
+ V::VisitUnallocated(instr); |
+ return; |
+ } |
+ |
+ if (instr->Bit(23) == 0) { |
+ if (instr->Bits(20, 16) == 0) { |
+ if (instr->Bit(24) == 0) { |
+ V::VisitNEONLoadStoreMultiStruct(instr); |
+ } else { |
+ V::VisitNEONLoadStoreSingleStruct(instr); |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } else { |
+ if (instr->Bit(24) == 0) { |
+ V::VisitNEONLoadStoreMultiStructPostIndex(instr); |
+ } else { |
+ V::VisitNEONLoadStoreSingleStructPostIndex(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
} |
+template <typename V> |
+void Decoder<V>::DecodeNEONVectorDataProcessing(Instruction* instr) { |
+ DCHECK(instr->Bits(28, 25) == 0x7); |
+ if (instr->Bit(31) == 0) { |
+ if (instr->Bit(24) == 0) { |
+ if (instr->Bit(21) == 0) { |
+ if (instr->Bit(15) == 0) { |
+ if (instr->Bit(10) == 0) { |
+ if (instr->Bit(29) == 0) { |
+ if (instr->Bit(11) == 0) { |
+ V::VisitNEONTable(instr); |
+ } else { |
+ V::VisitNEONPerm(instr); |
+ } |
+ } else { |
+ V::VisitNEONExtract(instr); |
+ } |
+ } else { |
+ if (instr->Bits(23, 22) == 0) { |
+ V::VisitNEONCopy(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } else { |
+ if (instr->Bit(10) == 0) { |
+ if (instr->Bit(11) == 0) { |
+ V::VisitNEON3Different(instr); |
+ } else { |
+ if (instr->Bits(18, 17) == 0) { |
+ if (instr->Bit(20) == 0) { |
+ if (instr->Bit(19) == 0) { |
+ V::VisitNEON2RegMisc(instr); |
+ } else { |
+ if (instr->Bits(30, 29) == 0x2) { |
+ V::VisitUnallocated(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ if (instr->Bit(19) == 0) { |
+ V::VisitNEONAcrossLanes(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitNEON3Same(instr); |
+ } |
+ } |
+ } else { |
+ if (instr->Bit(10) == 0) { |
+ V::VisitNEONByIndexedElement(instr); |
+ } else { |
+ if (instr->Bit(23) == 0) { |
+ if (instr->Bits(22, 19) == 0) { |
+ V::VisitNEONModifiedImmediate(instr); |
+ } else { |
+ V::VisitNEONShiftImmediate(instr); |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+} |
-template<typename V> |
-void Decoder<V>::DecodeAdvSIMDDataProcessing(Instruction* instr) { |
- // TODO(all): Implement Advanced SIMD data processing instruction decode. |
- DCHECK(instr->Bits(27, 25) == 0x7); |
- V::VisitUnimplemented(instr); |
+template <typename V> |
+void Decoder<V>::DecodeNEONScalarDataProcessing(Instruction* instr) { |
+ DCHECK(instr->Bits(28, 25) == 0xF); |
+ if (instr->Bit(24) == 0) { |
+ if (instr->Bit(21) == 0) { |
+ if (instr->Bit(15) == 0) { |
+ if (instr->Bit(10) == 0) { |
+ if (instr->Bit(29) == 0) { |
+ if (instr->Bit(11) == 0) { |
+ V::VisitUnallocated(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } else { |
+ if (instr->Bits(23, 22) == 0) { |
+ V::VisitNEONScalarCopy(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } else { |
+ if (instr->Bit(10) == 0) { |
+ if (instr->Bit(11) == 0) { |
+ V::VisitNEONScalar3Diff(instr); |
+ } else { |
+ if (instr->Bits(18, 17) == 0) { |
+ if (instr->Bit(20) == 0) { |
+ if (instr->Bit(19) == 0) { |
+ V::VisitNEONScalar2RegMisc(instr); |
+ } else { |
+ if (instr->Bit(29) == 0) { |
+ V::VisitUnallocated(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ if (instr->Bit(19) == 0) { |
+ V::VisitNEONScalarPairwise(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } else { |
+ V::VisitNEONScalar3Same(instr); |
+ } |
+ } |
+ } else { |
+ if (instr->Bit(10) == 0) { |
+ V::VisitNEONScalarByIndexedElement(instr); |
+ } else { |
+ if (instr->Bit(23) == 0) { |
+ V::VisitNEONScalarShiftImmediate(instr); |
+ } else { |
+ V::VisitUnallocated(instr); |
+ } |
+ } |
+ } |
} |