Google
 

Trailing-Edge - PDP-10 Archives - BB-H138C-BM - language-sources/lnkhsh.mac
There are 38 other files named lnkhsh.mac in the archive. Click here to see a list.
TITLE LNKHSH - SYMBOL TABLE HASH SEARCH
SUBTTL	D.M.NIXON/DMN/JLd/JNG/DZN	24-Aug-79


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973, 1979 BY DIGITAL EQUIPMENT CORPORATION


SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL

ENTRY	TRYSYM


CUSTVR==0		;CUSTOMER VERSION
DECVER==4		;DEC VERSION
DECMVR==1		;DEC MINOR VERSION
DECEVR==1220		;DEC EDIT VERSION


SEGMENT
SUBTTL	REVISION HISTORY


;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;162	CHECK FOR CALLING TRYSYM WITH 0 NAME

;START OF VERSION 2B
;271	Suppress searching Bound Globals when rehashing
;272	Continue to issue "RGS" message only if user could
;	have done something about it -- changed /HASHSIZE.
;404	Insert edit 340, which vanished.

;START OF VERSION 2C
;476	Insert missing FTOVERLAY conditionals.
;477	Count bound globals when computing HSPACE after rehashing.
;530	Get triplet flags definitions right
;557	Clean up the listing for release.

;START OF VERSION 3A
;560	Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)


;START OF VERSION 4
;731	SEARCH MACTEN,UUOSYM
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)

;START OF VERSION 4A
;1174	Label and clean up all error messages.
;1217	Clean up the listings for release.
;1220	Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL	SYMBOL TABLE HASH SEARCH


;ONE AUXILIARY TABLE IS USED (HASHTB)
;		LH - 18 BIT HASH TOTAL FOR SYMBOL
;		RH - LOCATION OF THE WORD IN NAMTAB, RELATIVE TO
;			       THE START OF NAMTAB
;	NAMTAB - THE NAMES, IN SIXBIT (USUALLY GS.LB)

;AN ATTEMPT IS MADE TO FIND AN ENTRY MATCHING NAMWRD IN THE FOLLOWING MANNER:
;	1) HASH-TOTAL NAMWRD BY XORING ALL THE WORDS TOGETHER, THEN XORING THE
;	   HALVES OF THE RESULT.
;	2) DIVIDE THE HASH-TOTAL BY THE SIZE OF HASHTB (HT.PRM)
;	   THE QUOTIENT BECOMES Q, THE REMAINDER R(0).
;	3) IF LH HASHTB (R) IS UNEQUAL TO THE HASH-TOTAL, GO TO STEP 5.
;	4) IF THE NAMTAB ENTRY, WHOSE RELATIVE ADDRESS IS IN THE RH OF
;	   HASHTB (R), IS EQUAL TO NAMWRD, THE MATCH IS MADE
;	   AND THE ROUTINE EXITS; ELSE GO TO STEP 6.
;	5) IF HASHTB (R) IS ZERO, THERE IS NO MATCHING ENTRY.
;	6) COMPUTE A NEW R BY ADDING Q TO R.  NOTE THAT
;		R(I) = R(0) + Q*I
;	7) STEPS 3 THRU 6 ARE EXECUTED "HT.PRM" TIMES, THEN NO MORE
;	   ATTEMPTS ARE MADE.
;HERE TO SEARCH GLOBAL SYMBOL TABLE FOR AN ENTRY

;ENTET VIA	PUSHJ P,TRYSYM
;W1 = FLAGS (TESTED FOR LONG SYMBOL BY PT.EXT)
;W2 = FIRST 6 CHARACTERS OF SYMBOL NAME
;W3 = VALUE (IF NOT EXTENDED) NOT USED
;W3 = POINTER (IF EXTENDED) TO EXTENDED SYMBOL BLOCK IN GS 

;RETURNS ARE 
;+1 SYMBOL NOT IN TABLE
;+2 SYMBOL IN TABLE BUT UNDEFINED
;+3 SYMBOL IN TABLE AND DEFINED

;RETURNS WITH FOLLOWING SETUP
;P1= QUOTIENT IN SEARCH
;P2= REMAINDER IN SEARCH
;P3= HASH TOTAL
;P4= NM12SZ PRIME NUMBER WITH WHICH TO HASH
;ALSO USES T1 _ T4

TRYSYM:	SKIPGE	HSPACE		;ENOUGH SPACE IN TABLE TO MAKE IT WORTHWHILE?
	JRST	REHASH		;NO, EXPAND TABLE FIRST
	JUMPE	W2,E$$ISN	;[1174] 0 IS ILLEGAL SYMBOL
TRYS1H:	PUSHJ	P,HASH		;INITIALIZE FOR SEARCH
	JRST	TRYS1B

TRYS1A:	ADD	P2,P1		;R_R+Q
	CAML	P2,HT.PRM	;STILL INSIDE TABLE
	SUB	P2,HT.PRM	;NO INSURE THAT IT IS

TRYS1B:	MOVS	T1,@HT.PTR	;GET HASH TOTAL (AND PTR)
	CAIN	P3,(T1)		;IS THIS THE ONE WE WANT?
	JRST	COMPAR		;MAYBE, CHECK THE SYMBOL NAME

	JUMPE	T1,NOFIND	;EXIT IF NULL ENTRY IN HASHTB

NOMACH:	SOJG	P4,TRYS1A	;YES, LOOP
				;TRIED ALL THE TABLE - YOU LOSE
NOFIND:
IFN FTOVERLAY,<
	SKIPGE	BG.SCH		;ANY BOUND GLOBALS WE CAN LOOK AT?
	JRST	TRY.BG##	;YES, TRY THEM
>
	POPJ	P,		;NON-SKIP RETURN

MATCH:	HRL	P2,P1		;SAVE Q IN R
	MOVE	P1,T1		;GET ADDRESS OF SYMBOL
	MOVE	T1,(P1)		;GET PRIMARY FLAGS
	TXNN	T1,PS.REQ!PS.UDF	;SEE IF DEFINED YET
CPOPJ2:	AOS	(P)		;YES
CPOPJ1:	AOS	(P)		;SKIP RETURN
CPOPJ:	POPJ	P,
COMPAR:	SKIPGE	HSPACE		;IF NO SPACE IN TABLE
	JRST	NOMACH		;WE ARE REHASHING ONLY

	HLRZ	T1,T1		;GET ADDRESS OF SYMBOL BLOCK
	ADD	T1,NAMLOC	;LOCATED IN CORE
	CAME	W2,1(T1)	;COMPARE FIRST 6 CHAR OF NAME
	JRST	NOMACH		;NOT THE SAME  KEEP TRYING
				;TEST FOR LONG SYMBOL
	MOVE	T2,0(T1)	;GET FLAGS
	TXNN	T2,PT.EXT	;EXTENDED (MUST BE IF LONG)
	JRST	MATCH		;NO
	MOVE	T2,.L(T1)	;GET NEXT TRIPLET FLAGS
	TXNE	T2,S.SYM	;MUST BE SYMBOL TYPE
	TXNN	T2,S.LNM	;AND EXTENDED NAME AT THAT
	JRST	MATCH		;NO, WE'VE GOT IT ALL
IFE .EXSYM,<
E$$ESN::.ERR.	(MS,,V%L,L%F,S%F,ESN,<Extended symbol not expected>) ;[1174]
>
IFN .EXSYM,<
	MOVE	T2,W3		;GET LONG SYMBOL POINTER
LCOMP0:	ADDI	T1,.L		;ADVANCE
	ADDI	T2,.L
	MOVE	T3,(T1)		;FLAGS
	MOVE	T4,(T2)		;DITTO
	TXNE	T3,S.SYM	;MUST BE SYMBOL TYPE
	TXNN	T3,S.LNM	;AND NAME
	JRST	[TXNE	T4,S.SYM	;2ND SYMBOL SAME TESTS
		TXNN	T4,S.LNM
		JRST	MATCH		;BOTH FINISHED
		JRST	NOMACH]		;NOT BOTH DONE
	TXNE	T4,S.SYM
	TXNN	T4,S.LNM
	JRST	NOMACH		;2ND NOT SAME LENGTH
	DMOVE	T3,1(T1)	;GET SYMBOL NAME
	CAMN	T3,1(T2)	;COMPARE
	CAME	T4,2(T2)
	JRST	NOMACH		;FAILED
	MOVE	T3,0(T1)	;GET FLAGS BACK
	MOVE	T4,0(T2)
	TXNE	T3,S.LST	;TEST FOR LAST TRIPLET
	JRST	[TXNN	T4,S.LST	;YES, TRY OTHER
		JRST	NOMACH		;NOT BOTH
		JRST	MATCH]		;BOTH
	TXNE	T4,S.LST	;LAST FOR 2ND?
	JRST	NOMACH		;YES, SO DIF LENGTH
	JRST	LCOMP0		;KEEP ON TRYING
>;END OF IFN .EXSYM
;INITIALIZE  FOR SEARCH

HASH:	MOVE	P3,W2		;GET FIRST 6 CHARS.
	TXNN	W1,PT.EXT	;LONG SYMBOL?
	JRST	SHASH		;NO
IFE .EXSYM,<
E02ESN::.ERR.	(MS,,V%L,L%F,S%F,ESN) ;[1174]
>
IFN .EXSYM,<
	MOVE	T1,W3		;GET POINTER
LHASH:	ADDI	T1,.L		;ADVANCE
	MOVE	T2,0(T1)	;GET FLAGS
	TXNE	T2,S.SYM	;SYMBOL TYPE
	TXNN	T2,S.LNM	;AND NAME
	JRST	SHASH		;GOT IT ALL
	XOR	P3,1(T1)	;FOLD IN
	XOR	P3,2(T1)
	TXNN	T2,S.LST	;DONE IF END
	JRST	LHASH		;KEEP GOING
>;END OF IFN .EXSYM

SHASH:	HLRZ	P1,P3
	HRRZ	P3,P3
	CAME	P1,P3		;WE DON'T WANT 0
	XORB	P1,P3
	MOVE	P4,HT.PRM	;ONLY 18 BITS AT MOST
	IDIVI	P1,(P4)		;REMAINDER IN P1
	JUMPE	P1,[AOJA P1,CPOPJ]	;ENSURE P1 NEVER ZERO
	CAIGE	P1,(P4)		;IS QUOTIENT LARGER THAN PRIME?
	POPJ	P,		;NO, RETURN
	SUBI	P1,(P4)		;STEP DOWN AND TRY AGAIN
	JRST	.-4		;ONLY HAPPENS OF PRIME L.T. ^D500
;HERE TO RE-HASH THE GLOBAL TABLE

REHASH:
IFN FTOVERLAY,<
	PUSH	P,BG.SCH	;REMEMBER IF BG EXITS
	SETZM	BG.SCH		;SUPPRESS SEARCHING IT
> ;END IFN FTOVERLAY
	PUSH	P,W1		;SAVE CURRENT SYMBOL INFO
	PUSH	P,W2
	PUSH	P,W3
	PUSH	P,R3		;AND A WORK ACC
	MOVN	R3,HT.PRM	;GET NUMBER
	HRLZ	R3,R3		;FIRST PART (LHS) OF AOBJN POINTER
	PUSH	P,HT.PRM	;SAVE OLD SIZE
	MOVE	T1,HT.PRM	;GET PREV
	LSH	T1,-1		;GET 50% OF IT
	SUBI	T1,^D50		;ALLOW SOME LEEWAY
	ADDM	T1,HT.PRM	;SO WE GET NEXT PRIME 50% LARGER
	PUSHJ	P,NPRIME##	;GET NEXT PRIME NUMBER FOR HASH SIZE
	MOVE	T1,GSYM		;SEE IF INITIAL /HASHSIZE:
	SUB	T1,@GS.LB	;YES IF SAME NUMBER
	JUMPE	T1,REHSH0	;SO DON'T TELL USER
	MOVE	T1,0(P)		;PUT OLD SIZE HERE FOR MESSAGE
E$$RGS::.ERR.	(MS,.EC,V%L,L%I,S%I,RGS,<Rehashing global symbol table from >) ;[1174]
	.ETC.	(DEC,.EC!.EP,,,,T1)
	.ETC.	(STR,.EC,,,,,< to >)
	.ETC.	(DEC,.EP,,,,HT.PRM)
REHSH0:	MOVE	T2,HT.PRM	;GET NEW NUMBER
	ADDI	T2,.L-1
	IDIVI	T2,.L
	IMULI	T2,.L
	PUSHJ	P,GS.GET##	;GET SPACE
	HRR	R3,HT.PTR	;COMPLETE AOBJN POINTER TO OLD ARRAY
	PUSH	P,HT.PTR	;SAVE OLD POSITION SO WE CAN GIVE IT BACK
	HRRM	T1,HT.PTR	;NEW TABLE OF HASH TOTALS & POINTERS
REHSH1:	SKIPN	T1,(R3)		;GET POINTER
	JRST	REHSH3		;NOTHING THERE
	PUSH	P,T1		;SAVE IT
	ADD	T1,NAMLOC	;RELOCATE
	TMOVE	W1,0(T1)	;GET FLAGS, SYMBOL, VALUE
	TXNN	W1,PT.EXT	;EXTENDED SYMBOL?
	JRST	REHSH2		;NO
	MOVE	T2,.L(T1)	;YES, BUT WE ONLY CARE ABOUT LONG NAMES HERE
	TXNE	T2,S.SYM
	TXNN	T2,S.LNM	;SO IGNORE COMMON, ETC
	JRST	[TXZ	W1,PT.EXT	;NOT EXTENDED NAME
		JRST	REHSH2]		;SO REMOVE FLAG
IFE .EXSYM,<
E03ESN::.ERR.	(MS,,V%L,L%F,S%F,ESN) ;[1174]
>
	HRRZ	W3,T1		;POINT TO SYMBOL
REHSH2:	PUSHJ	P,TRYS1H	;HASH WITH NEW SIZE AND INSERT IN TABLE
	POP	P,T1		;OLD POINTER
	HRL	T1,P3		;NEW HASH TOTAL
	MOVEM	T1,@HT.PTR	;STORE IN TABLE
REHSH3:	AOBJN	R3,REHSH1	;GET NEXT
	POP	P,T1		;GET LOCATION OF OLD TABLE
	HRRZ	T1,T1		;REMOVE INDEX IN LHS
	POP	P,T2		;AND SIZE
	ADDI	T2,.L-1		;BUT PUT BACK AS MULTIPLE OF .L
	IDIVI	T2,.L
	IMULI	T2,.L
	PUSHJ	P,GS.RET##	;GIVE IT BACK
	POP	P,R3		;RESTORE ACCS
	POP	P,W3		;RESTORE OLD SYMBOL
	POP	P,W2
	POP	P,W1
IFN FTOVERLAY,<
	POP	P,BG.SCH	;REENABLE BOUND GLOBAL SEARCH
> ;END IFN FTOVERLAY
	MOVE	T1,HT.PRM	;GET NEW SIZE
	IMUL	T1,HSFACT	;SEE HOW FULL IS FULL
	IDIVI	T1,^D100
	SUB	T1,GSYM		;MINUS WHATS THERE ALREADY
IFN FTOVERLAY,<
	SUB	T1,BSYM		;COUNT BOUND GLOBALS IN THIS TABLE
> ;END IFN FTOVERLAY
	MOVEM	T1,HSPACE	;RESET  SPACE
	JRST	TRYSYM		;AND TRY AGAIN
E$$ISN::.ERR.	(MS,.EC,V%L,L%F,S%F,ISN,<Illegal symbol name >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2) ;[1174]
	.ETC.	(JMP,,,,,.ETIMF##) ;[1174]
SUBTTL	THE END


	END