@@ -223,7 +223,7 @@ class InstructionEncoding {
223
223
224
224
private:
225
225
void parseVarLenEncoding (const VarLenInst &VLI);
226
- void parseFixedLenEncoding (const BitsInit &Bits );
226
+ void parseFixedLenEncoding (const BitsInit &RecordInstBits );
227
227
228
228
void parseVarLenOperands (const VarLenInst &VLI);
229
229
void parseFixedLenOperands (const BitsInit &Bits);
@@ -1772,12 +1772,51 @@ void InstructionEncoding::parseVarLenEncoding(const VarLenInst &VLI) {
1772
1772
assert (I == VLI.size ());
1773
1773
}
1774
1774
1775
- void InstructionEncoding::parseFixedLenEncoding (const BitsInit &Bits) {
1776
- InstBits = KnownBits (Bits.getNumBits ());
1777
- SoftFailBits = APInt (Bits.getNumBits (), 0 );
1775
+ void InstructionEncoding::parseFixedLenEncoding (
1776
+ const BitsInit &RecordInstBits) {
1777
+ // For fixed length instructions, sometimes the `Inst` field specifies more
1778
+ // bits than the actual size of the instruction, which is specified in `Size`.
1779
+ // In such cases, we do some basic validation and drop the upper bits.
1780
+ unsigned BitWidth = EncodingDef->getValueAsInt (" Size" ) * 8 ;
1781
+ unsigned InstNumBits = RecordInstBits.getNumBits ();
1782
+
1783
+ // Returns true if all bits in `Bits` are zero or unset.
1784
+ auto CheckAllZeroOrUnset = [&](ArrayRef<const Init *> Bits,
1785
+ const RecordVal *Field) {
1786
+ bool AllZeroOrUnset = llvm::all_of (Bits, [](const Init *Bit) {
1787
+ if (const auto *BI = dyn_cast<BitInit>(Bit))
1788
+ return !BI->getValue ();
1789
+ return isa<UnsetInit>(Bit);
1790
+ });
1791
+ if (AllZeroOrUnset)
1792
+ return ;
1793
+ PrintNote ([Field](raw_ostream &OS) { Field->print (OS); });
1794
+ PrintFatalError (EncodingDef, Twine (Name) + " : Size is " + Twine (BitWidth) +
1795
+ " bits, but " + Field->getName () +
1796
+ " bits beyond that are not zero/unset" );
1797
+ };
1798
+
1799
+ if (InstNumBits < BitWidth)
1800
+ PrintFatalError (EncodingDef, Twine (Name) + " : Size is " + Twine (BitWidth) +
1801
+ " bits, but Inst specifies only " +
1802
+ Twine (InstNumBits) + " bits" );
1803
+
1804
+ if (InstNumBits > BitWidth) {
1805
+ // Ensure that all the bits beyond 'Size' are 0 or unset (i.e., carry no
1806
+ // actual encoding).
1807
+ ArrayRef<const Init *> UpperBits =
1808
+ RecordInstBits.getBits ().drop_front (BitWidth);
1809
+ const RecordVal *InstField = EncodingDef->getValue (" Inst" );
1810
+ CheckAllZeroOrUnset (UpperBits, InstField);
1811
+ }
1812
+
1813
+ ArrayRef<const Init *> ActiveInstBits =
1814
+ RecordInstBits.getBits ().take_front (BitWidth);
1815
+ InstBits = KnownBits (BitWidth);
1816
+ SoftFailBits = APInt (BitWidth, 0 );
1778
1817
1779
1818
// Parse Inst field.
1780
- for (auto [I, V] : enumerate(Bits. getBits () )) {
1819
+ for (auto [I, V] : enumerate(ActiveInstBits )) {
1781
1820
if (const auto *B = dyn_cast<BitInit>(V)) {
1782
1821
if (B->getValue ())
1783
1822
InstBits.One .setBit (I);
@@ -1787,26 +1826,36 @@ void InstructionEncoding::parseFixedLenEncoding(const BitsInit &Bits) {
1787
1826
}
1788
1827
1789
1828
// Parse SoftFail field.
1790
- if (const RecordVal *SoftFailField = EncodingDef->getValue (" SoftFail" )) {
1791
- const auto *SFBits = dyn_cast<BitsInit>(SoftFailField->getValue ());
1792
- if (!SFBits || SFBits->getNumBits () != Bits.getNumBits ()) {
1793
- PrintNote (EncodingDef->getLoc (), " in record" );
1794
- PrintFatalError (SoftFailField,
1795
- formatv (" SoftFail field, if defined, must be "
1796
- " of the same type as Inst, which is bits<{}>" ,
1797
- Bits.getNumBits ()));
1798
- }
1799
- for (auto [I, V] : enumerate(SFBits->getBits ())) {
1800
- if (const auto *B = dyn_cast<BitInit>(V); B && B->getValue ()) {
1801
- if (!InstBits.Zero [I] && !InstBits.One [I]) {
1802
- PrintNote (EncodingDef->getLoc (), " in record" );
1803
- PrintError (SoftFailField,
1804
- formatv (" SoftFail{{{0}} = 1 requires Inst{{{0}} "
1805
- " to be fully defined (0 or 1, not '?')" ,
1806
- I));
1807
- }
1808
- SoftFailBits.setBit (I);
1829
+ const RecordVal *SoftFailField = EncodingDef->getValue (" SoftFail" );
1830
+ if (!SoftFailField)
1831
+ return ;
1832
+
1833
+ const auto *SFBits = dyn_cast<BitsInit>(SoftFailField->getValue ());
1834
+ if (!SFBits || SFBits->getNumBits () != InstNumBits) {
1835
+ PrintNote (EncodingDef->getLoc (), " in record" );
1836
+ PrintFatalError (SoftFailField,
1837
+ formatv (" SoftFail field, if defined, must be "
1838
+ " of the same type as Inst, which is bits<{}>" ,
1839
+ InstNumBits));
1840
+ }
1841
+
1842
+ if (InstNumBits > BitWidth) {
1843
+ // Ensure that all upper bits of `SoftFail` are 0 or unset.
1844
+ ArrayRef<const Init *> UpperBits = SFBits->getBits ().drop_front (BitWidth);
1845
+ CheckAllZeroOrUnset (UpperBits, SoftFailField);
1846
+ }
1847
+
1848
+ ArrayRef<const Init *> ActiveSFBits = SFBits->getBits ().take_front (BitWidth);
1849
+ for (auto [I, V] : enumerate(ActiveSFBits)) {
1850
+ if (const auto *B = dyn_cast<BitInit>(V); B && B->getValue ()) {
1851
+ if (!InstBits.Zero [I] && !InstBits.One [I]) {
1852
+ PrintNote (EncodingDef->getLoc (), " in record" );
1853
+ PrintError (SoftFailField,
1854
+ formatv (" SoftFail{{{0}} = 1 requires Inst{{{0}} "
1855
+ " to be fully defined (0 or 1, not '?')" ,
1856
+ I));
1809
1857
}
1858
+ SoftFailBits.setBit (I);
1810
1859
}
1811
1860
}
1812
1861
}
0 commit comments