%
Page Numbers: Yes First Page: 1
Heading:
MODEL 1: memSubrsC.mcJune 9, 1981 10:35 AM%
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Table of Contents by
Order of Occurence

TEST
DESCRIPTION
initBrsInitialize base register loop control
initCPatternsInitialize cache pattern loop control
initRowCtrl:Init cache row loop control
initRowDownInit cache row Descending loop control
initColCtrlInit cache column loop control
initCol2CtrlInit second cache column loop control
initFlagsCtrlInit cflags pattern loop control
getCvaReturn current value of cva
getSubrScrReturn current value of subrScr
getcBrCacheABitsreturn current value of cBrCacheAbits
nextBrReturn value of next BR
nextColReturn value of next column
nextCol2Return value of next column2 (ther’s two loop variables, col & col2).
getCol2Return current value of column2
nextRowReturn value of next cache row
nextRowDownReturn next value of row, descending loop control
getCrowReturn current value for cache row
nextCFlagReturn next value for CFlags
getCflagReturn current value of flagsVal
nextCPatternGenerate next cache pattern. Return ALU=0 when no more
getCPatternGenerate current pattern based on currnet pattern index (changed by nextCPattern)
mcrForColSet mcr for current column, extra flags passed in t
vaForRowReturn in T a va that matches row in T upon entry
cRowForVaReturn cache row in T for va in T upon entry
cVaForCrowColReturn va that matches row in T, col in rscr.
makeUseMcrVConstruct mcr value and forces useMcrV for column in T
setBrCacheABitsSet hi 15 bits of memory base register
setBrBrLo ← rscr2, BrHi ← rscr15 bits of memory base register
setBrBrLo ← rscr2, BrHi ← rscr
setMCRmcr ← t
longWaitWait number of cycles in T where T = 0 or T>3. Count doesn’t include call and return overhead
checkMemFlagsSubroutine that returns w/ ALU#0 if any memflags in T are set
setMbaseSet current memBase to T
clearCacheFlagsSet entire cache to vacant
setCAmemSet cacheA memory w/ va = addr to write, col = column select
setCflagsSet cache flags for T = va, rscr = pattern, col = column
putCFmemSet cache flags t = va, rscr = flags, rscr2 = column
putCAmemSet CacheA memory: t = va, rscr = brhi15, rscr2 = column
zeroCacheAndFlagsZero cacheAmem and zero cache flags
readCflagsread flags for rscr = va, rscr2 = column
getPipeCacheABitsreturn h 15 bits of pipe VA in T
chkPipeRowEnter w/ t = row, check that pipe1.row = t (ALU#0 if false)
chkPipe5ColRTN ALU#0 if pipe5.col # T
chkCflagsRTN T #0 if (rscr.cflags) # t
setRegs0(rscr,rscr2,t) ← (RM 0, RM 1, RM 2) midas subroutine
setRegs1(rscr,rscr2,t) ← (RM 3, RM 4, RM 5) midas subroutine
setRegs2(rscr,rscr2,t) ← (RM 6, RM 7, RM 10) midas subroutine
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%
June 9, 1981 10:35 AM
Accommodate default values for memState (left half of memFlags)
May 21, 1981 4:32 PM
Fix setMbase to use bmux rather than bdispatch
February 5, 1981 6:02 PM
Remove forceRbase because d1lang now accommodates our need. Change brx to cBrX to accommodate change in memdefs required by changes to d1lang.
Trying to find obscure problem, posibly related to some debugging instructions’ not being Held. add ’←MD’ to zeroCacheAndFlags
July 1, 1979 2:39 PM
Add table of contents, cause cRowForVa to use ldf rather than two constants & clobber rscr2.
May 29, 1979 11:07 AM
Modify clearCacheFlags to use putCFmem.
%
title[memSubrsC];
top level;
subroutine;
* February 5, 1981 6:07 PM
initBrs:
t ← cm1;
return, cBrX ← t;

initCPatterns:
RBASE← rbase[patX];
t←patX ← cm1;
curPattern ← t;
return, RBASE← rbase[defaultRegion];
initRowCtrl:
t ← cm1;
return, rowx ← t;
initRowDown:
t ← rowEndC;
return, rowx ← t;
initColCtrl:
t ← cm1;
return, colx ← t;
initCol2Ctrl:
t ← cm1;
return, col2x ← t;

initFlagsCtrl:
RBASE← rbase[flagsVal];
flagsVal ← (flagsVal)-(flagsVal);
flagsVal ← (flagsVal)-(20c);* first val returned will be zero
return, RBASE← rbase[defaultRegion];

getCva: subroutine;
RBASE ← rbase[cVa];
return, t ← cVa, RBASE ← rbase[defaultRegion];

getSubrScr:
subroutine;
RBASE ← rbase[subrScr];
return, t ← subrScr, RBASE ← rbase[defaultRegion];

getcBrCacheABits:
subroutine;
RBASE ← rbase[cBrCacheAbits];
return, t ← cBrCacheAbits, RBASE ← rbase[defaultRegion];

nextBr:
* compute mem base reg; return it in T
* January 1, 1979 3:04 PM
RBASE← rbase[cBrX];* compute end of base regs as branch condition
t←cBrX←(cBrX)+1;
RBASE← rbase[defaultRegion];
return,t-(brEndC);

nextCol:
* compute next column; return it in T
RBASE← rbase[colx];* compute end of columns as branch condition
t←colx←(colx)+1;
RBASE← rbase[defaultRegion];
return,t-(colEndC);

nextCol2:
* compute next column; return it in T
RBASE← rbase[col2x];* compute end of columns as branch condition
t←col2x←(col2x)+1;
RBASE← rbase[defaultRegion];
return,t-(colEndC);

getCol2:
* return current row in T
RBASE← rbase[col2x];
return, t←col2x, RBASE ← rbase[defaultRegion];


nextRow:
* compute next row; return it in T
RBASE← rbase[rowx];* compute end of row as branch condition
t←rowx←(rowx)+1;
RBASE← rbase[defaultRegion];
return,t-(rowEndC);
nextRowDown:
* compute next row(descending); return it in T
RBASE← rbase[rowx];* compute end of row as branch condition
t←rowx←(rowx)-1;
RBASE← rbase[defaultRegion];
return,t-(cm1);

getCrow:
* return current row in T
RBASE← rbase[rowx];
return, t←rowx, RBASE ← rbase[defaultRegion];

nextCFlag:* return next cache flag value in T
RBASE ← rbase[flagsVal];* return w/ fast branch condition
t ← flagsVal ← (flagsVal)+(20C);
RBASE ← rbase[defaultRegion];
return,t-(flagsEndC);
getCflag:
* return current row in T
RBASE← rbase[flagsVal];
return, t←flagsVal, RBASE ← rbase[defaultRegion];

* December 26, 1978 11:16 AM
%
Cache Pattern loop control: There are three sets of patterns. The first is a left cycled, single one bit. The second is a left cycled, single zero bit, and the third is a composite number = (current row lshift 3)+ current column. This routine returns an ALU result upon exit whose zero result means there are no more valid patterns. To obtain the actual pattern, the diagnostics use the subroutine getCpattern.

nextCPattern: PROCEDURE RETURNS[morePatterns: BOOLEAN] =
BEGIN
patX ← patX + 1;
SELECT patX FROM
IN [0..Pat1EndC) => curPattern ← doPat1[patX, curPattern];
IN [Pat1EndC..Pat2EndC) => curPattern ← doPat2[patX, curPattern];
IN [Pat2EndC..Pat3EndC) => curPattern ← doPat3[patX, curPattern];
ENDCASE => NULL;
morePatterns ← patX >= LastPatC
END
%
nextCPattern:
* compute next pattern index; return in t
RBASE← rbase[patx];* compute end of patterns as branch condition
pushReturn[];* save return link
top level;
t←patx←(patx)+1;* keep patX in T
t-(pat1EndC);* see if IN [0..pat1EndC)
branch[nxtPat2, alu>=0],t←t;* goto[nextPat2, ~IN [0..pat1EndC)]

* IN [0..pat1EndC)
skpif[alu#0];* see if just initialized
skip, curPattern ← 1c;* patX=0 ==> begin with one
curPattern←(curPattern)+(curPattern);
branch[nxtPatXit];

nxtPat2:* see if IN[pat1EndC..pat2EndC)
t-(pat2EndC);
branch[nxtPat3, alu>=0];* goto[nextPat3, ~IN[pat1EndC..pat2EndC)]

* IN [pat1EndC..pat2EndC)
curPattern ← lcy[curPattern, curPattern, 1];
t - (pat1EndC);* If first time thru pattern 2, init
skpif[ALU#0];* curPattern for left cycled zero pattern.
curPattern ← not(b15);
branch[nxtPatXit];

nxtPat3:* are we IN [pat3EndC..lastPat) ??
t - (pat3EndC);
branch[nxtPat4, alu>=0];
curPattern ← (curPattern)-(curPattern);* Zero it since getCPattern constructs
branch[nxtPatXit];* each value separately.

nxtPat4:
branch[nxtPatXit];* add code here for another pattern.
nxtPatXit:
link ← stack&-1;* restore return link, fix up rbase,
subroutine;
RBASE← rbase[defaultRegion];
return,t-(lastPatC);* return w/ proper branch condition

* December 25, 1978 11:53 AM
Cache Test General Subroutines

getCPattern:
* compute next pattern; return it in T
%
Currently there are three sets of patterns. The first set consists of a cycled one. The secod pattern is a cycled zero, and the third is a series of unique values based on row and column.
pattern1 and pattern2: maintained by the nextPattern code -- it changes when "next pattern" is called.
pattern3 changes more frequently (for every column!)
pattern3: OR the quantity (row lshift 3) + column into curPattern.
Eg., if curPattern = 0, row = 22, col = 3 THEN result = 223
%
RBASE← rbase[patx];
pushReturn[];
top level;
(patx)-(pat2EndC);* see which pattern we are using
branch[getCP2,alu>=0];
branch[getCPXit], t←(curPattern) and (CABitsMaskC);* handle BOTH pattern1, pattern2 here

getCP2:* return pattern 2 or greater
(patx)-(pat3EndC);
branch[getCP4, alu>=0];
subrScr ← q;* ROW kept in Q!!!
RBASE ← rbase[defaultRegion];* fetch value of col
t ← col;
RBASE ← rbase[rmForLoops];
subrScr ← lsh[subrScr, 3];
t←t OR (curPattern);* curPattern,,column
branch[getCPXit], t←t OR (subrScr);* curPattern,,row,,column

getCP4:* add code for pattern 3 here
branch[getCPXit];

getCPXit:
RBASE←rbase[defaultRegion];
returnP[];

knowRbase[defaultRegion];


* December 7, 1978 3:04 PM
mcrForCol: subroutine;* set mcr for current column
%
extra falgs to set are passed in T.
This code uses an array of four mcr values that is stored in IM at caMcrLoc..caMcrLoc+3. There is an mcr value for each column, plus bits for useMcrV, disCF, and disHold.
%

rscr ← mcr.useMcrV;
rscr ← (rscr) OR (mcr.disCF);
rscr ← (rscr) OR (mcr.disHold);
rscr ← (rscr) OR (mcr.noWake);
rscr ← (rscr) or t;* Or in the extra bits
t ← lsh[col, mcr.mcrVshift];* position the column for mcr
t ← t or (rscr);
noop;* assure there’s 8 cycles from time of
loadMcr[t,t];* last memory reference
return;

vaForRow:
* construct va that matches row in T
* clobber T and rscr2

t ← lsh[t, cacheShift];
rscr2 ← cacheRowMask0;
rscr2 ← (rscr2) OR (cacheRowMask1);
return, t←tAND(rscr2);* isolate bits of row
cRowForVa:* t = va. return the cache row. CLOBBER t, rscr2
return, t ← ldf[t, nBitsInRow, cacheShift];

cVaForCrowCol:* t = row, rscr = column. RETURN va
* CLOBBER T, RSCR, RSCR2

t ← lsh[t, cacheShift];
rscr ← lsh[rscr, skipCacheShift];

return, t ← t or (rscr);

makeUseMcrV:* construct an mcr value
* that specifies mcr.useMcrV, and selects contents of T as column for victim
* clobber T and rscr2

t←tAND(3c);* just for paranoia
t←lsh[t, mcr.mcrVshift];
return, t←t OR (mcr.useMcrV);* rtn w/ t= mcr value

setBrCacheABits:
* set hi 15 bits of memory base reg
* Enter w/ T = 15 bit value to use. clobber T, rscr, and rscr2

rscr ← rsh[t, CABitsInPipe1];
rscr ← (rscr) and (CABitsInPipe0Mask);
rscr2 ← lsh[t, CABitsInPipe1Shift];
rscr2 ← (rscr2) and (CABitsInPipe1Mask);
BrHi ← rscr;
return, BrLo ← rscr2;

setBR:* rscr2 = brLO, rscr = brHI
brlo ← rscr2;
brhi ← rscr;
return;
setMCR:
noop; noop; noop; noop;*NOTE: Hardware constraints require minimum
noop; noop; noop;* of 8 cycles between memops and setting mcr.

loadmcr[t,t];* set MCR w/ T
noop;* wait for MCR to settle down
return;

* December 4, 1978 5:38 PM

longWait:
subroutine;* wait (T + 2) cycles where T >3, not counting call or return! SPECIAL KLUDGE: IF T=0, return almost immediately (ie. total delay = 2 cycles + call + return)
PD←t;* CLOBBER T
loopUntil[ALU=0, .], t ← t-1;
return;

* December 4, 1978 5:39 PM
checkMemFlags: subroutine;* T = memory flags to check
* return w/ fast branch condition for flags ON in memFLAGS

pushReturnAndT[];
t ← memFlagsLocC;
call[getIMRH];* get flags into T
t ← t and (stack);* isolate 1 bits in t
pReturnPAndBranch[t];* rtn w/ branch condition. bits in t


* May 21, 1981 4:32 PM
%
Set MemBase to value in t.
%
subroutine;
setMbase:* t = value to use
MemBase←t, RETURN;

* May 29, 1979 11:07 AM
%
Clear Cache Flags
clearCacheFlags: PROCEDURE =
BEGIN
FOR rowX IN CacheRowX DO
t ← getVaForRow[rowX] - cflags.vacant;
FOR col IN Column DO
makeUniqueAmemEntryAtRowCol[rowX, col];
setBR[0,t];
mcrV ← MakeUseMcrV[col];
mcrV ← BitOR[mcrV, mcr.fdMiss, mcr.disHold];
setMcr[mcrV];
dummyRef ← cflags.vacant;
CFLAGS ← cflags.vacant;
ENDLOOP;
ENDLOOP;
END;

This subroutine causes the entire cache to be cacant. It clobbers MCR, BR
%
clearCacheFlags:
pushReturn[];

call[initRowCtrl];
clrCacheFrowL:* loop for all the rows of the cache
call[nextRow];
skpif[alu#0];
branch[clrCacheXit];

noop;* for placement

call[initColCtrl];
clrCacheFcolL:* loop for the columns in this row
call[nextCol];
skpif[alu#0];
branch[clrCacheFrowL];

col ← t;* col is the current column

call[getCrow], rscr ← t;* return w/ t = rowX
call[cVaForCrowCol];* t = row, rscr = col, return t = va
call[setCAmem], va ← t;* enter w/ t = va, col = column
rscr2 ← col;
rscr ← cflags.vacant;
call[putCFmem], t ← va;
branch[clrCacheFcolL];

clrCacheXit:
returnP[];

* December 4, 1978 5:41 PM
setCAmem:* yet another way to set Amemory
* ENTER w/ va = addr to write, col = column to select
* CLOBBER T, rscr, rscr2
pushReturn[];
t ← col;
rscr2 ← t;
t ← va;
call[putCAmem], rscr ← t-t;* call w/ t = va, rscr = brHi15, rscr2 =col
returnP[];
setCflags:* T = va, rscr =pattern, col = column
pushReturnAndT[];
t ← stack;
call[putCFmem], rscr2 ← col;
pReturnP[];
putCFmem: subroutine;* t = va, rscr=flags, rscr2 = col
cva ← t;
pushReturn[];
t ← rscr;* save flags value
cflagsV ← t;
call[makeUseMcrV], t ← rscr2;
t ← t OR (mcr.fdMiss);
t ← t OR (mcr.noRefHold);
call[setMCR];
call[getCva];
rscr2 ← t;* rscr2 ← cva
t ← not(rscr);* t ← cflags
t ← t and (cflags.mask);* invert only the cflags bits
rscr2 ← (rscr2)-t;* rscr2 ← cva - flags
call[setBR], rscr ← t-t;
dummyRef ← t;
CFLAGS ← t;
returnP[];
putCAmem: subroutine;* t = va, rscr = brhi15, rscr2 = col;
cva ← t;
pushReturn[];
t ← rscr;
cBrCacheAbits ← t;

t ← col;
subrScr ← t;

col ← rscr2;
t ← (mcr.fdMiss);
t ← t OR (mcr.noRef);
call[mcrForCol];* no extra flags, use rscr2 as victim
call[getcBrCacheABits];
call[setBrCacheAbits];
call[getCva];
rscr2 ← t;
DBuf ← r0, STORE ← T;
shortMemWait[rscr];
t ← rscr2;* restore t; shortMemWait used it
DBuf ← r0, STORE ← T;
shortMemWait[rscr];

call[getSubrScr];
col ← t;
returnP[];

* September 19, 1979 10:52 PM

zeroCacheAndFlags: subroutine;* zero cache Amem and cache flags
* CLOBBER RSCR, RSCR2, T
pushReturn[];
t←MD;* see if this makes obscure problems go away.
call[initRowCtrl];
zcafRowL:
call[nextRow];
skpif[alu#0];
branch[zcafRtn];
q ← t;* save row in Q

call[initColCtrl];
zcafColL:
call[nextCol];
skpif[alu#0];
branch[zcafRowL];
col ← t;
t ← q;
call[vaForRow];

rscr ← t;* ’round the register merry go round
t ← col;
rscr2 ← t;
t ← rscr;
call[putCAmem], rscr ← t-t;* t = va, rscr = brHi15, rscr2 = col

call[vaForRow], t ← q;
call[setCflags], rscr ← t-t;* t = va, rscr = pattern, col = column
branch[zcafColL];

zCafRtn:
returnP[];



* December 7, 1978 3:11 PM
PIPE reading routines
readCflags:* rscr = va, rscr2 = column
* clobber T, rscr, rscr2. Return all the bits from PIPE5 in T

pushReturn[];
top level;
* Set MCR for appropriate column, fdMiss, dPipeVA, disHold (use disBR for convenience)
call[makeUseMcrV],t ← rscr2;* setup mcr. RSCR ~clobbered !
t ← t OR (mcr.fdMiss);
t ← t OR (mcr.dPipeVa);
t ← t OR (mcr.disBR);* convenience: needn’t load BR!
t←tOR (mcr.noRefHold);* mcr.noRef + mcr.disHold
call[setMCR];

dummyRef ← rscr;
noop;
t ← PIPE5;* now read and remember flags
%
notice that we don’t invert the bits for cflags. To write a set of flags F, the processor must first invert F (F’), and then proceed. However, when reading the flags the bit
values have their "true" sex.
%
returnP[];* return w/ flag bits in T

getPipeCacheABits: subroutine;* return hi 15 bits of pipe VA in T.
* leave rscr2 untouched.
* clobber T, rscr

t←pipe0;
t ← t and (CABitsInPipe0Mask);
rscr ← pipe1;
rscr ← (rscr) AND (CABitsInPipe1Mask);
t←lsh[t, CABitsInPipe1];* hi bits of VA from pipe 0
rscr←rsh[rscr, CABitsInPipe1Shift];* isolate mid bits of VA from pipe 1
t←t OR (rscr);* add them together and mask
return, t←t AND (CABitsMaskC);* return: t= hi15 bits of VA rt. justified



* December 7, 1978 5:17 PM
Cache RESULT TESTING subroutines

chkPipeRow: subroutine;* enter with T = row. check that pipe1.row = t
* clobber T, rscr, rscr2

rscr ← (cacheRowMask0);
rscr ← (rscr) OR (cacheRowMask1);* construct row bits mask
rscr2 ← PIPE1;* NOW CHECK ROW=CACHE BITS. t=ROW
t ← lsh[t, cacheShift];
T ← (rscr2) # (t);
return, T ← (rscr) AND (t);* use row bits only

chkPipe5Col: subroutine;* T=expected col, rscr =PIPE5 value
* return w/ T=bad bits, rscr= PIPE5 val. return w/ fast branch condition
* CLOBBER rscr2,t

t ← t and (3c);* mask for paranoia
t ← lsh[t, pipe5.colShift];* position column field
t←t#(rscr);
rscr2 ← pipe5.colBit0;* construct mask to isolate col field
rscr2 ← (rscr2) + (pipe5.colBit1);
return, t←t and (rscr2);* return w/ fast branch condition

chkCflags: subroutine;* T = expected flags, rscr = PIPE5 value
* return w/ T=bad bits, rscr = PIPE5 val. return w/ fast branch condition
* clobber rscr2, t

t←t#(rscr);* isolate different bits
rscr2 ← pipe5.flagsMask;
return, t←t and (pipe5.flagsMask);* return w/ fast branch condition
* February 5, 1981 6:02 PM
% subroutines for midas level degbugging

This code sets rscr, rscr2, and T from RM0 thru RM10
%
top level;
call[setRegs0];* these calls assure that the named
call[setRegs1];* subroutines really get loaded onto call
call[setRegs2];* locations.
noop;* sigh. here for placement.
setRegs0: subroutine;
RBASE ← 0s;
t ← rmx0;
rscr ← t;
t ← rmx1;
rscr2 ← t;
return, t ← rmx2, RBASE ← rbase[defaultRegion];

setRegs1: subroutine;
RBASE ← 0s;
t ← rmx3;
rscr ← t;
t ← rmx4;
rscr2 ← t;
return, t ← rmx5, RBASE ← rbase[defaultRegion];

setRegs2: subroutine;
RBASE ← 0s;
t ← rmx6;
rscr ← t;
t ← rmx7;
rscr2 ←t;
return, t ← rmx10, RBASE ← rbase[defaultRegion];

data[(
memFlags: lh[defaultMemFlagsLeft], rh[defaultMemFlags], at[memFlagsLoc])];