@@ -1787,12 +1787,51 @@ void InstructionEncoding::parseVarLenEncoding(const VarLenInst &VLI) {
17871787 assert (I == VLI.size ());
17881788}
17891789
1790- void InstructionEncoding::parseFixedLenEncoding (const BitsInit &Bits) {
1791- InstBits = KnownBits (Bits.getNumBits ());
1792- SoftFailBits = APInt (Bits.getNumBits (), 0 );
1790+ void InstructionEncoding::parseFixedLenEncoding (const BitsInit &InstBits) {
1791+ // For fixed length instructions, sometimes the `Inst` field specifies more
1792+ // bits than the actual size of the instruction, which is specified in `Size`.
1793+ // In such cases, we do some basic validation and drop the upper bits.
1794+ unsigned BitWidth = EncodingDef->getValueAsInt (" Size" ) * 8 ;
1795+ unsigned InstNumBits = InstBits.getNumBits ();
1796+
1797+ // Returns true if all bits in `Bits` are zero or unset.
1798+ auto CheckAllZeroOrUnset = [&](ArrayRef<const Init *> Bits, const RecordVal *Field) {
1799+ bool AllZeroOrUnset = llvm::all_of (Bits, [](const Init *Bit) {
1800+ if (const auto *BI = dyn_cast<BitInit>(Bit))
1801+ return !BI->getValue ();
1802+ return isa<UnsetInit>(Bit);
1803+ });
1804+ if (AllZeroOrUnset)
1805+ return ;
1806+ PrintNote ([Field](raw_ostream &OS) {
1807+ Field->print (OS);
1808+ });
1809+ PrintFatalError (
1810+ EncodingDef,
1811+ Twine (Name) + " : Size is " + Twine (BitWidth) +
1812+ " bits, but " + Field->getName () + " bits beyond that are not zero/unset" );
1813+ };
1814+
1815+ if (InstNumBits < BitWidth)
1816+ PrintFatalError (EncodingDef, Twine (Name) + " : Size is " +
1817+ Twine (BitWidth) +
1818+ " bits, but Inst specifies only " +
1819+ Twine (InstNumBits) + " bits" );
1820+
1821+ if (InstNumBits > BitWidth) {
1822+ // Ensure that all the bits beyond 'Size' are 0 or unset (i.e., carry no
1823+ // actual encoding).
1824+ ArrayRef<const Init *> UpperBits = InstBits.getBits ().drop_front (BitWidth);
1825+ const RecordVal *InstField = EncodingDef->getValue (" Inst" );
1826+ CheckAllZeroOrUnset (UpperBits, InstField);
1827+ }
1828+
1829+ ArrayRef<const Init *> ActiveInstBits = InstBits.getBits ().take_front (BitWidth);
1830+ InstBits = KnownBits (BitWidth);
1831+ SoftFailBits = APInt (BitWidth, 0 );
17931832
17941833 // Parse Inst field.
1795- for (auto [I, V] : enumerate(Bits. getBits () )) {
1834+ for (auto [I, V] : enumerate(ActiveInstBits )) {
17961835 if (const auto *B = dyn_cast<BitInit>(V)) {
17971836 if (B->getValue ())
17981837 InstBits.One .setBit (I);
@@ -1802,26 +1841,36 @@ void InstructionEncoding::parseFixedLenEncoding(const BitsInit &Bits) {
18021841 }
18031842
18041843 // Parse SoftFail field.
1805- if (const RecordVal *SoftFailField = EncodingDef->getValue (" SoftFail" )) {
1806- const auto *SFBits = dyn_cast<BitsInit>(SoftFailField->getValue ());
1807- if (!SFBits || SFBits->getNumBits () != Bits.getNumBits ()) {
1808- PrintNote (EncodingDef->getLoc (), " in record" );
1809- PrintFatalError (SoftFailField,
1810- formatv (" SoftFail field, if defined, must be "
1811- " of the same type as Inst, which is bits<{}>" ,
1812- Bits.getNumBits ()));
1813- }
1814- for (auto [I, V] : enumerate(SFBits->getBits ())) {
1815- if (const auto *B = dyn_cast<BitInit>(V); B && B->getValue ()) {
1816- if (!InstBits.Zero [I] && !InstBits.One [I]) {
1817- PrintNote (EncodingDef->getLoc (), " in record" );
1818- PrintError (SoftFailField,
1819- formatv (" SoftFail{{{0}} = 1 requires Inst{{{0}} "
1820- " to be fully defined (0 or 1, not '?')" ,
1821- I));
1822- }
1823- SoftFailBits.setBit (I);
1844+ const RecordVal *SoftFailField = EncodingDef->getValue (" SoftFail" );
1845+ if (!SoftFailField)
1846+ return ;
1847+
1848+ const auto *SFBits = dyn_cast<BitsInit>(SoftFailField->getValue ());
1849+ if (!SFBits || SFBits->getNumBits () != Bits.getNumBits ()) {
1850+ PrintNote (EncodingDef->getLoc (), " in record" );
1851+ PrintFatalError (SoftFailField,
1852+ formatv (" SoftFail field, if defined, must be "
1853+ " of the same type as Inst, which is bits<{}>" ,
1854+ Bits.getNumBits ()));
1855+ }
1856+
1857+ if (InstNumBits > BitWidth) {
1858+ // Ensure that all upper bits of `SoftFail` are 0 or unset.
1859+ ArrayRef<const Init *> UpperBits = SFBits->getBits ().drop_front (BitWidth);
1860+ CheckAllZeroOrUnset (UpperBits, SoftFailField);
1861+ }
1862+
1863+ ArrayRef<const Init *> ActiveSFBits = SFBits->getBits ().take_front (BitWidth);
1864+ for (auto [I, V] : enumerate(ActiveSFBits)) {
1865+ if (const auto *B = dyn_cast<BitInit>(V); B && B->getValue ()) {
1866+ if (!InstBits.Zero [I] && !InstBits.One [I]) {
1867+ PrintNote (EncodingDef->getLoc (), " in record" );
1868+ PrintError (SoftFailField,
1869+ formatv (" SoftFail{{{0}} = 1 requires Inst{{{0}} "
1870+ " to be fully defined (0 or 1, not '?')" ,
1871+ I));
18241872 }
1873+ SoftFailBits.setBit (I);
18251874 }
18261875 }
18271876}
0 commit comments