{ 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; , c1; TT _ TT LRot8, c2; TT _ RShift1 TT, getTypemsBit,{or with page}, c3,; 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, getHashmsBit, 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[GcLcomx], CarryBr, {delRef} c3,at[1,4,GcLdisp]; GcLcomx: TT _ Q and ~u1FF, BRANCH[GcdelOV, GcLcom1], c1;{TT _ cnt,,stk} GcLcom: TT _ Q and ~u1FF, c1;{TT _ cnt,,stk} GcLcom1: 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 } GcdelOV: GOTO[GcLcoll], c2; GcLpunt1: , c1; GcLdifptr: , 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} } rhTT _ hashOVrh, TT _ hashOVr, c2; TT _ TT LRot8, c3; GcLfov: MAR _ [rhTT, TT + 0], c1; Noop, c2; Q _ MD, c3; Ybus _ Q, ZeroBr, c1;{is ov empty?} uGcLov _ PC xor ~PC, BRANCH[GcLnext, $], c2;{uGcLov # 0} Q _ uGcLhi, c3; MAR _ [rhTT, TT + 0], c1; MDR _ Rx or Q, c2; Rx _ uGcLlo, c3; MAR _ TT _ [rhTT, TT + 1], c1; MDR _ Rx, LOOPHOLE[wok], CANCELBR[$, 2], c2; {GcLret:} TT _ TT xor ~TT, 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; { E N D }