// MDcheck.bcpl -- check the results of MicroD // last edited November 29, 1979 5:12 PM get "mddecl.d" external // defined here [ Check // () ] external // used [ // OS Zero @oneBits // MDmain @IP @DMachine @IM; @NInstructions // MDerr Err PutAddrData // MDprescan @PageSize; @PageMask @globalZero @calledMask; @goedtoMask; @jbctMask @callerMask; @slowJump; @jbcSubpage ] let Check() be // Check all addressability constraints [ Err(PassMessage, "Checking assignment...") let bt = vec IMsize/16 Zero(bt, IMsize/16) let jbcSame = (jbcSubpage? IMsize-20B, PageMask) for i = 0 to NInstructions-1 do [ let ip = IP(i) let a0 = ip>>IM.W0 let bitp, bitm = bt+(a0 rshift 4), oneBits!(a0&17B) test (@bitp & bitm) ne 0 ifso // Find the other location with the same assigned address [ let j = i [ j = j-1 ] repeatuntil IP(j)>>IM.W0 eq a0 Err(PassFatal, "******$P, $P....duplicate assignment", PutAddrData, j, PutAddrData, i) ] ifnot @bitp = @bitp + bitm if (ip>>IM.global ne 0) & ((a0&globalZero) ne 0) then Err(PassFatal, "******$P....bad assignment for global", PutAddrData, i) let i1 = ip>>IM.W1 if i1 eq WExt loop let ip1 = IP(i1) let a1 = ip1>>IM.W0 let a1bit = oneBits!(a1&17B) if (ip>>IM.iscond ne 0) & (ip>>IM.returns eq 0) then [ let i2 = ip>>IM.W2 let a2 = IP(i2)>>IM.W0 if ((a1&1) ne 0) % (a2 ne a1+1) % ((DMachine ne 0) & (ip>>IM.jbc ne 0) & (((a1bit&jbctMask) eq 0) % ((a1&jbcSame) ne (a0&jbcSame)))) then Err(PassFatal, "******$P -> $P, $P....bad assignment for conditional", PutAddrData, i, PutAddrData, i1, PutAddrData, i2) ] test DMachine eq 0 ifso [ if ip>>IM.returns loop if callerMask ne -1 then test ip>>IM.calls ifso if (a0&1) ne 0 then Err(PassFatal, "******$P....does a CALL but at odd address", PutAddrData, i) ifnot if ip>>IM.oddcall then if (a0&1) eq 0 then Err(PassFatal, "******$P....does a RCALL but at even address", PutAddrData, i) if ip1>>IM.returns loop let i3 = (slowJump? ip1>>IM.W1, i1) let ip3 = IP(i3) if (ip3>>IM.W0/PageSize) ne (ip>>IM.swpage? ip>>IM.newpage, a1/PageSize) then Err(PassFatal, (slowJump? "******$P....(-> $P) -> $P which is on wrong page", "******$P....-> $P which is on wrong page"), PutAddrData, i, PutAddrData, i1, PutAddrData, i3) ] ifnot [ if ((ip>>IM.goes ne 0) & ((a1bit&goedtoMask) eq 0)) % ((ip>>IM.calls ne 0) & (ip>>IM.returns eq 0) & ((a1bit&calledMask) eq 0)) then Err(PassFatal, "******$P -> $P....bad assignment for GOTO or CALL", PutAddrData, i, PutAddrData, i1) if (ip>>IM.usesFN eq 0) % (ip>>IM.returns ne 0) then loop // no constraint on successor if ((a1&PageMask) ne (a0&PageMask)) & ((a1&globalZero) ne 0) then Err(PassFatal, "******$P -> $P....bad assignment -- can't get there", PutAddrData, i, PutAddrData, i1) ] ] ]