Imports Atom, BitOps, CacheOps, Dragon; Cedar iBufMaxWords: NAT = 32; iBufMaxBytes: NAT = 4*iBufMaxWords; IFCState: TYPE = {pendingJump, fetchingFirst, fetchingMore, full, faulted}; ; IFetcherControl: CELL [ PreLengthAB >INT[3], InstReadyAB >BOOL, PreFetchFaultedBA >BOOL, GetNextInstB EnumType["Dragon.PBusCommands"], IPRejectB BOOL, FetchFinishedB >BOOL, FlushB >BOOL, Take1B >BOOL, Take2B >BOOL, Take3B >BOOL, Take5B >BOOL, PreOpA preFetchPCWord[b]+1, ENDCASE => preFetchPCWord[b]; firstByteOffset[a] _ firstByteOffset[b]; pParityErrorAB _ (NOT DHold0BA AND successfulFetchBA) AND (CacheOps.Parity32[pDataBA] # pParityBA); NoneValidAB _ NHas1A; noRoomForMoreAB _ NoRoomForMoreA; END; -- of PhA evaluation IF PhB THEN BEGIN Dragon.Assert[NOT (IPFaultB # None AND NOT IPRejectB)]; Dragon.Assert[NOT (GetNextInstB AND JumpB)]; Dragon.Assert[NOT (GetNextInstB AND NOT InstReadyAB)]; PreFetchFaultedBA _ state[a] = faulted AND NOT InstReadyAB AND NOT JumpB; IF pParityErrorAB THEN IPNPErrorB _ FALSE; pDataBA _ BitOps.ExtractLongFDouble[container: IPData, containerWidth: 32, fieldPosition: 0, fieldWidth: 32]; -- latch for parity check pParityBA _ IPParityB; FetchFinishedB _ successfulFetchBA _ NOT DHold1AB AND NOT IPRejectB AND NOT JumpB AND state[a] IN [fetchingFirst..fetchingMore]; state[b] _ SELECT TRUE FROM DHold1AB => state[a], JumpB AND IPRejectB => pendingJump, NOT IPRejectB AND (JumpB OR state[a] = pendingJump) => fetchingFirst, state[a] IN [fetchingFirst..fetchingMore] AND IPFaultB # None => faulted, IPRejectB, state[a] = faulted => state[a], NOT noRoomForMoreAB => fetchingMore, ENDCASE => full; newFetchBA _ NOT IPRejectB AND state[b] IN [fetchingFirst..fetchingMore]; IF (FlushB _ NOT DHold1AB AND JumpB) THEN BEGIN firstByteOffset[b] _ BitOps.ExtractLongFDouble[container: XBus, containerWidth: 32, fieldPosition: 0, fieldWidth: 32] MOD 4; preFetchPCWord[b] _ BitOps.ExtractLongFDouble[container: XBus, containerWidth: 32, fieldPosition: 0, fieldWidth: 32]/4; END ELSE BEGIN firstByteOffset[b] _ firstByteOffset[a]; preFetchPCWord[b] _ preFetchPCWord[a]; END; Take1B _ GetNextInstB OR ((state[a]=fetchingFirst AND NOT IPRejectB) AND (firstByteOffset[a]>=1)); Take2B _ (GetNextInstB AND (PreLengthAB>=2)) OR ((state[a]=fetchingFirst AND NOT IPRejectB) AND (firstByteOffset[a]>=2)); Take3B _ (GetNextInstB AND (PreLengthAB>=3)) OR ((state[a]=fetchingFirst AND NOT IPRejectB) AND (firstByteOffset[a]>=3)); Take5B _ GetNextInstB AND (PreLengthAB>=5); END; -- of PhB evaluation ENDCELL; IFetcherArray: CELL [ IPDataB INT[8], PreAlphaA >INT[8], PreBetaA >INT[8], PreGammaA >INT[8], PreDeltaA >INT[8], NHas1A >BOOL, Has2A >BOOL, Has3A >BOOL, Has5A >BOOL, NoRoomForMoreA >BOOL, PhA BEGIN PreOpA _ BitOps.WAND[PreOpA, byteBA[i]]; NHas1A _ FALSE; END; firstBA[(i+iBufBytes-1) MOD iBufBytes] => BEGIN PreAlphaA _ BitOps.WAND[PreAlphaA, byteBA[i]]; Has2A _ Has2A AND validBA[i]; END; firstBA[(i+iBufBytes-2) MOD iBufBytes] => BEGIN PreBetaA _ BitOps.WAND[PreBetaA, byteBA[i]]; Has3A _ Has3A AND validBA[i]; END; firstBA[(i+iBufBytes-3) MOD iBufBytes] => BEGIN PreGammaA _ BitOps.WAND[PreGammaA, byteBA[i]]; Has5A _ Has5A AND validBA[i]; END; firstBA[(i+iBufBytes-4) MOD iBufBytes] => BEGIN PreDeltaA _ BitOps.WAND[PreDeltaA, byteBA[i]]; Has5A _ Has5A AND validBA[i]; END; ENDCASE => NULL; ENDLOOP; FOR i: NAT _ 3, i+4 WHILE i < iBufBytes DO NoRoomForMoreA _ NoRoomForMoreA AND (validBA[i] OR validBA[(i+5) MOD iBufBytes]); ENDLOOP; validAB _ validBA; FOR i: [0..iBufMaxBytes) IN [0..iBufBytes) DO SELECT i FROM 0 => firstAB[i] _ firstBA[i] OR NoneValidAB; ENDCASE => firstAB[i] _ firstBA[i]; ENDLOOP; END; -- of PhA evaluation IF PhB THEN BEGIN IF FlushB THEN BEGIN r: REF = Atom.GetProp[$Cluster, $IBufWords]; iBufWords _ IF r#NIL THEN NARROW[r, REF INT]^ ELSE 8; iBufBytes _ 4*iBufWords; END; FOR i: [0..iBufMaxBytes) IN [0..iBufBytes) DO validBA[i] _ (validAB[i] OR (FetchFinishedB AND ((validAB[(i+iBufBytes-1-(i MOD 4)) MOD iBufBytes] AND NOT validAB[(i+3-(i MOD 4))]) OR (NoneValidAB AND i<4)))) AND NOT FlushB AND NOT (Take1B AND firstAB[i]) AND NOT (Take2B AND firstAB[(i+iBufBytes-1) MOD iBufBytes]) AND NOT (Take3B AND firstAB[(i+iBufBytes-2) MOD iBufBytes]) AND NOT (Take5B AND firstAB[(i+iBufBytes-3) MOD iBufBytes]) AND NOT (Take5B AND firstAB[(i+iBufBytes-4) MOD iBufBytes]); IF FetchFinishedB AND ((validAB[(i+iBufBytes-1-(i MOD 4)) MOD iBufBytes] AND NOT validAB[(i+3-(i MOD 4))]) OR (NoneValidAB AND i<4)) THEN byteBA[i] _ BitOps.ECFD[IPDataB, 32, 8*(i MOD 4), 8]; ENDLOOP; FOR i: [0..iBufMaxBytes) IN [0..iBufBytes) DO firstBA[i] _ validBA[i] AND NOT validBA[(i+iBufBytes-1) MOD iBufBytes]; ENDLOOP; PreOpA _ PreAlphaA _ PreBetaA _ PreGammaA _ PreDeltaA _ LAST[Dragon.HexByte]; NHas1A _ Has2A _ Has3A _ Has5A _ NoRoomForMoreA _ TRUE; END; -- of PhB evaluation ENDCELL; Cedar PreFetcherState: TYPE = {pendingJump, fetching, waiting, faulted} _ faulted; ; IFetcher: CELL [ PreOpA >INT[8], PreAlphaA >INT[8], PreBetaA >INT[8], PreGammaA >INT[8], PreDeltaA >INT[8], PreLengthAB >INT[3], InstReadyAB >BOOL, PreFetchFaultedBA >BOOL, -- generated during PhB (there's no hurry) GetNextInstB EnumType["Dragon.PBusCommands"], IPRejectB