@@ -1042,80 +1042,74 @@ class ReadCsrMicroOp extends MicroOp {
10421042 BitStruct ({'funct' : MicroOp .functRange, 'source' : const BitRange (5 , 8 )});
10431043}
10441044
1045- /// ---------------------------------------------------------------------------
1046- /// Operation / RiscVExtension / Microcode
1047- /// ---------------------------------------------------------------------------
1048-
10491045class OperationDecodePattern {
10501046 final int mask;
10511047 final int value;
10521048 final int opIndex;
1053- final Map <String , BitRange > nonZeroFields;
1049+ final int type;
1050+ final int nzfMask;
1051+ final int zfMask;
10541052
10551053 const OperationDecodePattern (
10561054 this .mask,
10571055 this .value,
10581056 this .opIndex,
1059- this .nonZeroFields,
1057+ this .type,
1058+ this .nzfMask,
1059+ this .zfMask,
10601060 );
10611061
1062- OperationDecodePattern .map (Map <String , int > m, Map < String , BitRange > fields )
1062+ OperationDecodePattern .map (Map <String , int > m)
10631063 : mask = m['mask' ]! ,
10641064 value = m['value' ]! ,
10651065 opIndex = m['opIndex' ]! ,
1066- nonZeroFields = Map .fromEntries (
1067- m.entries.where ((e) => e.key.startsWith ('nzf' )).map ((e) {
1068- final key = e.key.substring (3 );
1069- return MapEntry (key, fields[key]! );
1070- }),
1071- );
1066+ type = m['type' ]! ,
1067+ nzfMask = m['nzfMask' ]! ,
1068+ zfMask = m['zfMask' ]! ;
10721069
1073- OperationDecodePattern copyWith ({int ? opIndex}) => OperationDecodePattern (
1070+ OperationDecodePattern copyWith ({int ? opIndex, int ? type }) => OperationDecodePattern (
10741071 mask,
10751072 value,
10761073 opIndex ?? this .opIndex,
1077- nonZeroFields,
1074+ type ?? this .type,
1075+ nzfMask,
1076+ zfMask,
10781077 );
10791078
10801079 Map <String , int > toMap () => {
10811080 'mask' : mask,
10821081 'value' : value,
10831082 'opIndex' : opIndex,
1084- ...nonZeroFields.map ((k, _) => MapEntry ('nzf$k ' , 1 )),
1083+ 'type' : type,
1084+ 'nzfMask' : nzfMask,
1085+ 'zfMask' : zfMask,
10851086 };
10861087
1087- int encode (int opIndexWidth, Map <int , String > fields) =>
1088- struct (opIndexWidth, fields).encode (toMap ());
1088+ BigInt encode (int opIndexWidth, int typeWidth , Map <int , String > fields) =>
1089+ struct (opIndexWidth, typeWidth, fields).bigEncode (toMap ());
10891090
10901091 @override
10911092 String toString () =>
1092- 'OperationDecodePattern($mask , $value , $opIndex , $nonZeroFields )' ;
1093+ 'OperationDecodePattern($mask , $value , $opIndex , $type , $ nzfMask , $ zfMask )' ;
10931094
1094- static BitStruct struct (int opIndexWidth, Map <int , String > fields) {
1095+ static BitStruct struct (int opIndexWidth, int typeWidth, Map <int , String > fields) {
10951096 final mapping = < String , BitRange > {};
10961097 mapping['mask' ] = BitRange (0 , 31 );
10971098 mapping['value' ] = BitRange (32 , 63 );
10981099 mapping['opIndex' ] = BitRange (64 , 64 + opIndexWidth - 1 );
1099-
1100- var offset = 64 + opIndexWidth;
1101-
1102- final sortedFields = fields.entries.toList ()
1103- ..sort ((a, b) => a.key.compareTo (b.key));
1104- for (final field in sortedFields) {
1105- mapping['nzf${field .key }' ] = BitRange .single (offset++ );
1106- }
1107-
1100+ mapping['type' ] = BitRange (64 + opIndexWidth, 64 + opIndexWidth + typeWidth - 1 );
1101+ mapping['nzfMask' ] = BitRange (64 + opIndexWidth + typeWidth, 64 + opIndexWidth + typeWidth + 31 );
1102+ mapping['zfMask' ] = BitRange (64 + opIndexWidth + typeWidth + 32 , 64 + opIndexWidth + typeWidth + 32 + 31 );
11081103 return BitStruct (mapping);
11091104 }
11101105
11111106 static OperationDecodePattern decode (
11121107 int opIndexWidth,
1108+ int typeWidth,
11131109 Map <int , String > indices,
1114- Map <String , BitRange > ranges,
1115- int value,
1110+ BigInt value,
11161111 ) => OperationDecodePattern .map (
1117- struct (opIndexWidth, indices).decode (value),
1118- ranges,
1112+ struct (opIndexWidth, typeWidth, indices).bigDecode (value),
11191113 );
11201114}
11211115
@@ -1162,7 +1156,7 @@ class Operation<T extends InstructionType> {
11621156 return map;
11631157 }
11641158
1165- OperationDecodePattern decodePattern (int index) {
1159+ OperationDecodePattern decodePattern (int index, Map < String , int > typeMap ) {
11661160 var mask = 0 ;
11671161 var value = 0 ;
11681162
@@ -1193,32 +1187,31 @@ class Operation<T extends InstructionType> {
11931187
11941188 if (funct12 != null ) bind (struct.mapping['funct12' ]! , funct12);
11951189
1196- final nz = < String , BitRange > {};
1190+ int nzfMask = 0 ;
1191+
11971192 for (final f in nonZeroFields) {
11981193 if (! struct.mapping.containsKey (f)) {
11991194 throw '$mnemonic instruction does not have field $f ' ;
12001195 }
12011196
12021197 final r = struct.mapping[f]! ;
1203-
1204- final shiftedMask = r.mask << r.start;
1205- mask | = shiftedMask;
1206-
1207- final lsbBit = 1 << r.start;
1208- value | = lsbBit;
1209- nz[f] = r;
1198+ nzfMask | = (r.mask << r.start);
12101199 }
12111200
1201+ int zfMask = 0 ;
1202+
12121203 for (final f in zeroFields) {
12131204 if (! struct.mapping.containsKey (f)) {
12141205 throw '$mnemonic instruction does not have field $f ' ;
12151206 }
12161207
12171208 final r = struct.mapping[f]! ;
1218- mask | = (r.mask << r.start);
1209+ zfMask | = (r.mask << r.start);
12191210 }
12201211
1221- return OperationDecodePattern (mask, value, index, nz);
1212+ mask | = zfMask;
1213+
1214+ return OperationDecodePattern (mask, value, index, typeMap[Microcode .instrType (this )]! , nzfMask, zfMask);
12221215 }
12231216
12241217 bool _mapMatch (Map <String , int > map) {
@@ -1301,10 +1294,27 @@ class RiscVExtension {
13011294 return null ;
13021295 }
13031296
1304- Iterable <OperationDecodePattern > get decodePattern => operations
1305- .asMap ()
1306- .entries
1307- .map ((entry) => entry.value.decodePattern (entry.key));
1297+ Map <String , BitStruct > get typeStructs {
1298+ Map <String , BitStruct > result = {};
1299+ for (final op in operations) {
1300+ final t = Microcode .instrType (op);
1301+ if (result.containsKey (t)) continue ;
1302+ result[t] = op.struct;
1303+ }
1304+ return result;
1305+ }
1306+
1307+ Map <String , int > get typeMap => Map .fromEntries (typeStructs.entries.indexed.map ((e) => MapEntry (e.$2.key, e.$1)));
1308+
1309+ List <OperationDecodePattern > get decodePattern {
1310+ List <OperationDecodePattern > result = [];
1311+ var i = 0 ;
1312+ for (final op in operations) {
1313+ result.add (op.decodePattern (i, typeMap));
1314+ i += op.microcode.length + 1 ;
1315+ }
1316+ return result;
1317+ }
13081318
13091319 Map <OperationDecodePattern , Operation <InstructionType >> get decodeMap {
13101320 // NOTE: we probably should loop through the operations and patterns to ensure coherency.
@@ -1348,17 +1358,53 @@ class Microcode {
13481358
13491359 int get patternWidth => OperationDecodePattern .struct (
13501360 opIndices.length.bitLength,
1361+ typeStructs.length.bitLength,
13511362 fieldIndices,
13521363 ).width;
13531364
1365+ int get opIndexWidth => decodeLookup.keys
1366+ .fold (0 , (a, b) => a > b ? a : b);
1367+
13541368 int opWidth (Mxlen mxlen) => map.values
13551369 .map ((op) => op.microcodeWidth (mxlen))
13561370 .fold (0 , (a, b) => a > b ? a : b);
13571371
1358- List <int > get encodedPatterns {
1359- List <int > result = [];
1360- for (final pattern in map.keys) {
1361- result.add (pattern.encode (opIndices.length.bitLength, fieldIndices));
1372+ Map <int , OperationDecodePattern > get decodeLookup {
1373+ Map <int , OperationDecodePattern > result = {};
1374+ var i = 0 ;
1375+ for (final e in map.entries) {
1376+ result[i] = e.key.copyWith (opIndex: i);
1377+ i += e.value.microcode.length + 1 ;
1378+ }
1379+ return result;
1380+ }
1381+
1382+ Map <int , Operation <InstructionType >> get execLookup {
1383+ Map <int , Operation <InstructionType >> result = {};
1384+ var i = 0 ;
1385+ for (final op in map.values) {
1386+ result[i] = op;
1387+ i += op.microcode.length + 1 ;
1388+ }
1389+ return result;
1390+ }
1391+
1392+ Map <String , BitStruct > get typeStructs {
1393+ Map <String , BitStruct > result = {};
1394+ for (final op in map.values) {
1395+ final t = instrType (op);
1396+ if (result.containsKey (t)) continue ;
1397+ result[t] = op.struct;
1398+ }
1399+ return result;
1400+ }
1401+
1402+ Map <String , int > get typeMap => Map .fromEntries (typeStructs.entries.indexed.map ((e) => MapEntry (e.$2.key, e.$1)));
1403+
1404+ List <BigInt > get encodedPatterns {
1405+ List <BigInt > result = [];
1406+ for (final pattern in decodeLookup.values) {
1407+ result.add (pattern.encode (opIndices.length.bitLength, typeMap.length.bitLength, fieldIndices));
13621408 }
13631409 return result;
13641410 }
@@ -1480,14 +1526,9 @@ class Microcode {
14801526
14811527 Operation <InstructionType >? lookup (int instr) {
14821528 for (final entry in map.entries) {
1483- final decoded = entry.value.struct.decode (instr);
1484-
1485- for (final field in entry.key.nonZeroFields.keys) {
1486- decoded[field] = 1 ;
1487- }
1488-
1489- final temp = entry.value.struct.encode (decoded);
1490- if ((temp & entry.key.mask) == entry.key.value) {
1529+ final nzfMatch = entry.key.nzfMask == 0 || (instr & entry.key.nzfMask) != 0 ;
1530+ final zfMatch = entry.key.zfMask == 0 || (instr & entry.key.zfMask) == 0 ;
1531+ if ((instr & entry.key.mask) == entry.key.value && nzfMatch && zfMatch) {
14911532 return entry.value;
14921533 }
14931534 }
@@ -1521,11 +1562,13 @@ class Microcode {
15211562 List <RiscVExtension > extensions,
15221563 ) {
15231564 final list = < OperationDecodePattern > [];
1565+ var i = 0 ;
15241566 for (final ext in extensions) {
15251567 final patterns = ext.decodePattern;
15261568
1527- for (final pattern in patterns) {
1528- list.add (pattern.copyWith (opIndex: list.length));
1569+ for (final e in patterns.indexed) {
1570+ list.add (e.$2.copyWith (opIndex: i));
1571+ i += ext.operations[e.$1].microcode.length + 1 ;
15291572 }
15301573 }
15311574 return list;
@@ -1542,4 +1585,9 @@ class Microcode {
15421585 // NOTE: we probably should loop through the operations and patterns to ensure coherency.
15431586 return Map .fromIterables (patterns, operations);
15441587 }
1588+
1589+ static String instrType <T extends InstructionType >(Operation <T > i) {
1590+ final name = i.runtimeType.toString ();
1591+ return name.substring (10 , name.length - 1 );
1592+ }
15451593}
0 commit comments