Trailing-Edge
-
PDP-10 Archives
-
ap-c796e-sb
-
gt1n.bli
There are 18 other files named gt1n.bli in the archive. Click here to see a list.
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!
!COPYRIGHT (C) 1977,1978 BY DIGITAL EQUIPMENT CORPORATION
!FILENAME: H1GTRE.BLI
!DATE: 24 MAY 73 MGM/FLD
%3.% GLOBAL BIND H1GTV=2; !MODULE VERSION NUMBER
! REVISION HISTORY:
!
! 9-19-77 ROUTINE GENGRAPH IS MODIFIED TO FIX BUG#46,
! NESTED IF THEN ELSE EXPRESSIONS.(COMMON SUB-
! EXPRESSIONS).
!
! 6-2-77 ROUTINE GTGOTM IS MODIFIED TO FIX BUG #11
! IN BLISS10.DOC.GADD AND GSTO WAS REPLACED
! BY GOTM AND DID NO GOOD. THIS WAS DONE FOR OPTIMIZATION.
! NOW IN THIS CASE FORGET ABOUT OPTIMIZATION.
! CASE IS X[]_.X[]+2;.
!
! GRAPH TABLE GENERATION AND INTERPRETATION ROUTINES
!----------------------------------------------------
ROUTINE TREGP(X)= (((.X AND NOT(#37^16)) EQL 0) AND (.X<RTEF> GEQ 16));
%3.1% GLOBAL ROUTINE FIXOCCF(L,F,T)=
BEGIN LOCAL YR;
! THIS ROUTINE FIXES THE <OCCF> AND <USEF> FIELDS
! IN THOSE CASES WHERE A NODE IS RE-FOUND BEFORE ITS
! USE HAS GONE TO ZERO.
INCR I FROM .F TO .T DO
IF .GT[.L,.I]<LEFTHALF> EQL GTLEX THEN
BEGIN
GT[.GT[.L,.I]<LINKF>,0]<OCCF> _
MAXER(.GT[.GT[.L,.I]<LINKF>,0]<OCCF>-1,0);
IF .GT[.GT[.L,.I]<LINKF>,0]<RESULTF> THEN
IF (YR_TREGNUM(.GT[.GT[.L,.I]<LINKF>,1])) GEQ 16 THEN
DUN(.YR);
END
ELSE IF(YR_TREGNUM(.GT[.L,.I])) GEQ 16 THEN DUN(.YR);
END;
ROUTINE FIXALLOCCF(L)=
BEGIN LOCAL N; N_.GT[.L,0]<SUBNF>+2;
INCR I FROM 3 TO .N DO
IF .GT[.L,.I]<LEFTHALF> EQL GTLEX THEN
IF NOT .GT[.GT[.L,.I]<LINKF>,0]<RESULTF> THEN
FIXALLOCCF(.GT[.L,.I]<LINKF>);
FIXOCCF(.L,3,.N)
END;
%3.1% GLOBAL ROUTINE MAKGT(N,OP,PTR,DIR)=
BEGIN LOCAL S,L,GTL;
! THIS ROUTINE BUILDS A GRAPH-TABLE ENTRY IN CASE THERE
! WASN'T ONE. THE SUBNODE ENTRIES ARE POINTED TO BY THE
! VARIABLE PTR -- THERE DIRECTION RELATIVE TO PTR IS KEPT
! IN DIR.
S_2+.N/2;
GT[L_GETSPACE(.S),0]_ .GRAPHHEAD[GTL_GTHASH(.OP)];
GRAPHHEAD[.GTL]_.L;
GT[.L,0]<OCCF>_1;
GT[.L,0]<SUBNF>_.N;
GT[.L,1]_0;
GT[.L,2]_.OP;
INCR I FROM 0 TO .N-1 DO
GT[.L,.I+3]_@(.PTR+.I*.DIR);
.L
END;
ROUTINE GTGOTM(O1,O2,OP)=
BEGIN LOCAL L1,L2,L3,L4,L5; BIND NNDM=7^33;
!
! THIS ROUTINE ATTEMPTS TO RECOGNIZE AND OPTIMIZE THE
! CASES IN WHICH A 'TO-MEMORY' OPERATOR MAY BE
! GENERATED. A SPECIAL GT-NODE IS BUILT IN THESE CASES
! SO THAT A SPECIAL CODE GENERATOR, 'GOTM', WILL BE
! BE CALLED.
!
ROUTINE OKOP(X)=(.X<HPRIORITY> GTR #21 AND .X<HPRIORITY> LSS #37
AND .X<HPRIORITY> NEQ #30);
ROUTINE NNTYPE(X)=(.X<LEFTHALF> EQL HNEG OR .X<LEFTHALF> EQL HNOT);
ROUTINE DOTTYPE(X)= .X<HPRIORITY>EQL #21;
FUNCTION FIND(E,ATT)=
BEGIN
IF NNTYPE(.GT[.ATT,2]) THEN
IF .GT[.ATT,3]<LEFTHALF> NEQ GTLEX
THEN RETURN 0 ELSE ATT_.GT[.ATT,3]<LINKF>;
L5_IF .GT[.ATT,3]<LEFTHALF> EQL GTLEX
THEN .GT[.ATT,3]<LINKF> ELSE 0;
IF DOTTYPE(.GT[.ATT,2]) THEN
(IF .L5 NEQ 0 THEN NOT DOTTYPE(.GT[.L5,2]) ELSE 1) AND
(.GT[.ATT,3] EQL .E)
ELSE 0
END;
IF .OP<LEFTHALF> EQL HSTO THEN
IF (.O1 AND NNDM) EQL 0 THEN
IF .O2<LEFTHALF> EQL GTLEX THEN
IF OKOP(.GT[L1_.O2<LINKF>,2]) THEN
IF NOT(.GT[.L1,0]<RESULTF>) THEN
BEGIN L4_4-.GT[.L1,2]<HUNARY>;
IF .GT[.L1,.L4]<LEFTHALF> EQL GTLEX THEN
IF FIND(.O1,.GT[.L1,.L4]<LINKF>) THEN
BEGIN ! PHEW--WE GOT ONE
! DONOT BOTHER TO OPTIMIZE X[1]_.X[1]+5
! BECAUSE IT DOES NOT ANYWAY.
!IT GOES TO GOTM,GADD,GSTO AND GOING TO GOTM UNNECESSARY
! 5_27_77
IF .STUTYPE EQL 1 AND .O1<LEFTHALF> EQL GTLEX
THEN (STUTYPE_0; RETURN 0);
L2_MAKGT(4,NGOTM<0,0>,GT[.L1,2],+1);
GT[.L2,4]_ IF .GT[.L1,.L4]<LEFTHALF> EQL GTLEX
THEN .GT[.GT[.L1,.L4]<LINKF>,0]<OCCF> LEQ 1 ELSE 1;
GT[.L2,4]<LEFTHALF>_.L5;
GT[.L2,5]_.GT[.L1,.L4];
GT[.L2,6]_ IF .OP<HUNARY>
THEN 0 ELSE .GT[.L1,3];
GT[.L1,0]<OCCF>_MAXER(.GT[.L1,0]<OCCF>-1,0);
RETURN (GTLEX^18 + .L2)
END;
END;
END;
%3.1% GLOBAL ROUTINE GENGRAPH(OP,N)=
BEGIN LOCAL S,GTL,L,X,XR,YR;
EXTERNAL NOIFOPT;
!
! THIS ROUTINE GENERATES THE GRAPH TABLE AND RETURNS A
! GRAPH-TABLE LEXEME FOR THE (SUB) TREE(S). BEFORE A
! NEW ENTRY IS MADE THE EXISTING TABLE IS SEARCHED
! FOR A COMMON SUB-EXPRESSION, AND, IF FOUND, THE LEXEME
! FOR THIS ENTRY IS RETURNED AFTEN APPROPRIATE ADJUSTMENT
! OF THE OCCURRENCE COUNTS.
!
IDCHECKER(OP,.N);
IF NOT(.CODETOG) THEN RETURN LITLEXEME(0);
IF NOT .NOIFOPT %9-19-77%
THEN
BEGIN
L_.GRAPHHEAD[GTL_GTHASH(.OP)];
IF (X_GTGOTM(@(OP-2),@(OP-1),@OP)) NEQ 0 THEN RETURN .X;
WHILE .L NEQ 0 DO
BEGIN
IF .OP EQL .GT[.L,2] THEN
BEGIN
X_ INCR I FROM 1 TO .N DO
IF @(OP-.I) NEQ .GT[.L,.I+2] THEN BREAK 0
ELSE IF TREGP(@(OP-.I)) THEN BREAK 0;
IF .X NEQ 0 THEN
!SUCCESS, WE HAVE FOUND A MATCHING ENTRY.
BEGIN
IF (GT[.L,0]<OCCF>_.GT[.L,0]<OCCF>+1) GTR 1^8-1 THEN ERROR(.NSYM,#773);
IF .GT[.L,0]<RESULTF> THEN
IF (XR_TREGNUM(.GT[.L,1])) GEQ 16 THEN
INCRUSEN(.XR);
IF .GT[.L,0]<RESULTF> THEN FIXALLOCCF(.L) ELSE
IF .GT[.L,0]<OCCF> GTR 1 THEN FIXOCCF(.L,3,.N+2);
RETURN (GTLEX^18+.L)
END
END;
L_.GT[.L,0]<LINKF>;
END;
END;
!IF WE REACH THIS POINT WE HAVE SEARCHED THE ENTIRE GRAPH TABLE (SUB-LIST)
! AND HAVE NOT FOUND A COMMON SUBEXPRESSION. THEREFORE WE CREATE
! A GRAPH TABLE ENTRY AND LINK IT INTO THE LIST.
!
MAKGT(.N,.OP,OP-1,-1)+GTLEX^18
END;
%3.1% GLOBAL ROUTINE GTPURGE(TOG)=
BEGIN LOCAL L,L1,L2;
!
! THIS ROUTINE PURGES THE GRAPH TABLE OF ALL ENTRIES WHICH
! DO NOT HAVE VALID RESULTS STILL HELD IN REGISTERS OR
! ARE CONSTITUENTS OF SUCH RESULTS. IT OPERATES BY FIRST
! MARKING ALL SUCH ENTRIES AND THEN RELEASING ALL UNMARKED
! ENTRIES.
!
! DEPENDING ON THE VALUE OF 'TOG' WE DO A MORE OR
! LESS DRASTIC PURGE (2=>MORE, 0=>LESS). IN PARTICULAR
! TOG=0: WE SAVE ANY ENTRY WITH A RESULT
! STILL CONTAINED IN A REG.
! TOG=1: WE SAVE ONLT THOSE ENTRIES WITH A NON-ZERO
! 'SAVE' FIELD -- IE, THOSE ENTRIES BEING
! PRESERVED ACROSS A 'FORK'.
! TOG=2: WE SAVE ONLY THOSE ENTRIES WITH A
! SAVE FIELD VALUE GREATER THAN ONE,
! THIS IS USUALLY THE CASE JUST BEFIRE
! TERMINATING A FORK.
!
ROUTINE GTMARK(GTE)=
BEGIN LOCAL F;
!
! THIS ROUTINE PROPAGATES MARK BITS DOWN AND
! FUNNYBITS BACK UP TO PARENTS.
!
F_.GT[.GTE,0]<FUNNYBIT>;
IF .GT[.GTE,0]<MARKBIT> THEN RETURN .F;
INCR I FROM 3 TO .GT[.GTE,0]<SUBNF>+2 DO
IF .GT[.GTE,.I]<LEFTHALF> EQL GTLEX THEN
F_.F OR GTMARK(.GT[.GTE,.I]<LINKF>);
GT[.GTE,0]<MARKBIT>_1;
GT[.GTE,0]<FUNNYBIT>_.F;
.F
END;
INCR I FROM 0 TO GTMASK DO
BEGIN
L_.GRAPHHEAD[.I];
WHILE .L NEQ 0 DO
BEGIN
IF .GT[.L,0]<OCCF> NEQ 0 THEN GTMARK(.L) ELSE
CASE .TOG OF
SET
IF .GT[.L,0]<ROSF> NEQ 0 THEN
IF NOT .GT[.L,0]<RESULTF> THEN GTMARK(.L) ELSE
IF TREGNUM(.GT[.L,1]) GEQ 16 THEN GTMARK(.L);
IF .GT[.L,0]<SAVGEF> GTR 0 THEN GTMARK(.L);
IF .GT[.L,0]<SAVGEF> GTR 1 THEN GTMARK(.L);
TES;
L_.GT[.L,0]<LINKF>;
END;
END;
INCR I FROM 0 TO GTMASK DO
BEGIN
L_.GRAPHHEAD[.I]; GRAPHHEAD[.I]_0;
WHILE .L NEQ 0 DO
BEGIN
L1_.GT[.L,0]<LINKF>;
IF .GT[.L,0]<MARKBIT>
THEN
BEGIN
GT[.L,0]<LINKF>_.GRAPHHEAD[.I]; GRAPHHEAD[.I]_.L;
IF .GT[.L,0]<FUNNYBIT> THEN
BEGIN
GT[.L,0]<RESULTF>_0; GT[.L,0]<FUNNYBIT>_0;
IF (L2_TREGNUM(.GT[.L,1])) GEQ 16 THEN
SCAN( CTRCTH(.L2),
.L,GTLEXP,ERASE)
END;
GT[.L,0]<MARKBIT>_0;
END
ELSE
BEGIN
IF (L2_TREGNUM(.GT[.L,1])) GEQ 16 THEN
SCAN ( CTRCTH(.L2),
.L,GTLEXP,ERASE);
RELEASESPACE(.L,2+.GT[.L,0]<SUBNF>/2)
END;
L_.L1
END;
END;
END;
ROUTINE GTID(TOG)=
BEGIN LOCAL L,NS,OC,RN;
!
! THIS ROUTINE INCREMENTS (TOG=1) OR DECREMENTS (TOG=-1)
! ALL 'SAVGE' FIELDS IN THE GRAPH TABLE. THIS IS DONE TO
! PRESERVE THE EXISTING GRAPH TABLE ACROSS
! FORKS (E.G. IF-THEN-ELSE).
!
INCR I FROM 0 TO GTMASK DO
BEGIN
L_.GRAPHHEAD[.I];
WHILE .L NEQ 0 DO
BEGIN
IF (NS_.GT[.L,0]<SAVGEF>+.TOG) GTR 1^7-1 THEN ERROR(.NDEL,#771) ELSE
IF .NS GEQ 0 THEN GT[.L,0]<SAVGEF>_.NS ELSE
BEGIN
OC_.GT[.L,0]<OCCF>; GT[.L,0]<OCCF>_0;
IF .GT[.L,0]<RESULTF> THEN
IF (RN_TREGNUM(.GT[.L,1])) GEQ 16 THEN
WHILE (OC_.OC-1) GEQ 0 DO DUN(.RN);
END;
L_.GT[.L,0]<LINKF>;
END;
END;
END;
%3.1% GLOBAL ROUTINE GTINCR=GTID(+1);
%3.1% GLOBAL ROUTINE GTDECR= GTID(-1);
%3.1% GLOBAL ROUTINE FIXSIDEEFFECTS=
BEGIN
IF .CODETOG THEN
BEGIN
IF .NPTFLG AND .SESTOG GEQ 2 THEN CLEARSOME() ELSE
IF .SESTOG GEQ 8 THEN CLEARSOME() ELSE
IF .SESTOG GEQ 4 THEN CLEARTEMP();
GTPURGE(0);
END;
END;
%3.1% GLOBAL ROUTINE GENCODE(LEX,TOG)=
IF NOT.CODETOG THEN LITLEXEME(0) ELSE
BEGIN LOCAL R;
!
! THIS ROUTINE CONTROLS THE ACTUAL GENERATION OF MACHINE
! CODE FROM THE TREE STORED IN THE GRAPH-TABLE. THE INPUT
! PARAMETER 'LEX' CONTAINS A LEXEME POINTING TO THE
! (SUB) TREE WHOSE CODE IS TO BE PRODUCED. THE PARAMETER
! 'TOG' CONTROLS THE ACTION OF THE ROUTINE AFTER CODE
! HAS BEEN PRODUCED. TOG CONTROLS SUCH THINGS AS HOW THE
! GRAPH-TABLE IS CLEANED UP AFTERWARDS.
!
VTARGET_.VTARGET OR ( .DEL<LEFTHALF> NEQ HSEMCOL OR .FUTDEL<HCLASS> EQL DCLRTR );
R_IF ((.TOG GTR 0) AND (.LEX<LEFTHALF> EQL GTLEX)) THEN GENERATOR(.LEX) ELSE .LEX;
IF .TOG THEN FIXSIDEEFFECTS();
VTARGET_0;
.R
END;
%%
% THIS ROUTINE WILL SET THE OCCURRENCE COUNTS IN THE GRAPH
TABLE AND/OR USE-FIELDS IN THE REGISTER TABLE TO REFLECT THE
USE TO BE EXPECTED FROM A STRUCTURE PARAMETER LEXEME. THE
ROUTINE MUST MERELY BE CALLED BEFORE THE 1ST USE OF THE LEXEME
IN THE STRUCTURE EXPANSION. IF "CNT" IS NEGATIVE, WE UNLOCK
REGISTERS THAT NEED IT (CALLED AFTER THE EXPANSION IS COMPLETE).
THE NEW VALUE OF "LEX" IS RETURNED (AND SHOULD BE SUBSTITUTED
FOR THE ACTUALS PASSED.
%
%%
%3.1% GLOBAL ROUTINE FOCGPH(LEX,CNT)=
BEGIN
LOCAL REGIND, NEWUSE, GTVEC NODE;
REGIND_NEWUSE_0;
IF .LEX<LEFTHALF> EQL GTLEX
THEN BEGIN
NODE_.LEX<LINKF>;
NODE[0]<OCCF>_.NODE[0]<OCCF>+.CNT;
NEWUSE_IF .NODE[0]<RESULTF> THEN
IF (REGIND_TREGNUM(.NODE[1])) GEQ 16
THEN .RT[.REGIND]<USEF>+.CNT
END
ELSE
IF (REGIND_TREGNUM(.LEX)) GEQ 16
THEN NEWUSE_.RT[.REGIND]<USEF>+.CNT;
IF .REGIND GEQ 16
THEN (INCRUSEN(.REGIND); RT[.REGIND]<USEF>_.NEWUSE);
.LEX
END;
!END OF H1GTRE.BLI