{
file: GcRef.mc
last edit: 25-Aug-83 14:30:28 by cal, added non-lisp ptr check{virtual range}
last edit: 5-Aug-83 15:33:49 by charnley
put into system: 28-Jun-83 11:12:18
created: 2-Jun-83 14:36:05 by charnley
}
SetTask[0];
{*******************************************************************
GCREF
*******************************************************************}
{ alpha contains code: 0 addRef, 1 delRef, 2 stkRef
TOSH contains high address bits
TOS contains low address bits
replaces TOSH,,TOS with NIL except in the case that the new value
has stk = 0, and refcnt = 0, in which case stack left alone
}
GcRef: opcode[25'b],
TT ← RShift1 0, SE ← 1, c1; {set sign bit of Q}
Q ← TT + ibNA, L1 ← L1.NoFixes, c2;
Rx ← TOSH and 0FF, L2 ← L2.gcref, c3;
TT ← TOS, CALL[GcLookup], c1;
{*******************************************************************
GCLOOKUP SUBROUTINE
*******************************************************************}
{ Q contains code: 0 addRef, 1 delRef, 2 stkRef {sign bit = 1 if opcode}
Rx contains high address bits {will be put into uGcLhi}
if Rx = 0, then treat as atom
TT has low address bits {will be put in uGcLlo}
uGcLov returns non-zero if overflow entry added {for non-opcode}
TT returns 0 in the case that the new value
has stk = 0, and refcnt = 0
L2 contains caller
}
{
The address of a type table word is:
PageTableBase + Top 15 address bits
The format of a type table word is:
bit 0 -- Atom
bit 1 -- Don't RefCnt, goto ufn
The address of a hash table entry is:
HashTableBase + ( Low 16 address bits ) / 2
The format of a hash table entry is:
bits
0..5 -- Count {63 = max count, if count is one
entry is not in hash table}
6 -- Stack Ref bit
7..14 -- eight high address bits
15 -- Collision bit, goto ufn
}
GcLookup:
uGcLlo ← TT, c2;
TT ← TT and ~0FF, c3;
uGcLhi ← Rx, ZeroBr, c1;
rhRx ← crhHashTable, BRANCH[$, GcLHighZero], c2;
rhTT ← crhTypeTable, TT ← TT or Rx, c3;
Xbus ← Rx LRot12, XDisp, c1;
TT ← TT LRot8, DISP4[GcLTest, 3], c2;
TT ← RShift1 TT, SE ← 1,{or 80 with page}, c3, at[03, 10, GcLTest];
MAR ← [rhTT, TT + 0], c1;{read Type table}
Rx ← uGcLlo, c2;
TT{Probe} ← MD, c3;
TT ← LShift1 TT, NegBr,{test sign bit} c1;
Ybus ← TT, NegBr, BRANCH[$, GcLatom], c2;{test 4000 bit}
Rx ← RShift1 Rx, SE ← 0, BRANCH[$, GcLpunt1], c3;
MAR ← [rhRx, Rx + 0], c1;{read hash table}
uGcLTem ← Rx, c2;{save HT addr}
TT{Entry} ← MD, c3;
Ybus ← TT and 1, NZeroBr, c1;{test coll bit}
Ybus ← TT, ZeroBr, BRANCH[$, GcLcoll], c2;{test empty}
Rx ← uGcLhi, BRANCH[$, GcLempty], c3;
Rx ← LShift1 Rx, SE ← 0, c1;
Rx ← RShift1 Rx xor TT, SE ← 0, c2;
Rx ← Rx - 1, PgCarryBr, c3;{compare hi addr}
Rx ← 4, BRANCH[$, GcLdifptr], c1;{sub has PgCarry compl}
Rx ← Rx LRot8, c2;{Rx ← 0400}
Ybus ← TT + Rx, CarryBr, c3;{cnt = max?}
GcLSel: Ybus ← Q, YDisp, BRANCH[$, GcLcntovf], c1;
Noop, DISP2[GcLdisp], c2;
Rx ← RShift1 Rx, SE ← 0,{stkRef} c3,at[2,4,GcLdisp];
Q ← TT or Rx, c1;
Noop, GOTO[GcLpw], c2;
Q ← TT + Rx, GOTO[GcLcom], {addRef} c3,at[0,4,GcLdisp];
Q ← TT - Rx, GOTO[GcLcom], {delRef} c3,at[1,4,GcLdisp];
GcLcom: TT ← Q and ~u1FF, c1;{TT ← cnt,,stk}
Ybus ← TT xor Rx, ZeroBr, c2;{TT = 1,,0 ?}
GcLpw: Rx ← uGcLTem, BRANCH[$, GcLc1s0], c3;{get HT addr}
MAR ← [rhRx, Rx + 0], c1;
MDR ← TT ← Q, c2;
GcLfin: TT ← TT and ~u1FF, L2Disp, GOTO[GcLend], c3;
{EXCEPTIONS}
GcLc1s0: MAR ← [rhRx, Rx + 0], c1;
MDR ← TT ← 0, GOTO[GcLatom], c2;{store 0}
GcLatom: TT ← TT xor ~TT{non-zero}, L2Disp, CANCELBR[GcLend], c3;
GcLHighZero: TT ← TT xor ~TT{non-zero}, L2Disp, CANCELBR[GcLend], c3;
GcLcntovf:
Noop, CANCELBR[GcLatom, 3], c2;
GcLempty: {build a new entry with a cnt of 1}
Rx ← 4, c1;
Rx ← Rx LRot8, c2;{leave Rx setup for GcLSel}
TT ← uGcLhi , c3;
TT ← LShift1 TT , SE ← 0, c1;
TT ← TT or Rx , c2;
Noop, GOTO[GcLSel], c3;
{ Entry into overflow table here }
GcLpunt1: Noop, c1;
GcLdifptr: Noop, c2;
GcLcoll: Rx ← Q, NegBr, CANCELBR[$], c3;{test if opcode}
Rx ← Rx LRot8, BRANCH[$, GcLufn], c1;
TT ← 0A0, c2;
TT ← TT LRot8 c3;{build ov table addr}
GcLfov: MAR ← [rhTT, TT + 0], c1;
Noop, c2;
Q ← MD, c3;
Ybus ← Q, ZeroBr, c1;{is ov empty?}
uGcLov ← TT, BRANCH[GcLnext, $], c2;{uGcLov # 0}
Q ← uGcLhi, c3;
MAR ← [rhTT, TT + 0], c1;
MDR ← Rx or Q, c2;
Rx ← uGcLlo, c3;
MAR ← [rhTT, TT + 1], c1;
MDR ← Rx, LOOPHOLE[wok], CANCELBR[$, 0], c2;
GcLret:
L2Disp, GOTO[GcLend], c3;
GcLnext: TT ← TT + 2, GOTO[GcLfov], c3;
GcLufn: Rx ← 25'b, GOTO[ufn3], {only occurs if GcRef opcode} c2;
GcLend: RET[GcLookRet],{** EXIT HERE **} c1;
Ybus ← TT, ZeroBr, Xbus ← ib, c2,at[L2.gcref,10,GcLookRet];
PC ← PC + 1, BRANCH[$, GcRlvTOS], c3;
TOS ← 0, c1;
TOSH ← 0, IBDisp, L2 ← L2.0, GOTO[DNI.nop], c2;
GcRlvTOS: Noop, GOTO[IB.nop], c1;
Ybus ← Q, NegBr, GOTO[GcLOut], c3, at[07, 10, GcLTest];
Ybus ← Q, NegBr, GOTO[GcLOut], c3, at[0B, 10, GcLTest];
Ybus ← Q, NegBr, GOTO[GcLOut], c3, at[0F, 10, GcLTest];
GcLOut:
BRANCH[GcLnotop, GcLop], c1;
GcLop: Rx ← 25'b, GOTO[ufn3], c2;
GcLnotop: GOTO[GcLret], c2;
{ E N D }