%
Page Numbers: Yes First Page: 1
Heading:
DORADO:memSubrsS.mcJune 17, 1981 9:31 AM %
title[memSubrsS];
top level;
subroutine;
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RoutineDescription
iSmunchCtrlInitialize 24 bit va loop control for munch addrs
iSvaCtrlInitialize 24 bit va control for simple addrs.
iSvaDownCtrlInitialize 24 bit va control going down
iSmunchDownCtrlInitialize 24 bit va control going down for munches
restoreBrHirestores current BrHi to value indicated by SvaHiX
iSpatCtrlInit storage patterns
isChaosXInit chaos loop control
nextChaosXReturn next chaos index
getSsubrScrReturn current value of sSubrScr
getSsavedHoldValueReturn current value of SsavedHoldValue
iSboardInitialize the c,x,d,s boards for storage diagnostics
getSmcrVictimReturn current sMCRvictim
sRestoreMcrVictimSet sMcrVictim from memState, then set defaultMcr
sUseMcrVictimSEts Mcr to use indicated victim in cache
sUseDefaultMcrSet Mcr w/ sUseMcr
saOrMcrNoWakeORs more bits into a Mcr value + mcr.noWake
sChkNoErrsrtn memState.noErrs bit
sNoErrsOnTurn on error checking in storage diagnostic
sNoErrsOffTurn off error checking in storage diagnotic
nextSvaReturn next sva value
nextSvaDownReturn next (decreasig) sva value
nextSMunchReturn next munch address
incSvaIncrement current sva by indicated amount
nextSpatReturn next pattern index
getSPatReturn current pattern value
zeroMemoryZero all available storage
setMemorySet all available storage to given value
saveMemAddrSave (sVaHi,,sVaX) in sVaHiXold,, sVaXold
fetchMemAddrReturn sVaHiOld,,sVaXold
getSvaXoldReturn sVaXOld
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

%
June 17, 1981 9:31 AM
Move sPingPong, dirtyWriteLoop and doScheckOut into memMisc’s memDesperateA.mc
June 16, 1981 10:59 AM
Add call to xGetMapICs in iSboard
June 9, 1981 11:12 AM
Init memState from within iSboard.
May 20, 1981 5:18 PM
Fix problems in sPingPong
May 18, 1981 2:12 PM
Change nextSPat to cycle random number seed.
May 14, 1981 4:51 PM
Miscellaneous fixes to make microcode smaller.
July 1, 1979 3:39 PM
Cause doScheckOut to set mcr.noWake before it tries to load Brs.
July 1, 1979 3:04 PM
Fix doScheckOut to vacate the cache where required (code was buggy) & add scope loops.
June 28, 1979 11:20 AM
Move sGetConfig into memSubrsX and rename it.
June 27, 1979 6:59 PM
Force sBrHi and sBrLo to be zero as default in doSCheckout, remove mcr.disCF from default mcr value.
June 26, 1979 4:43 PM
Make another change to doScheckOut.
June 25, 1979 10:14 AM
Change doScheckOut as per requests (fixes several bugs, thnx to k pier).
June 7, 1979 2:07 PM
Fix bug in sex of skip instruction in sGetICtype.
May 7, 1979 2:16 PM
Update sGetICtype to Rev C standards for Config.
January 17, 1979 9:12 AM
remove saSetMcr entirely: setting mcr now independent of setting sMCRvictim
January 16, 1979 2:32 PM
change MCRvictim handling: sMCRvictim may be set by any routine and that value becomes the one sUseDefaultMcr uses (ie., really causes it to occur in MCR). However, the test-wide value (ie., the one set by program default or by the operator) is kept in a separate place, and that value may be restored by calling sRestoreMcrVictim.
January 15, 1979 2:58 PM
reenable dirtyWriteLoop, sPingPong
January 13, 1979 12:43 PM
procSRN←r0 inside iSboard, remove dirtyWriteLoop, sPingPong: get memA to place
January 12, 1979 3:17 PM
new sGetConfig that notices that storage begins w/ Module 1,2, or 3, pattern3 diddles
%


knowRbase[defaultRegion];

* April 23, 1978 9:56 PM

iSmunchCtrl: subroutine;* initialize 24 bit va loop control
* CLOBBER T, RSCR, RSCR2

saveReturn[Srlink];* NOTE: this code (down ctrl, too) won’t
* work properly when va[0:1]#0. THAT
* requires rewriting the Map as well AND that
sVaHiX ← t← a1;* may present other problems
t ← (r0)-(20c);* begin w/ 0-munchSize
svaX ← t;
rscr ← (rscr) - (rscr);
call[setBR], rscr2 ← (rscr2) - (rscr2);
returnUsing[Srlink];


iSvaCtrl: subroutine;* initialize 24 bit va loop control
* CLOBBER T, RSCR, RSCR2

saveReturn[Srlink];* NOTE: this code (down ctrl, too) won’t
* work properly when va[0:1]#0. THAT
* requires rewriting the Map as well AND that
sVaHiX ← t← a1;* may present other problems
svaX ← t;
rscr ← (rscr) - (rscr);
call[setBR], rscr2 ← (rscr2) - (rscr2);
returnUsing[Srlink];

iSvaDownCtrl: subroutine;
saveReturn[Srlink];
RBASE ← rbase[sMaxBrHi];
t←sMaxBrHi;
svaX ← t-t;
sVaHiX ← t, RBASE ← rbase[defaultRegion];
rscr ← t;
call[setBR], rscr2 ← t-t;
returnUsing[Srlink];

iSmunchDownCtrl: subroutine;
saveReturn[Srlink];
t ← (r0)-(20c);
svaX ← t;
RBASE ← rbase[sMaxBrHi];
t←sMaxBrHi;
sVaHiX ← t, RBASE ← rbase[defaultRegion];
rscr ← t;
call[setBR], rscr2 ← t-t;
returnUsing[Srlink];

restoreBrHi: subroutine;* restore current BRHI after its been clobbered
saveReturn[Srlink];
RBASE ← rbase[sVaHiX];
t ← sVaHiX, RBASE ← rbase[defaultRegion];
rscr ← t;
call[setBR], rscr2 ← t-t;
returnUsing[Srlink];

iSpatCtrl:
subroutine;
Spatx ← t← a1;
return, curSPattern ← t;

isChaosX: subroutine;
return, sChaosX ← t← a1;

nextChaosX: subroutine;
RBASE ← rbase[sChaosX];
t ← sChaosX ←(sChaosX) + 1, RBASE ← rbase[defaultRegion];
return, t - (sChaosEndC);* alu=0 IF last pattern

getSsubrScr: subroutine;
RBASE ← rbase[sSubrScr];
return, t ← sSubrScr, RBASE ← rbase[defaultRegion];

getSsavedHoldValue: subroutine;
RBASE ← rbase[SsavedHoldValue];
return, t ← SsavedHoldValue, RBASE ← rbase[defaultRegion];

* June 16, 1981 10:58 AM
%
Initialize the Storage Boards
Init the storage boards in preparation for storage diagnostics. Turn on or off error correction as required by memState.useTestSyn. Simulate a cache w/ only one column, as required by sMCRvictim (RM location). This subroutine also presets the map, clears the cache flags and determines the current memory configuration.
%

iSboard: subroutine;
saveReturn[Srlink];

t ← FaultInfo’[];* remove any waiting wakeups

call[iMemState];

call[xGetConfig];
call[xGetMapICs];
call[clearCacheFlags];* make the cache vacant
call[presetMap];* initialize the map
call[clearCacheFlags];* make the cache vacant

t ← memState.useTestSyn;
call[checkMemState];
skpif[alu=0], t ← t-t;* don’t use error correction
t ← (200c);* use error correction
call[setTestSyn];* causes cache to be non-vacant
call[clearCacheFlags];* make the cache vacant

rscr ← t-t;* set our base register to zero
call[setBR], rscr2 ← t-t;

call[saNoWakeOn];* default = set mcr.noWake
call[sRestoreMcrVictim];* get MCRvictim (>3 => set MCR w/ 0)
procSRN ← r0;
returnUsing[Srlink];

* January 17, 1979 9:31 AM
%
getSmcrVictimreturns t = sMCRvictim
sRestoreMcrVictimresets sMCRvictim from memState, sets MCR
sUseMcrVictimsets sMCRvictim, memState
sUseDefaultMcrsets MCR w/ current sMCRvictim
%
getSmcrVictim: subroutine;
RBASE ← rbase[sMCRvictim];
return, t ← sMCRvictim, RBASE ← rbase[defaultRegion];
sRestoreMcrVictim: subroutine;* rtn restored victim value in T
pushReturn[];* read value of sMCRvictim as stored in
call[getmemState];* memState, and set sMCRvictim with
rscr ← rsh[t, memState.mcrVictimShift];* that value.
t and (memState.usingOneColumn);
skpif[ALU=0];* see if we use all the cache
skip, t ← (rscr) and (3c);* Using one column: use value from memstate.
t ← 7c;* impossible cache column => use all the cache
sMCRvictim ← t;
call[sUseDefaultMcr];
returnP[];
%
sUseMcrVictim
This routine "permanently" sets the mcrVictim used the the diagnostics. This means that every time
iSboard gets called or every timethe operator invokes sRestoreMcrVictim, sMCRvictim will be set to select the indicated column of the cache (or to allow full use of the cache). Any given piece of code may change the value of sMCRvictim, an r-register, to temporarily cause the cache to behave as if it were only one column wide. Once that code has done this, that value of sMCRvictim will continue to be used by sUseDefaultMcr until sRestoreMcrVictim gets called.
%
sUseMcrVictim: subroutine;
pushReturnAndT[];* Enter w/ t = new victim.
(stack) and (not[3]C);* see if impossible cache column
skpif[ALU=0];
branch[sUseMcrVicOff];

* set sMCRvictim with a "non-null" value. This means we set it to a value IN [0..3]
t ← (stack) and (3c);
t ← lsh[t, memState.mcrVictimShift];
rscr ← t or (memState.usingOneColumn);
sUseMcrVicSet:* set both sMCRvictim and memState
t ← (stack);
sMCRvictim ← t;* set sMCRvictim w/ our input
t ← rscr;* now save our new addition for memState
stack+1 ← t;
call[getMemState];* rtns t=current memState
rscr ← (add[memState.usingOneColumn!, memState.mcrVictim!]C);
rscr ← not(rscr);* Remove "current" mcr stuff from
t ← t and (rscr);* memState so we can add our new
t ← t or (stack&-1);* mcr stuff. Pop stack, too
call[putMemState];
pReturnP[];
sUseMcrVicOff:
rscr ← t-t;
branch[sUseMcrVicSet];

sUseDefaultMcr: subroutine;
pushReturn[];*BEWARE: uses Srlink; clobbers rscr, rscr2, t
call[getSmcrVictim];* get MCRvictim (>3 => set MCR w/ 0)
t and (not[3]C);* see if we’re using a victim
dblBranch[sUseDefaultVic, sUseDefaultAll, ALU=0];

sUseDefaultAll:
branch[sUseDefaultSet], t ← t-t;

sUseDefaultVic:
noop;* for placement.
call[makeUseMcrV];* enter w/ t = column, rtns t = mcr value
sUseDefaultSet:
call[saOrMcrNoWake];* OR proper noWake into current mcr val.
call[setMCR];

returnP[];

* January 16, 1979 3:08 PM

* enter w/ t = mcr bits
* return w/ t = mcr bits OR (correct value for mcr.noWake -- same as memState.noWake)
saOrMcrNoWake: subroutine;
saveReturnAndT[saOrMcrNoWakeRtn, sSubrScr];
call[checkMemState], t ← (memState.noWake);
skpif[alu=0], rscr ← t-t;
rscr ← mcr.noWake;
call[getsSubrScr];
t ← t or (rscr);
returnUsing[saOrMcrNoWakeRtn];

* January 5, 1979 2:34 AM
* RTN ALU#0 IF error checking is turned off
* applies to storage data test
sChkNoErrs: subroutine;
saveReturn[sRlink];
call[checkMemState], t ← memState.noErrs;
returnAndBranch[sRlink, t];
sNoErrsOn: subroutine;
saveReturn[sRlink];
call[getMemState];
t ← t OR (memState.noErrs);
call[putMemState];
returnUsing[sRlink];
sNoErrsOff: subroutine;
saveReturn[sRlink];
call[getMemState];
rscr ← not(memState.noErrs);
call[putMemState], t ← t and (rscr);
returnUsing[sRlink];


* January 27, 1978 11:30 AM
%
nextSva: PROCEDURE RETURNS [va: Low16BitsOfVa, validity: BOOLEAN]
BEGIN
RETURN[incSva[inc: 1]];
END;
nextSvaDown: PROCEDURE RETURNS[va: Low16BitsOfVa, validity: BOOLEAN]=
BEGIN
RETURN[ incSva[inc: -1] ];
END;
nextSmunch: PROCEDURE RETURNS [va: Low16BitsOfVa, validity: BOOLEAN] =
BEGIN
RETURN[incSva[inc: 16]];
END;
incSva: PROCEDURE[increment: CARDINAL] RETURNS[va: Low16BitsOfVa, validity: BOOLEAN] =
BEGIN
oldLow ← low;
low ← low + increment;
signChange ← (oldLow xor low) AND (b0);
IF signChange THEN
IF increment >0 AND (( low BITAND b0) = 0) THEN
-- overflow if msb is zero
hiVa ← hiVa + 1;
IF hiVa = lastVa THEN RETURN[nil, FALSE];
SetBr[hiVa, 0];
END;
IF increment <0 AND ((low BITAND b0) # 0) THEN
-- underflow if msb is 1
hiVa ← hiVa -1;
IF hiVa <0 THEN RETURN[nil, FALSE];
SetBR[hiVa,0];
END;
RETURN[low, TRUE];
END;
%

* October 16, 1978 10:06 AM
knowRbase[defaultRegion];
nextSva: subroutine;* return t = low 16 bits of next va.
* automatically set BRHI. Clobber T, RSCR, RSCR2
saveReturn[Srlink];
t ← 1c;
call[incSva];* REMEMBERED the ALU=0 condition in rscr

returnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbr
nextSmunch: subroutine;* return t = low 16 bits of next va.
* automatically set BRHI. Clobber T, RSCR, RSCR2
saveReturn[Srlink];
t ← 20c;
call[incSva];* REMEMBERED the ALU=0 condition in rscr

returnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbr
nextSvaDown: subroutine;* return t = low 16 bits of next va.
* automatically set BRHI. Clobber T, RSCR, RSCR2
saveReturn[Srlink];
t ← cm1;
call[incSva];* REMEMBEREDED the ALU=0 condition in rscr

returnAndBranch[Srlink, rscr];* use Srlink for return, use val of rscr for fastbr

incSva: subroutine;* Enter w/ T = increment to sVaX
* return t = low 16 bits of next Sva, alu=0 result in rscr
* is fast branch condition, clobber T, RSCR, RSCR2. call setBR if required.

saveReturnAndT[incSvaRtn, SsubrScr];

RBASE ← rbase[sSubrScr];
t ← sSubrScr;
SvaX ← (SvaX)+t;* increment SvaX

t ← (SvaX)-t;* compute signChange
t ← t # (SvaX);
t ← t and (B0);
branch[incNormal,alu=0], sSubrScr ← sSubrScr;* IF signChange THEN ...
branch[incOverFlChk, alu>=0];* IF increment >=0 THEN
incUnderFlChk:
(SvaX) and (b0);
skpif[alu#0];* IF SvaX AND b0 =0
branch[incNormal];

t ← sVaHiX ← (sVaHiX) -1;* THEN decrement sVaHiX
dblbranch[incRtnDone, incSetBr, alu<0];

incOverFlChk:
(SvaX) and (b0);
skpif[alu=0];* IF SvaX AND b0 # 0
branch[incNormal];

t ← sVaHiX ← (sVaHiX)+1;* THEN increment sVaHiX
t-(sMaxBrHi);
dblbranch[incRtnDone, incSetBr, alu=0];

incSetBr:
RBASE ← rbase[defaultRegion];
rscr ← t;
call[setBR], rscr2 ← (rscr2) - (rscr2);* set BRHi
noop;

incNormal:
subroutine;
RBASE ← rbase[incSvaRtn];
link ← incSvaRtn;
RBASE ← rbase[svaX];
t ← svaX, RBASE ← rbase[defaultRegion];
return, rscr ← r1;* return w/ t=lowva, alu result #0

incRtnDone:
subroutine;
RBASE ← rbase[incSvaRtn];
link ← incSvaRtn;
t ← t-1, RBASE ← rbase[defaultRegion];* return w/ t undefined,
return, rscr ← t-t;* return w/ t undefined, alu result =0


* May 18, 1981 2:11 PM
nextSpat:* compute next pattern index; return in t
%
This routine increments SpatX, the pattern control variable that determines which pattern the routine getSPat will generate. For simple patterns like cycled 1 and cycled 0, nextSpat also generates the value for the current pattern. The routine getSPat computes the values for the more complicated patterns.
%
* pattern1 IN [0..pat1EndC)
= cycled 1
* pattern2 IN [Spat1EndC..Spat2EndC)
= cycled 0
* pattern3 IN [Spat2EndC..Spat3EndC)
= cycled 32 bit va (only 16 bits returned)
* pattern4 IN [Spat3EndC..Spat4EndC)
= pseudo random numbers

* Return w/ end of patterns as branch condition ("ALU=0" means end of patterns)

RBASE← rbase[rmForStoreLoops];
SRlink ← link;* save return link
top level;
t←Spatx←(Spatx)+1;* SpatX in T while finding current pattern
t-(Spat1EndC);* see if IN [0..pat1EndC)
branch[nxtSPat2, alu>=0],t←t;* goto[nextPat2, ~IN [0..Spat1EndC)]

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

nxtSPat2:
t-(Spat2EndC);
branch[nxtSPat3, alu>=0];* goto[nxtSPat3, ~IN [0..Spat2EndC)

* IN [Spat1EndC..Spat2EndC)
* pattern2 = left cycled 0
curSPattern ← lcy[curSPattern, curSPattern, 1];
t - (Spat1EndC);* If first time thru pattern 2, init
skpif[ALU#0];* curSPattern for left cycled zero pattern.
curSPattern ← not(b15);* curspattern ← 177776 on first time thru
branch[nxtSPatXit];

nxtSPat3:
t - (Spat3EndC);
branch[nxtSpat4, alu>=0];* goto[nxtSPat4, ~IN[0..Spat3EndC) ]

* IN [Spat2EndC..Spat3EndC)
* pattern3 = cycled 32bit va (use low 16 bits)
branch[nxtSpatXit];* pattern3 (cycled va) done by getSPat.

nxtSPat4:
t - (Spat4EndC);
branch[nxtSpatXit, alu>=0];

* IN [Spat3EndC..Spat4EndC)
* pattern4 = pseudo random numbers
noop;
call[cycleRandV];
RBASE← rbase[SRLink];* pattern4 (random numbers) done by getSpat
branch[nxtSpatXit];

nxtSPatXit:
link ← SRlink;* restore return link, fix up rbase,
subroutine;
RBASE← rbase[defaultRegion];
return,t-(SlastPatC);* return w/ proper branch condition

* January 12, 1979 6:38 PM
STORAGE Test General Subroutines

getSPat:
* Enter w/ T = VA. rtn w/ next pattern in T
%
Currently there are four sets of patterns:
pattern1left cycled 1 bit
pattern2
left cycled 0 bit
pattern3
left cycled va
pattern4
random numbers
Pattern1 and pattern2 return the same value every time getSPat is called, given a constant value for SpatX. Ie., the range for SpatX in pattern 1 is [0..Spat1EndC), and when SpatX is zero, getSPat always returns 1, when SpatX is one, getSPat always returns 2, etc.
Pattern2 is similar to pattern1 except that it is a bitwise complement, ie., a single zero bit with the remaining bits all ones.
Pattern3 returns the current va (treated as a 32 bit number) left cycled. The calling program provides the current va (low 16 bits only) in T. The first time pattern3 is in effect, it returns the current va. The next time nextSpat is called, the cycle count for pattern 3 increments and getSpat returns the va left cycled 1, etc. When the current va is even, it returns the low 16 bits of svaHiX,,currentSva (appropriately cycled) and when it is odd it returns the low 16 bits of currentSva,,sVaHiX (appropriately cycled).
Pattern4 returns a random number.
%
mc[shc.AisT, b2];
mc[
shc.BisT, b3];
set[
shc.countShift, 10];
mc[
shc.maskShiftCount, b4,b5,b6,b7]
mc[
shc.rmt, shc.BisT!];* deal w/ rm,,t

RBASE← rbase[rmForStoreLoops];
SRlink ← link;
top level;
(Spatx)-(Spat1EndC);* see which pattern we are using
branch[getSP2,ALU>=0];
* IN [0..Spat1EndC)
* pattern 1 returns a cycled 1 bit.
branch[getSPXit], t←curSPattern;* nextSpat did our work

getSP2:* return pattern 2 or greater
(Spatx)-(Spat2EndC);
branch[getSP3, ALU>=0];
* IN [Spat1EndC..Spat2EndC)
* pattern 1 returns a cycled 0 bit.
branch[getSPXit], t ← curSPattern;* nextSpat did our work

* January 12, 1979 6:48 PM
getSP3:
(SpatX) - (Spat3EndC);
branch[getSP4, ALU>=0];
* IN [Spat2EndC..Spat3EndC)
%
Pattern3 returns a cycled version of the current va.
If current va is even,
return the left cycle of sVaHix,,currentVa;
otherwise,
return the left cycle of currentVa,,sVaHiX.
Begin by moving the current va into curSpattern, and then construct a shifter control value that will provide the correct cycle value. Always construct a SHC value that cycles rm,,t.
%
curSpattern ← t;* ENTERED W/ T = low 16 bits of va

t ← shc.rmt;* construct SHC constant that will
sSubrScr ← SpatX;* left cycle rm,,t by the correct amount
sSubrScr ← (sSubrScr) - (Spat2EndC);* Spat2EndC is the first valid index for this pattern
sSubrScr ← lsh[sSubrScr, shc.countShift];
sSubrScr ← (sSubrScr) and (shc.maskShiftCount);
t ← t or (sSubrScr);* now we have the correct shc value
SHC ← t;

t ← curSpattern;* we’ll cycle rm,,t
t ← shiftNoMask, sVaHiX;* = lcy[sVaHiX, t, <current cycle count>]
branch[getSPxit], curSpattern ← t;

skpif[R ODD], curSpattern;* decide which half of a cycled va to use
branch[getSP3even];

getSP3odd: * lcy[currentVa,,sVaHix, <current cycle count>]
t ← sVahiX;
t ← shiftNoMask, curSpattern;* lcy[rm,,t, <current shift>];
branch[getSPxit], curSpattern ← t;

getSP3even: * lcy[sVaHiX,,currentVa, <current cycle count>]
t ← curSpattern;
t ← shiftNoMask, sVaHix;* t ← lcy[rm,,t, <current shift>]
branch[getSPxit], curSpattern ← t;

getSP4:
(SpatX) - (Spat4EndC);
branch[getSPXit, ALU>=0];
* IN [Spat3EndC..Spat4EndC)
* pattern4 returns pseudo ranom numbers
noop;
getRandom[];* IN [Spat2EndC..Spat3EndC) (random numbers)
RBASE ← rbase[SpatX];
branch[getSPXit], curSpattern ← t;

getSPXit:
link ← SRlink;
subroutine;
return, RBASE← rbase[defaultRegion];

getCurSpattern: subroutine;* return curSPattern in T
saveReturn[Srlink];
RBASE ← rbase[curSPattern];
t ← curSPattern;
returnUsing[Srlink];


* May 19, 1981 11:28 AM
zeroMemory: subroutine;* zero contents of memory. clobber T, RSCR, RSCR2
q← t;
saveReturn[zeroMemoryRtn];
branch[doSetMemory], t←q;

setMemory: subroutine;
q←t;
saveReturn[zeroMemoryRtn];
doSetMemory:

call[iSmunchCtrl];
setMemL:
call[nextSmunch];* returns t = next sva
skpif[alu#0];
branch[setMemLxit];

cnt ← 17s;* inner loop to zero current munch
rscr ← q;
setMemIL:
store ← t, DBuf ← rscr;
loopuntil[cnt=0&-1, setMemIL], t ← t +1;

branch[setMemL];

setMemLxit:
setMemLRtn:
returnUsing[zeroMemoryRtn];

saveMemAddr: subroutine;* save SvaHi, SvaX
t ← Sva, RBASE ← rbase[SvaHiX];
sVaXold ← t;
t ← SvaHiX;
SvaHiOld ← t;
return, RBASE ← rbase[defaultRegion];

fetchMemAddr: subroutine;* return SvaXold, SvaHiOld in rscr2, rscr
saveReturn[Srlink];
RBASE ← rbase[SvaHiOld];
t ← SvaXold;
rscr2 ← t;
t ← SvaHiOld;
rscr ← t;
returnUsing[Srlink];

getSvaXold: * return value of SvaXold in T
saveReturn[Srlink];
RBASE ← rbase[SvaXold];
t ← SvaXold;
returnUsing[Srlink];