!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ! !COPYRIGHT (C) 1972,1973,1974,1977,1978 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754 !FILENAME: H2GTRE.BLI !DATE: 24 MAY 73 MGM/FLD ! REVISION HISTORY:: ! ! 9-19-77 ROUTINE GTORES IS MODIFIED TO FIX BUG#34 (PARTLY). ! DO NOT MOVE ONTO STACK UNNECESSARY ITEMS.CLEAR REGISTER ! TABLE ALONG WITH LEXEME. ! %3.2% GLOBAL BIND H2GTV=2; !MODULE VERSION NUMBER %3.4% GLOBAL ROUTINE GTORES(LEX)= %3.4% %3.4% !TURN OFF THE RESULT BIT FOR GT LEXEME .LEX. %3.4% !ALSO TURN OFF THE RESULT BIT FOR EACH GT LEXEME WHICH %3.4% !DEPENDS UPON .LEX (I.E., HAS .LEX AS AN ARGUMENT). %3.4% !EACH TIME WE TURN OFF A RESULT BIT IN A LEXEME, WE MUST RECURSIVELY %3.4% !CALL GTORES TO TURN OF THE RESULT BIT OF EACH GT LEXEME ENTRY %3.4% !WHICH DEPENDS UPON IT. %3.4% %3.4% !GTORES IS CALLED WHENEVER, WE DELETE A GT LEXEME %3.4% !ENTRY FROM THE TRCT LIST. IN OTHER WORDS, %3.4% !WHEN WE REUSE A TEMPORARY REGISTER, WE CALL GTORES TO %3.4% !INSURE THAT ANY RESULT LEXEME WHICH DEPENDED UPON THE OLD %3.4% !REGISTER CONTENTS IS INVALIDATED IN THE GT. AT THE SAME %3.4% !TIME WE MUST INSURE THAT ANY RESULT WHICH IS DEPENDENT %3.4% !ON ANY INTERMEDIATE RESULT BASED ON THE OLD REGISTER %3.4% !CONTENTS IS ALSO INVALIDATED. %3.4% %3.4% BEGIN %3.4% %3.4% %3.4% REGISTER L, !INDEX OF CURRENT GT ENTRY %3.4% CHANGE; !TRUE IF WE TURNED OFF A RESULT BIT DURING %3.4% !OUR LAST PASS THRU THE GT %3.4% REGISTER REGNUM; %9-19-77% %3.4% GT[.LEX,0]_0; !TURN OFF RESULT BIT FOR LEX %3.4% %3.4% DO !MAKE PASSES THRU GT UNTIL WE FAIL TO MAKE A CHANGE ON A PASS %3.4% BEGIN %3.4% CHANGE_0; !INIT BEFORE WE START THIS PASS %3.4% DECR I FROM GTMASK TO 0 %3.4% DO !LOOK AT EACH CHAIN HANGING FROM GRAPHHEAD %3.4% BEGIN %3.4% IF (L_.GRAPHHEAD[.I]) NEQ 0 THEN !GET START OF CHAIN %3.4% DO !THE WHOLE CHAIN %3.4% IF .GT[.L,0] NEQ 0 !DO NOTHING IF ALREADY NO RESULT %3.4% THEN INCR J FROM 2 TO 2+.GT[.L,0] !CHECK EACH ARG %3.4% DO %3.4% IF .GT[.L,.J] EQL .LEX !IF WE MATCH %3.4% THEN %3.4% BEGIN %3.4% GTORES(#77777^18+.L); !DO THIS GT LEX %3.4% CHANGE_-1 !WE MADE A CHANGE %3.4% END %3.4% UNTIL ((L_.GT[.L,]) EQL 0) %3.4% END %3.4% END %3.4% UNTIL .CHANGE EQL 0 %3.4% END; !OF ROUTINE GTORES ROUTINE GTDIVMOD(GTE,RLEX)= BEGIN LOCAL OP,L,L1,L2,L3; BIND HDIV=#245700, HMOD=#246700; ! THIS ROUTINE CREATES A 'MOD'('DIV') GRAPHTABLE NODE ! WHEN A 'DIV'('MOD') OPERATION IS GENERATED. THE RESULT ! OF THE MOD (DIV) OPERATION IS AVAILABLE IN A REGISTER ! WHEN A DIV (MOD) OPERATION IS DONE -- THIS ROUTINE ! ALLOWS US TO CAPTURE IT. IF LITP(.GT[.GTE,3]) THEN BEGIN L_LITV(.GT[.GTE,3]); IF .L NEQ 0 THEN L_LOG2(.L); IF .L NEQ 0 THEN IF .GT[.GTE,2] EQL NGDIV<0,0> THEN RETURN END; L1_IF .GT[.GTE,2] EQL NGDIV<0,0> THEN 1 ELSE -1; IF (1^(.RT[.RLEX] + .L1) AND .HITREGM) EQL 0 THEN RETURN; OP_IF .GT[.GTE,2] EQL HDIV THEN NGMOD<0,0>+HMOD^18 ELSE NGDIV<0,0>+HDIV^18; L_.GRAPHHEAD[L1_GTHASH(.OP)]; L_L3_ WHILE .L NEQ 0 DO BEGIN IF .GT[.L,2] EQL .OP THEN IF .GT[.L,3] EQL .GT[.GTE,3] THEN IF .GT[.L,4] EQL .GT[.GTE,4] THEN EXITLOOP .L; L_.GT[.L,0]; END; IF .L LSS 0 THEN (L_MAKGT(2,.OP,GT[.GTE,3],+1);GT[.L,0]_0) ELSE IF .GT[.L,0] NEQ 0 THEN FIXOCCF(.L,3,4); IF NOT(.GT[.L,0]) AND TREGNUM(.RLEX) GEQ 16 THEN BEGIN L1_(IF .OP EQL HMOD THEN 1 ELSE -1)+.RT[.RLEX]; GT[.L,0]_1; GT[.L,1]_LEXRA(.L1); ST[NEWBOT(CTRCTH(.GT[.L,1]),1),1]_GTLEX^18+.L; DUA(.L1); IF .L3 GTR 0 THEN BEGIN L1_.GT[.L,1]; INCRUSEN(.L1); IF (RT[.L1]_.RT[.L1]+.GT[.L,0]-1) GEQ 1^8-1 THEN ERROR(.NSYM,#772); END; END; END; GLOBAL ROUTINE GENERATOR(LEX)= IF .CODETOG THEN BEGIN LOCAL N,L,I,R; MACHOP PUSH=#261; BIND SREG=0<0,36>; ! ! THIS ROUTINE, WORKING FROM THE GRAPH-TABLE, ACTUALLY ! CAUSES CODE TO BE GENERATED. IF THE INPUT LEXEME 'LEX' ! IS NOT A GRAPH-TABLE-LEXEME WE RETURN IMMEDIATELY, ! OTHERWISE WE FIRST TEST TO SEE WHETHER ITS ! 'RESULT' EXITS--IF SO WE SIMPLY RETURN THAT VALUE AFTER ! DECREMENTING THE . IF 'LEX' IS A GRAPH TABLE AND ITS ! RESULT IS NOT AVAILABLE WE CALL GENERATOR RECURSIVELY FOR ! ITS SUBNODES, CALL THE APPROPRIATE OPERATOR ROUTINE, ! SAVE THE RESULT AND SET THE RESULT BIT IN THE GRAPH-TABLE ! ENTRY; SET THE APPROPRIATE 'USE-FIELD' VALUE IN A TEMPORARY ! REGISTER IF NECESSARY, AND RETURN THE RESULT. ! IF .LEX NEQ GTLEX THEN RETURN(.LEX); L_.LEX; IF .GT[.L,0] THEN (GT[.L,0]_MAXER(.GT[.L,0]-1,0);RETURN (.GT[.L,1])); ! ! SINCE WE GOT PAST THE PREVIOUS TWO TESTS WE MUST HAVE TO ! GENERATE CODE. FIRST WE GENERATE CODE FOR THE SUBEXPRESSIONS. ! NOTE THAT WE CLEVERLY(?) DECLARE 'P' TO BE A LOCAL ARRAY ! IN THE APPROPRIATE POSITION FOR PARAMETERS TO THE ACTUAL ! CODE GENERATION ROUTINE. ! DECR J FROM (N_.GT[.L,0]) TO 1 DO (GENERATOR(.GT[.L,.J+2]); PUSH(0,3)); IF NOT(.CODETOG) THEN (SREG_.SREG-(.N^18+.N); RETURN ZERO); ! MUST HAVE HAD ERR IN CODE R_(@GT[.L,2])(); SREG_.SREG-(.N^18+.N); GT[.L,1]_.R; ! ! NOW WE HAVE THE SUBEXPRESSION VALUE (I.E. A LEXEME ! FOR IT) IN THE RESULT WORD SO WE FIX UP THE OCCURRENCE COUNT ! IN THE GRAPH TABLE ENTRY; THEN--IF THE RESULT IS IN A ! TEMPORARY REGISTER (OR DEPENDS ON SUCH A RESULT)-- ! WE INCREASE THE REGISTER USE FIELD ! AND PUT THIS GRAPH-TABLE NAME INTO THE NAME-LIST FOR THAT %2.24% ! REGISTER. IN ALL CASES(EXCEPT FOR _) WE SET THE RESULT-BIT. %2.24% IF .GT[.L,2] NEQ HSTO THEN GT[.L,0]_1; GT[.L,0]_MAXER(.GT[.L,0]-1,0); IF (R_TREGNUM(.R)) GEQ 16 THEN BEGIN IF NOT .RT[.R] THEN IF (RT[.R]_.GT[.L,0]+.RT[.R]) GTR 1^8-1 THEN ERROR(.NSYM,#772); ST[NEWBOT(CTRCTH(.R),1),1]_GTLEX^18+.L; IF .GT[.L,2] EQL NGDIV<0,0> OR .GT[.L,2] EQL NGMOD<0,0> THEN GTDIVMOD(.L,.GT[.L,1]); END; RETURN(.GT[.L,1]); END; ROUTINE FBSETTER(VARLEX,TYP,NAME)= BEGIN LOCAL X,Y,H; ! SET FUNNY BITS IN GTLIST, SEE COMMENT IN SETFUNBIT BELOW. H_.GRAPHHEAD[GTHASH(.TYP)]; WHILE .H NEQ 0 DO BEGIN IF .GT[.H,2]<0,18> EQL .TYP THEN BEGIN X_.GT[.H,.NAME]; Y_IF LITP(.X) THEN LITV(.X) AND IXYM ELSE .X AND LSSTEM; IF .VARLEX EQL .X OR .VARLEX EQL .Y THEN ( GT[.H,0]_1; RETURN); END; H_.GT[.H,0]; END; END; GLOBAL ROUTINE SETFUNBIT(VARLEX)= BEGIN LOCAL L; ! ! THIS ROUTINE WILL SET THE FUNNY BIT OF A DOT-TYPE ! GT ENTRY FOR THE SIMPLE NAME LEXEME "VARLEX". THIS ROUTINE ! IS CALLED FROM THE CODE GENERATORS WHEN A STORE IS DONE ! INTO A SIMPLE VARIABLE. ! IF REGP(.VARLEX) THEN VARLEX_.RT[.VARLEX]; VARLEX_.VARLEX AND LSSTEM; FBSETTER(.VARLEX, NGDOT<0,0>,3); FBSETTER(.VARLEX, NGAT<0,0>,3); FBSETTER(.VARLEX, NGPTR<0,0>,7); END; GLOBAL ROUTINE MARKFUNNY(L)= BEGIN ! THIS ROUTINE FORCES THE FUNNYBIT OF A GT-NODE, AND THAT ! OF ITS DESCENDENTS, TO BE SET IF .L EQL GTLEX THEN BEGIN L_.L; GT[.L,0]_1; INCR I FROM 3 TO .GT[.L,0]+2 DO MARKFUNNY(.GT[.L,.I]); END; END; !END OF H2GTRE.BLI