@@ -1042,80 +1042,88 @@ 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- }),
1066+ type = m['type' ]! ,
1067+ nzfMask = m['nzfMask' ]! ,
1068+ zfMask = m['zfMask' ]! ;
1069+
1070+ OperationDecodePattern copyWith ({int ? opIndex, int ? type}) =>
1071+ OperationDecodePattern (
1072+ mask,
1073+ value,
1074+ opIndex ?? this .opIndex,
1075+ type ?? this .type,
1076+ nzfMask,
1077+ zfMask,
10711078 );
10721079
1073- OperationDecodePattern copyWith ({int ? opIndex}) => OperationDecodePattern (
1074- mask,
1075- value,
1076- opIndex ?? this .opIndex,
1077- nonZeroFields,
1078- );
1079-
10801080 Map <String , int > toMap () => {
10811081 'mask' : mask,
10821082 'value' : value,
10831083 'opIndex' : opIndex,
1084- ...nonZeroFields.map ((k, _) => MapEntry ('nzf$k ' , 1 )),
1084+ 'type' : type,
1085+ 'nzfMask' : nzfMask,
1086+ 'zfMask' : zfMask,
10851087 };
10861088
1087- int encode (int opIndexWidth, Map <int , String > fields) =>
1088- struct (opIndexWidth, fields).encode (toMap ());
1089+ BigInt encode (int opIndexWidth, int typeWidth , Map <int , String > fields) =>
1090+ struct (opIndexWidth, typeWidth, fields).bigEncode (toMap ());
10891091
10901092 @override
10911093 String toString () =>
1092- 'OperationDecodePattern($mask , $value , $opIndex , $nonZeroFields )' ;
1094+ 'OperationDecodePattern($mask , $value , $opIndex , $type , $ nzfMask , $ zfMask )' ;
10931095
1094- static BitStruct struct (int opIndexWidth, Map <int , String > fields) {
1096+ static BitStruct struct (
1097+ int opIndexWidth,
1098+ int typeWidth,
1099+ Map <int , String > fields,
1100+ ) {
10951101 final mapping = < String , BitRange > {};
10961102 mapping['mask' ] = BitRange (0 , 31 );
10971103 mapping['value' ] = BitRange (32 , 63 );
10981104 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-
1105+ mapping['type' ] = BitRange (
1106+ 64 + opIndexWidth,
1107+ 64 + opIndexWidth + typeWidth - 1 ,
1108+ );
1109+ mapping['nzfMask' ] = BitRange (
1110+ 64 + opIndexWidth + typeWidth,
1111+ 64 + opIndexWidth + typeWidth + 31 ,
1112+ );
1113+ mapping['zfMask' ] = BitRange (
1114+ 64 + opIndexWidth + typeWidth + 32 ,
1115+ 64 + opIndexWidth + typeWidth + 32 + 31 ,
1116+ );
11081117 return BitStruct (mapping);
11091118 }
11101119
11111120 static OperationDecodePattern decode (
11121121 int opIndexWidth,
1122+ int typeWidth,
11131123 Map <int , String > indices,
1114- Map <String , BitRange > ranges,
1115- int value,
1124+ BigInt value,
11161125 ) => OperationDecodePattern .map (
1117- struct (opIndexWidth, indices).decode (value),
1118- ranges,
1126+ struct (opIndexWidth, typeWidth, indices).bigDecode (value),
11191127 );
11201128}
11211129
@@ -1162,7 +1170,7 @@ class Operation<T extends InstructionType> {
11621170 return map;
11631171 }
11641172
1165- OperationDecodePattern decodePattern (int index) {
1173+ OperationDecodePattern decodePattern (int index, Map < String , int > typeMap ) {
11661174 var mask = 0 ;
11671175 var value = 0 ;
11681176
@@ -1193,32 +1201,38 @@ class Operation<T extends InstructionType> {
11931201
11941202 if (funct12 != null ) bind (struct.mapping['funct12' ]! , funct12);
11951203
1196- final nz = < String , BitRange > {};
1204+ int nzfMask = 0 ;
1205+
11971206 for (final f in nonZeroFields) {
11981207 if (! struct.mapping.containsKey (f)) {
11991208 throw '$mnemonic instruction does not have field $f ' ;
12001209 }
12011210
12021211 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;
1212+ nzfMask | = (r.mask << r.start);
12101213 }
12111214
1215+ int zfMask = 0 ;
1216+
12121217 for (final f in zeroFields) {
12131218 if (! struct.mapping.containsKey (f)) {
12141219 throw '$mnemonic instruction does not have field $f ' ;
12151220 }
12161221
12171222 final r = struct.mapping[f]! ;
1218- mask | = (r.mask << r.start);
1223+ zfMask | = (r.mask << r.start);
12191224 }
12201225
1221- return OperationDecodePattern (mask, value, index, nz);
1226+ mask | = zfMask;
1227+
1228+ return OperationDecodePattern (
1229+ mask,
1230+ value,
1231+ index,
1232+ typeMap[Microcode .instrType (this )]! ,
1233+ nzfMask,
1234+ zfMask,
1235+ );
12221236 }
12231237
12241238 bool _mapMatch (Map <String , int > map) {
@@ -1301,10 +1315,29 @@ class RiscVExtension {
13011315 return null ;
13021316 }
13031317
1304- Iterable <OperationDecodePattern > get decodePattern => operations
1305- .asMap ()
1306- .entries
1307- .map ((entry) => entry.value.decodePattern (entry.key));
1318+ Map <String , BitStruct > get typeStructs {
1319+ Map <String , BitStruct > result = {};
1320+ for (final op in operations) {
1321+ final t = Microcode .instrType (op);
1322+ if (result.containsKey (t)) continue ;
1323+ result[t] = op.struct;
1324+ }
1325+ return result;
1326+ }
1327+
1328+ Map <String , int > get typeMap => Map .fromEntries (
1329+ typeStructs.entries.indexed.map ((e) => MapEntry (e.$2.key, e.$1)),
1330+ );
1331+
1332+ List <OperationDecodePattern > get decodePattern {
1333+ List <OperationDecodePattern > result = [];
1334+ var i = 0 ;
1335+ for (final op in operations) {
1336+ result.add (op.decodePattern (i, typeMap));
1337+ i += op.microcode.length + 1 ;
1338+ }
1339+ return result;
1340+ }
13081341
13091342 Map <OperationDecodePattern , Operation <InstructionType >> get decodeMap {
13101343 // NOTE: we probably should loop through the operations and patterns to ensure coherency.
@@ -1348,17 +1381,60 @@ class Microcode {
13481381
13491382 int get patternWidth => OperationDecodePattern .struct (
13501383 opIndices.length.bitLength,
1384+ typeStructs.length.bitLength,
13511385 fieldIndices,
13521386 ).width;
13531387
1388+ int get opIndexWidth => decodeLookup.keys.fold (0 , (a, b) => a > b ? a : b);
1389+
13541390 int opWidth (Mxlen mxlen) => map.values
13551391 .map ((op) => op.microcodeWidth (mxlen))
13561392 .fold (0 , (a, b) => a > b ? a : b);
13571393
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));
1394+ Map <int , OperationDecodePattern > get decodeLookup {
1395+ Map <int , OperationDecodePattern > result = {};
1396+ var i = 0 ;
1397+ for (final e in map.entries) {
1398+ result[i] = e.key.copyWith (opIndex: i);
1399+ i += e.value.microcode.length + 1 ;
1400+ }
1401+ return result;
1402+ }
1403+
1404+ Map <int , Operation <InstructionType >> get execLookup {
1405+ Map <int , Operation <InstructionType >> result = {};
1406+ var i = 0 ;
1407+ for (final op in map.values) {
1408+ result[i] = op;
1409+ i += op.microcode.length + 1 ;
1410+ }
1411+ return result;
1412+ }
1413+
1414+ Map <String , BitStruct > get typeStructs {
1415+ Map <String , BitStruct > result = {};
1416+ for (final op in map.values) {
1417+ final t = instrType (op);
1418+ if (result.containsKey (t)) continue ;
1419+ result[t] = op.struct;
1420+ }
1421+ return result;
1422+ }
1423+
1424+ Map <String , int > get typeMap => Map .fromEntries (
1425+ typeStructs.entries.indexed.map ((e) => MapEntry (e.$2.key, e.$1)),
1426+ );
1427+
1428+ List <BigInt > get encodedPatterns {
1429+ List <BigInt > result = [];
1430+ for (final pattern in decodeLookup.values) {
1431+ result.add (
1432+ pattern.encode (
1433+ opIndices.length.bitLength,
1434+ typeMap.length.bitLength,
1435+ fieldIndices,
1436+ ),
1437+ );
13621438 }
13631439 return result;
13641440 }
@@ -1480,14 +1556,10 @@ class Microcode {
14801556
14811557 Operation <InstructionType >? lookup (int instr) {
14821558 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) {
1559+ final nzfMatch =
1560+ entry.key.nzfMask == 0 || (instr & entry.key.nzfMask) != 0 ;
1561+ final zfMatch = entry.key.zfMask == 0 || (instr & entry.key.zfMask) == 0 ;
1562+ if ((instr & entry.key.mask) == entry.key.value && nzfMatch && zfMatch) {
14911563 return entry.value;
14921564 }
14931565 }
@@ -1521,11 +1593,13 @@ class Microcode {
15211593 List <RiscVExtension > extensions,
15221594 ) {
15231595 final list = < OperationDecodePattern > [];
1596+ var i = 0 ;
15241597 for (final ext in extensions) {
15251598 final patterns = ext.decodePattern;
15261599
1527- for (final pattern in patterns) {
1528- list.add (pattern.copyWith (opIndex: list.length));
1600+ for (final e in patterns.indexed) {
1601+ list.add (e.$2.copyWith (opIndex: i));
1602+ i += ext.operations[e.$1].microcode.length + 1 ;
15291603 }
15301604 }
15311605 return list;
@@ -1542,4 +1616,9 @@ class Microcode {
15421616 // NOTE: we probably should loop through the operations and patterns to ensure coherency.
15431617 return Map .fromIterables (patterns, operations);
15441618 }
1619+
1620+ static String instrType <T extends InstructionType >(Operation <T > i) {
1621+ final name = i.runtimeType.toString ();
1622+ return name.substring (10 , name.length - 1 );
1623+ }
15451624}
0 commit comments