@@ -223,7 +223,7 @@ class InstructionEncoding {
223223
224224private:
225225 void parseVarLenEncoding (const VarLenInst &VLI);
226- void parseFixedLenEncoding (const BitsInit &Bits );
226+ void parseFixedLenEncoding (const BitsInit &RecordInstBits );
227227
228228 void parseVarLenOperands (const VarLenInst &VLI);
229229 void parseFixedLenOperands (const BitsInit &Bits);
@@ -1772,12 +1772,51 @@ void InstructionEncoding::parseVarLenEncoding(const VarLenInst &VLI) {
17721772 assert (I == VLI.size ());
17731773}
17741774
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 );
17781817
17791818 // Parse Inst field.
1780- for (auto [I, V] : enumerate(Bits. getBits () )) {
1819+ for (auto [I, V] : enumerate(ActiveInstBits )) {
17811820 if (const auto *B = dyn_cast<BitInit>(V)) {
17821821 if (B->getValue ())
17831822 InstBits.One .setBit (I);
@@ -1787,26 +1826,36 @@ void InstructionEncoding::parseFixedLenEncoding(const BitsInit &Bits) {
17871826 }
17881827
17891828 // 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));
18091857 }
1858+ SoftFailBits.setBit (I);
18101859 }
18111860 }
18121861}
0 commit comments