{ file: GcRef.mc last edit: 29-Feb-84 10:42:04 by cal, added uGcZero last edit: 15-Feb-84 12:03:38 by cal, added RefCount Exit 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} uGcZero returns non-zero if entry created {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 ← 8, BRANCH[$, GcLdifptr], c1;{sub has PgCarry compl} Rx ← Rx LRot8, c2;{Rx ← 0800} Ybus ← TT + Rx, CarryBr, c3;{cnt = 62 or 63?} GcLSel: Ybus ← Q, YDisp, BRANCH[$, GcLcntovf], c1; Rx ← RShift1 Rx, SE ← 0, DISP2[GcLdisp], c2;{Rx ← 0400} Rx ← RShift1 Rx, SE ← 0,{stkRef} c3,at[2,4,GcLdisp];{Rx ← 0200} 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[GcLcoll, 3], c2; GcLempty: {build a new entry with a cnt of 1} Rx ← uTT3FF, c1;{Rx ← 03FF} uGcZero ← Rx, c2; TT ← uGcLhi , c3; TT ← LShift1 TT , SE ← 0, c1; TT ← TT + Rx + 1, c2;{TT ← TT + 400} Rx ← LShift1 Rx + 1, SE ← 1, GOTO[GcLSel], c3;{Rx ← 0801} { 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[$, CB2], 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 }