! 05/07/84 - put routine ARRTR in include file targ_arrtr ! 06/06/84 - extend array OPCAT for INTRIN & DCMPLX ! 05/06/84 - do not optimise arrays with constant subscripts (ARRTR) ! 13/03/84 - correct TYPES and LENGTHS in routine DESC ! 19/01/84 - CTSIZE & EXTNSIZE NOW IN HOST ! 18/01/84 - BLOCK BIT STRIP ADDRESSES ARE NOW RELATIVE TO ABLOCKS ! 07/11/83 COPIED FROM ERCS06.REL8002_OP3B23 !* %include "host_host" ! %include "targ_target" ! %include "pf_version" !* %include "bits_fmts" !* %include "bits_optspecs" !* %include "bits_optfmts" !* %include "bits_consts" !* %include "bits_triadops" !* ! ! ! ! %INTEGERFUNCTIONSPEC CREATETE (%INTEGER M) %INTEGERFUNCTIONSPEC CREATEDT (%INTEGER M) %INTEGERFUNCTIONSPEC ARBASE (%RECORD (RESF) OPD) %INTEGERFUNCTIONSPEC CHAFTER (%INTEGER TR) %ROUTINESPEC ELIM (%INTEGER TR) %ROUTINESPEC TEXTPASS (%INTEGER BREG) ! ! ! ! %EXTERNALROUTINE OP3 ! ! ! %ROUTINESPEC LOOPSEL (%INTEGER L) %ROUTINESPEC LOOPBUILD %ROUTINESPEC COMMTEMPS %INTEGERFUNCTIONSPEC STRENGTH %ROUTINESPEC REPLACE (%INTEGER S) %ROUTINESPEC BTEMPREP (%INTEGER MAX) %ROUTINESPEC VALUE (%INTEGER S) %ROUTINESPEC DESC (%INTEGER S) %ROUTINESPEC PRINTSR %ROUTINESPEC PRINTTE %ROUTINESPEC PRINTDT ! ! %INTEGERARRAYFORMAT TABF (0:1000) %INTEGERARRAYNAME ENTBTAB %RECORD (CLOOPRECF) %NAME CL %RECORD (BLRECF) %NAME BB %RECORD (LOOPRECF) %NAME LO %RECORD (CONRECF) %NAME CN %RECORD (TRIADF) %NAME TT %RECORD (SREDF) %NAME SR ! %CONSTINTEGER INFIN = X'80000001' ! %INTEGER I,SAVEPTR,DLOOPCH,BCOORD,CLOOPPTR,BREGTEMP,ADDTRIAD %INTEGER TEMAXCOORD,COORDMAX,BACKTARG ! !********************************************************************** !* OP3 CONTROL. * !* BUILD AND PROCESS ALL LOOPS, STARTING AT INNERMOST. * !********************************************************************** ! %IF SRFLAGS & 16 # 0 %THEN PRINTSR COORDMAX = BSWORDS << 5 TEINDEX = 1 DTINDEX = 1 VALTEMPHEAD = 0 DESTEMPHEAD = 0 TECH = ADDR (VALTEMPHEAD) DTCH = ADDR (DESTEMPHEAD) BCOORD = BSBITS TEMAXCOORD = BCOORD !* PROCESS TEXT FROM INNERMOST LOOPS OUTWARDS. %UNLESS FREELOOPS = 0 %THEN LOOPSEL (0) !* NOW PROCESS ENTRY-LEVEL BLOCKS. SAVEPTR = FREETABS ENTBTAB == ARRAY (ATABS + ENTBPTR,TABF) DLOOPCH = ADDR (DLOOPHEAD) DLOOPHEAD = 0 DLOOPTAIL = 0 %FOR I = 1,1,ENTBTAB(0) %CYCLE CLOOPTAIL = CREATETAB (CLOOPSZ) CL == RECORD (ATABS + CLOOPTAIL) CL_BLOCK = ENTBTAB (I) INTEGER (DLOOPCH) = CLOOPTAIL CL_PDCHAIN = 0 DLOOPCH = ADDR (CL_PDCHAIN) CL_PDBACKCHAIN = DLOOPTAIL DLOOPTAIL = CLOOPTAIL %REPEAT CLOOPHEAD = DLOOPHEAD LOOPDEPTH = 0 BACKTARG = 0 BREGTEMP = 0 LOOP = X'FFFF' LOOPBUILD %IF SRFLAGS & 16 # 0 %THENSTART PRINTTE PRINTDT %FINISH !* ATTEMPT TO COMMON UP TEMPORARIES ALLOCATED IN OP3. COMMTEMPS %UNLESS FREELOOPS = 0 ! ! ! ! %ROUTINE LOOPSEL (%INTEGER L) ! !************************************************************************ !* RECURSIVE ROUTINE TO PROCESS ALL "SON" LOOPS OF A GIVEN LOOP. * !* PARAMETER IS A LOOPTAB POINTER FOR CURRENT LOOP. CALLS ROUTINE TO * !* HANDLE STRENGTH REDUCTION TEMPORARIES BEFORE PROCESSING INNER LOOPS.* !************************************************************************ ! %INTEGER LOOPPTR,BTEMP ! LOOPPTR = L %CYCLE LOOP = LOOPPTR BTEMP = STRENGTH;! PROCESS SR TEMPS FOR THIS LOOP. LO == RECORD (ALOOPS + LOOPPTR) %UNLESS LO_DOWN = 0 %THENSTART LOOPSEL (LO_DOWN) LO == RECORD (ALOOPS + LOOPPTR) %FINISH SAVEPTR = FREETABS CLOOPHEAD = CREATETAB (CLOOPSZ) CL == RECORD (ATABS + CLOOPHEAD) CL_BLOCK = LO_BLOCK CL_PDCHAIN = 0 CL_PDBACKCHAIN = 0 DLOOPHEAD = CLOOPHEAD CLOOPTAIL = CLOOPHEAD DLOOPTAIL = CLOOPHEAD DLOOPCH = ADDR (CL_PDCHAIN) BB == RECORD (ABLOCKS + LO_BLOCK * BLSIZE) LOOPDEPTH = BB_DEPTH BACKTARG = BB_BTARG LOOP = LOOPPTR BREGTEMP = BTEMP LOOPBUILD LOOPPTR = LO_ACROSS;! PROCESS NEXT "BROTHER" IF ANY. %REPEAT %UNTIL LOOPPTR = 0 ! %END;! LOOPSEL ! ! ! ! %ROUTINE LOOPBUILD ! !************************************************************************** !* EXTEND CLOOP LIST TO HOLD ALL FORWARD CONNECTIONS OF THE ENTRY BLOCKS * !* WHICH ARE IN THE LOOP. BLOCKS WHICH HAVE NOT YET BEEN PROCESSED ARE * !* CHAINED INTO DLOOP LIST. * !************************************************************************** ! %INTEGER BLK,PTR ! CLOOPPTR = CLOOPHEAD %CYCLE CL == RECORD (ATABS + CLOOPPTR) BB == RECORD (ABLOCKS + CL_BLOCK * BLSIZE) %UNLESS BB_FCON = 0 %THENSTART CN == RECORD (ATABS + BB_FCON) %FOR I = 1,1,CN_COUNT %CYCLE BLK = CN_BLOCK(I) %UNLESS BLK = 0 %THENSTART BB == RECORD (ABLOCKS + BLK * BLSIZE) %IF BB_DEPTH >= LOOPDEPTH %THENSTART %FOR PTR = CLOOPHEAD,CLOOPSZ,CLOOPTAIL %CYCLE CL == RECORD (ATABS + PTR) %IF CL_BLOCK = BLK %THEN -> L1;! BLOCK ALREADY IN LIST %REPEAT CLOOPTAIL = CREATETAB (CLOOPSZ) CL == RECORD (ATABS + CLOOPTAIL) CL_BLOCK = BLK %IF BB_DEPTH = LOOPDEPTH %THENSTART INTEGER (DLOOPCH) = CLOOPTAIL DLOOPCH = ADDR (CL_PDCHAIN) CL_PDCHAIN = 0 CL_PDBACKCHAIN = DLOOPTAIL DLOOPTAIL = CLOOPTAIL %FINISH %FINISH %FINISH L1: %REPEAT %FINISH CLOOPPTR = CLOOPPTR + CLOOPSZ %REPEAT %UNTIL CLOOPPTR > CLOOPTAIL ! !* LOOP-LEVEL DIAGNOSTICS: %IF SRFLAGS & 8 # 0 %THENSTART NEWLINE NEWLINE PRINTSTRING (" BACK TARGET & CLOOP BLOCKS AFTER OP3A") NEWLINE NEWLINE %UNLESS BACKTARG = 0 %THENSTART PRBLOCK (BACKTARG) PRBLTRIADS (BACKTARG) %FINISH %FOR CLOOPPTR = CLOOPHEAD,CLOOPSZ,CLOOPTAIL %CYCLE CL == RECORD (ATABS + CLOOPPTR) PRBLOCK (CL_BLOCK) PRBLTRIADS (CL_BLOCK) %REPEAT %FINISH ! TEXTPASS (BREGTEMP) ! !* MORE LOOP-LEVEL DIAGNOSTICS: %IF SRFLAGS & 32 # 0 %THENSTART NEWLINE NEWLINE PRINTSTRING (" BACK TARGET & CLOOP BLOCKS AFTER OP3B") NEWLINE NEWLINE %UNLESS BACKTARG = 0 %THENSTART PRBLOCK (BACKTARG) PRBLTRIADS (BACKTARG) %FINISH %FOR CLOOPPTR = CLOOPHEAD,CLOOPSZ,CLOOPTAIL %CYCLE CL == RECORD (ATABS + CLOOPPTR) PRBLOCK (CL_BLOCK) PRBLTRIADS (CL_BLOCK) %REPEAT %FINISH ! FREETABS = SAVEPTR ! %END;! LOOPBUILD ! ! ! ! %INTEGERFUNCTION STRENGTH ! !************************************************************************ !* DECIDES ON MAPPINGS FOR ALL STRENGTH REDUCTION TEMPORARIES * !* ASSOCIATED WITH A GIVEN LOOP. ON ENTRY LOOP CONTAINS A LOOPTAB * !* POINTER FOR THE CURRENT LOOP. RETURNS A POINTER INTO SRTEMP TABLE * !* FOR ENTRY MAPPED ONTO B-REG. * !************************************************************************ ! %RECORD (SREDF) %NAME SR1,SR2 %RECORD (TRIADF) %NAME TT2 ! %INTEGER TRID,SRPTR,MAXWEIGHT,MAXTEMP,IDENT,PTR1,PTR2,CHAIN ! !* FIND LAST TRIAD IN LOOP'S BACK TARGET: WE MAY NEED TO ADD TRIADS THERE. LO == RECORD (ALOOPS + LOOP) BB == RECORD (ABLOCKS + LO_BLOCK * BLSIZE) BB == RECORD (ABLOCKS + BB_BTARG * BLSIZE) TRID = BB_TEXT TT == RECORD (ATRIADS + TRID * TRIADLENGTH) %CYCLE ADDTRIAD = TRID TRID = TT_CHAIN TT == RECORD (ATRIADS + TRID * TRIADLENGTH) %REPEAT %UNTIL TT_OP = INIT %OR TT_OP = GOTO %C %OR (TT_OP = STMT %AND TT_USE & SOB # 0) !* FIND MAX-WEIGHTED TEMP IN THIS LOOP & MAP ONTO B-REG. OTHERS ARE !* REPLACED BY DT OR TE ENTRIES. MAXWEIGHT = INFIN - 1 MAXTEMP = 0 CHAIN = LO_ST %WHILE CHAIN # 0 %CYCLE SRPTR = CHAIN SR == RECORD (ABLOCKS + SRPTR << SRSCALE) CHAIN = SR_CHAIN !* STOP WHEN SR ENTRIES FOR A DIFFERENT LOOP ARE MET. %IF SR_LOOP # LOOP %THEN %EXIT !* IGNORE ENTRY IF ALREADY SCANNED. %IF SR_FLAGS & SCANDBIT # 0 %THEN %CONTINUE !* LOOK FOR IDENTICAL SR ENTRIES, & CHAIN THEM TOGETHER. PTR1 = SRPTR SR1 == SR SR2 == SR IDENT = SR_IDENT SR_IDENT = 0 %CYCLE PTR2 = SR2_CHAIN %IF PTR2 = 0 %THEN %EXIT SR2 == RECORD (ABLOCKS + PTR2 << SRSCALE) %IF SR2_LOOP # LOOP %THEN %EXIT %IF SR2_FLAGS & SCANDBIT # 0 %THEN %CONTINUE %IF SR2_IDENT # IDENT %THEN %CONTINUE TT == RECORD (ATRIADS + SR1_INIT * TRIADLENGTH) TT2== RECORD (ATRIADS + SR2_INIT * TRIADLENGTH) %IF TT_RES2_W # TT2_RES2_W %THEN %CONTINUE %FOR I = 1,1,3 %CYCLE %IF SR1_INCR(I) = 0 %THENSTART %IF SR2_INCR(I) = 0 %THEN %EXIT %C %ELSE -> L1 %FINISH %IF SR2_INCR(I) = 0 %THEN -> L1 TT == RECORD (ATRIADS + SR1_INCR(I) * TRIADLENGTH) TT2== RECORD (ATRIADS + SR2_INCR(I) * TRIADLENGTH) %IF TT_RES2_W # TT2_RES2_W %OR TT_OP # TT2_OP %THEN -> L1 %REPEAT !* TWO ENTRIES ARE IDENTICAL. ADD NEW ONE TO CHAIN. SR1_IDENT = PTR2 PTR1 = PTR2 SR1 == SR2 SR1_IDENT = 0 !* WEIGHT OF COMBINED CHAIN IS MAX OF WEIGHTS OF ITS MEMBERS. %IF SR1_WEIGHT > SR_WEIGHT %THEN SR_WEIGHT = SR1_WEIGHT !* MARK NEW ENTRY AS SCANNED. SR1_FLAGS = SR1_FLAGS ! SCANDBIT !* IF ANY ENTRY IN CHAIN IS SUITABLE FOR TEST REPLACEMENT, THEN WHOLE CHAIN IS. SR_FLAGS = SR_FLAGS ! (SR1_FLAGS & TESTREPBIT) !* INIT & INCR TRIADS FOR NEW SR ENTRY NOT NEEDED, SO SET THEM TO NULL, !* AND IF THEIR OPDS ARE TEXT, REDUCE THEIR USE CTS BY ONE. TRID = SR1_INIT I = 1 %WHILE TRID#0 %CYCLE TT == RECORD (ATRIADS + TRID * TRIADLENGTH) TT_OP = NULL %IF TT_QOPD2 & TEXTMASK # 0 %THEN DELUSE (TT_OPD2) %IF I = 4 %THEN %EXIT TRID = SR1_INCR(I) I = I + 1 %REPEAT L1: %REPEAT !* REPLACE LOWER WEIGHTED ENTRY BY A DT OR TE ENTRY. %IF SR_WEIGHT > MAXWEIGHT %AND SR_MODE = INT4 %THENSTART MAXWEIGHT = SR_WEIGHT REPLACE (MAXTEMP) %UNLESS MAXTEMP = 0 MAXTEMP = SRPTR %FINISHELSE REPLACE (SRPTR) %REPEAT %IF MAXTEMP = 0 %THEN %RESULT = 0 %C %ELSESTART BTEMPREP (MAXTEMP) %RESULT = MAXTEMP %FINISH ! %END;! STRENGTH ! ! ! ! %ROUTINE BTEMPREP (%INTEGER MAX) ! !**************************************************************************** !* MARKS THE B-REG SR ENTRY AS SUCH. CHANGES THE OPD1 OF THE INIT TO B-REG,* !* AND ENSURES THAT ALL OTHER TESTS & USES POINT TO MAIN SR ENTRY * !* IN CHAIN. * !**************************************************************************** ! %RECORD (RESF) SRMAX,SRCURRENT ! SRMAX_H0 = MAX SRMAX_FORM = SRTEMP SRMAX_MODE = INT4 SR == RECORD (ABLOCKS + MAX << SRSCALE) SR_FLAGS = SR_FLAGS ! BREGBIT SR_DUMP = 0 TT == RECORD (ATRIADS + SR_INIT * TRIADLENGTH) TT_QOPD1 = BREG SRCURRENT = SRMAX !* SCAN THRO' ENTRIES IN AN IDENTITY CHAIN, CHANGING REFS TO POINT TO HEAD-OF-CHAIN. %WHILE SR_IDENT # 0 %CYCLE SRCURRENT_H0 = SR_IDENT SR == RECORD (ABLOCKS + SR_IDENT << SRSCALE) %FOR I = 1,1,3 %CYCLE %IF SR_TEST(I) = 0 %THEN %EXIT TT == RECORD (ATRIADS + SR_TEST(I) * TRIADLENGTH) %IF TT_RES1_W = SRCURRENT_W %THEN TT_RES1 = SRMAX %IF TT_RES2_W = SRCURRENT_W %THEN TT_RES2 = SRMAX %REPEAT %FOR I = 1,1,SR_USECT %CYCLE %IF SR_USE(I) = 0 %THEN %EXIT TT == RECORD (ATRIADS + SR_USE(I) * TRIADLENGTH) %IF TT_RES1_W = SRCURRENT_W %THEN TT_RES1 = SRMAX %IF TT_RES2_W = SRCURRENT_W %THEN TT_RES2 = SRMAX %REPEAT %REPEAT ! %END;! BTEMPREP ! ! ! ! %ROUTINE REPLACE (%INTEGER SRENT) ! !************************************************************************** !* DECIDES WHETHER TO MAP AN SR TEMP ONTO A DT OR A TE ENTRY. * !* (MAPPED ONTO DTEMP ONLY IF TEMP HAS NOT BEEN SELECTED FOR TEST * !* REPLACEMENT, AND ALL THE USES ARE AS SUBSCRIPTS IN ARR OR DEFARR * !* TRIADS USING THE SAME ARRAY.) * !************************************************************************** ! %RECORD (RESF) CURRARR ! CURRARR_W = 0 SR == RECORD (ABLOCKS + SRENT << SRSCALE) %IF SR_FLAGS & TESTREPBIT = 0 %THENSTART %CYCLE %FOR I = 1,1,SR_USECT %CYCLE %IF SR_USE(I) = 0 %THEN %EXIT TT == RECORD (ATRIADS + SR_USE(I) * TRIADLENGTH) %UNLESS TT_OP = ARR %OR TT_OP = DEFARR %THEN -> L1 %IF TT_MODE=CHARMODE %THEN ->L1 %IF CURRARR_W = 0 %THEN CURRARR = TT_RES1 %C %ELSESTART %UNLESS TT_RES1_W = CURRARR_W %THEN -> L1 %FINISH %REPEAT %IF SR_IDENT = 0 %THEN %EXIT SR == RECORD (ABLOCKS + SR_IDENT << SRSCALE) %REPEAT DESC (SRENT) %FINISHELSESTART L1: VALUE (SRENT) %FINISH ! %END;! REPLACE ! ! ! ! %ROUTINE VALUE (%INTEGER S) ! !********************************************************************* !* REPLACES AN SR TEMP WITH A TE ENTRY. * !********************************************************************* ! %RECORD (RESF) TEPTR,CURRSR ! %RECORD (TERECF) %NAME TE ! SR == RECORD (ABLOCKS + S << SRSCALE) TEPTR_W = CREATETE (INT4) TE == RECORD (ADICT + TEPTR_H0 << DSCALE) TE_FLAGS = SRTEMPBIT TE_LOOP = LOOP TEMAXCOORD = TEMAXCOORD + 1 TE_COORD = TEMAXCOORD !* INIT TRIAD BECOMES AN ASMT. TT == RECORD (ATRIADS + SR_INIT * TRIADLENGTH) TT_OP = ASMT CURRSR_H0 = S CURRSR_FORM = SRTEMP CURRSR_MODE = INT4 !* FOR EACH ENTRY IN SR IDENTITY CHAIN, REPLACE SR REFS BY TE REFS IN !* INIT & ALL INCRS, TESTS, & USES. %CYCLE TT_RES1 = TEPTR %FOR I = 1,1,SR_USECT+6 %CYCLE %IF SR_ALLREFS(I) = 0 %THEN %CONTINUE TT == RECORD (ATRIADS + SR_ALLREFS(I) * TRIADLENGTH) %IF TT_RES1_W = CURRSR_W %THEN TT_RES1 = TEPTR %IF TT_RES2_W = CURRSR_W %THEN TT_RES2 = TEPTR %REPEAT %IF SR_IDENT = 0 %THEN %EXIT CURRSR_H0 = SR_IDENT SR == RECORD (ABLOCKS + SR_IDENT << SRSCALE) TT == RECORD (ATRIADS + SR_INIT * TRIADLENGTH) %REPEAT ! %END;! VALUE ! ! ! ! %ROUTINE DESC (%INTEGER S) ! !*********************************************************************** !* REPLACES AN SR TEMP WITH A DT ENTRY. * !*********************************************************************** ! %RECORD (RESF) DTPTR,WINC,OPD ! %RECORD (DTRECF) %NAME DT %RECORD (TRIADF) %NAME TT1 ! %INTEGER MODE,BASE,TYPE,SCALE,NEWTR,CUSES,INC,TRID,I ! %CONSTBYTEINTEGERARRAY TYPES(0:15) = INTTYPE(3),REALTYPE(3),CMPLXTYPE(3), LOGTYPE(4),CHARTYPE,0,INTTYPE %CONSTBYTEINTEGERARRAY LENGTHS(0:15) = 2,4,8,4,8,16,8,16,32,1,2,4,8,1,0,1 ! %ROUTINESPEC ADDCODE (%INTEGER TR) ! SR == RECORD (ABLOCKS + S << SRSCALE) I=1 TT == RECORD (ATRIADS + SR_USE(I) * TRIADLENGTH) OPD = TT_RES1 BASE = ARBASE (OPD) MODE = TT_MODE DTPTR_W = CREATEDT (TT_MODE) DT == RECORD (ADICT + DTPTR_H0 << DSCALE) DT_IDENT = BASE DT_FLAGS = SRTEMPBIT DT_LOOP = LOOP !* CALCULATE VALUE BY WHICH EACH INCREMENT MUST BE SCALED. TYPE = TYPES (MODE) SCALE = LENGTHS(MODE) !* %IF TYPE = CMPLXTYPE %THEN SCALE = SCALE >> 1 !* %IF TARGET=PERQPNX %THENSTART %IF SCALE#1 %THEN SCALE=SCALE>>1;! 16 bit word addresses %FINISH !* %IF TARGET=ICL2900 %THENSTART %IF SCALE=2 %THEN SCALE=1;! for string descriptor use %FINISH !* !* MODIFY INIT TRIAD BY REPLACING SRTEMP BY THE NEW DTEMP, AND THE !* INITIAL VALUE BY A DEFARR TRIAD. TT1 == RECORD (ATRIADS + SR_INIT * TRIADLENGTH) !* INSERT NEW TRIAD IMMEDIATELY BEFORE THE RELEVANT INIT. TRID = ADDTRIAD %CYCLE TT == RECORD (ATRIADS + TRID * TRIADLENGTH) %IF TT_CHAIN = SR_INIT %THEN %EXIT TRID = TT_CHAIN %REPEAT NEWTR = CHAFTER (TRID) TT == RECORD (ATRIADS + NEWTR * TRIADLENGTH) TT_RES1 = OPD TT_RES2 = TT1_RES2 TT_OP = DEFARR TT_USE = 1 TT1_RES1 = DTPTR TT1_OPD2 = NEWTR TT1_QOPD2 = TRIAD TT1_MODE2 = MODE TT1_OP = DINIT !* MODIFY EACH OF THE INCR/DECR TRIADS BY SCALING THE INCREMENT AND !* REPLACING THE OLD SR TEMP BY THE NEW DT ENTRY. %FOR I = 1,1,3 %CYCLE %IF SR_INCR(I) = 0 %THEN %EXIT TT == RECORD (ATRIADS + SR_INCR(I) * TRIADLENGTH) %IF TT_OP # INCR %THENSTART TT_OP = INCR SCALE = -SCALE %FINISH !* AMEND DT-INCR TRIADS SO THAT OPD 2 IS CORRECTLY SCALED FOR INCA. !* MAY INVOLVE CHAINING INTO THE BACK TARGET. %UNLESS SCALE = 1 %THENSTART L1: INC = TT_OPD2 WINC = TT_RES2 %IF TT_QOPD2 & TEXTMASK # 0 %THENSTART TT1 == RECORD (ATRIADS + TT_OPD2 * TRIADLENGTH) %IF TT1_OP = REPL %OR TT1_OP = REF %THENSTART ELIM (INC) TT_RES2 = TT1_RES1 -> L1 %FINISH %IF TT1_OP = MULT %AND TT1_USE = 1 %THENSTART %IF TT1_QOPD2 & CONSTMASK # 0 %THEN %C TT1_RES2_W = CONIN (SCALE * CONOUT (TT1_RES2)) %C %ELSEIF TT1_QOPD1 & CONSTMASK # 0 %THEN %C TT1_RES1_W = CONIN (SCALE * CONOUT (TT1_RES1)) %FINISHELSE ADDCODE (INC) %FINISHELSEIF TT_QOPD2 & CONSTMASK # 0 %THEN %C TT_RES2_W = CONIN (SCALE * CONOUT (TT_RES2)) %C %ELSE ADDCODE (ADDTRIAD) %AND ADDTRIAD = NEWTR %FINISH TT_RES1 = DTPTR %REPEAT !* EACH USE TRIAD BECOMES A REPL WITH OPD 1 = THE NEW DTEMP. CUSES = 0 %CYCLE %FOR I = 1,1,SR_USECT %CYCLE %IF SR_USE(I) = 0 %THEN %EXIT TT == RECORD (ATRIADS + SR_USE(I) * TRIADLENGTH) TT_RES1 = DTPTR TT_OP = REPL TT_RES2_W = 0 CUSES = CUSES + 1 %REPEAT %IF SR_IDENT = 0 %THEN %EXIT SR == RECORD (ABLOCKS + SR_IDENT << SRSCALE) %REPEAT SR == RECORD (ABLOCKS + S << SRSCALE) TT == RECORD (ATRIADS + SR_INIT * TRIADLENGTH) TT == RECORD (ATRIADS + TT_OPD2 * TRIADLENGTH) %IF TT_QOPD1 & TEXTMASK # 0 %THENSTART TT == RECORD (ATRIADS + TT_OPD1 * TRIADLENGTH) TT_USE = TT_USE + 1 - CUSES %FINISH ! ! ! ! %ROUTINE ADDCODE (%INTEGER TR) ! !************************************************************************ !* GENERATES 'INC * SCALE' (OR 'INC NEG -' , IF SCALE = -1) TRIAD. * !************************************************************************ ! NEWTR = CHAFTER (TR) TT1 == RECORD (ATRIADS + NEWTR * TRIADLENGTH) TT1_RES1 = WINC %UNLESS SCALE = -1 %THENSTART TT1_RES2_W = CONIN (SCALE) TT1_OP = MULT %FINISHELSE TT1_OP = NEG TT1_USE = 1 TT_OPD2 = NEWTR TT_QOPD2 = TRIAD TT_MODE2 = INT4 ! %END;! ADDCODE ! %END;! DESC ! ! ! ! %ROUTINE COMMTEMPS ! !*************************************************************************** !* EQUIVALENCES TOGETHER DT & TE ENTRIES WHICH ARE NOT ACTIVE AT THE SAME * !* POINT IN THE FORTRAN SECTION. * !*************************************************************************** ! %INTEGERARRAYFORMAT BF(0:15) %INTEGERARRAYNAME B ! %INTEGER CTAREA,PTR,MODE,BITNO,CTEND,CTLENGTH,CHAIN,SAVE ! %RECORDFORMAT CTEMPF (%HALFINTEGER TEMP) ! %RECORD (TERECF) %NAME TE %RECORD (DTRECF) %NAME DT %RECORD (LOOPRECF) %NAME LO %RECORD (BLRECF) %NAME BB %RECORD (CTEMPF) %NAME CT ! %ROUTINESPEC SETVAL (%INTEGER L) %INTEGERFUNCTIONSPEC BITVAL (%INTEGER L) %ROUTINESPEC ZEROBITS ! !* FIRST COMMON UP TE ENTRIES. SAVE = FREETABS ZEROBITS PTR = VALTEMPHEAD %WHILE PTR # 0 %CYCLE TE == RECORD (ADICT + PTR << DSCALE) CHAIN = TE_CHAIN LOOP = TE_LOOP !* TEMPS USED AT OUTER LEVEL CAN'T BE COMMONED. %UNLESS LOOP = X'FFFF' %THENSTART TE_LOOP = 0 MODE = TE_MODE BITNO = 0 !* SCAN CTEMP TABLE & BITSTRIPS TO FIND APPROPRIATE BIT-NO FOR TEMP. %CYCLE CT == RECORD (ATABS + CTAREA + BITNO * CTSIZE) !* BIT-NO OK IF UNALLOCATED. %IF CT_TEMP = 0 %THEN %EXIT TE == RECORD (ADICT + CT_TEMP << DSCALE) !* ALSO OK IF ALREADY ALLOCATED TO A TEMP OF SAME MODE, AND NEVER !* ACTIVE IN SAME LOOPS. %IF TE_MODE = MODE %AND BITVAL (LOOP) = 0 %THEN %EXIT BITNO = BITNO + 1 %IF BITNO > COORDMAX %THEN -> L1;! NO SUITABLE BIT-NO. %REPEAT !* WE HAVE A GOOD BIT-NO. ATTACH IT TO CHAIN. SETVAL (LOOP) TE_LOOP = CT_TEMP CT_TEMP = PTR L1: %FINISH PTR = CHAIN %REPEAT FREETABS = SAVE ! !* NOW COMMON UP DT ENTRIES. ! ZEROBITS PTR = DESTEMPHEAD %WHILE PTR # 0 %CYCLE DT == RECORD (ADICT + PTR << DSCALE) LOOP = DT_LOOP !* TEMPS INITIALISED BY LOADER, OR USED AT OUTER LEVEL, CAN'T BE COMMONED. %UNLESS DT_FLAGS & INITLOADBIT # 0 %OR LOOP = X'FFFF' %THENSTART DT_LOOP = 0 BITNO = 0 !* SCAN CTEMP TABLE & BITSTRIPS TO FIND APPROPRIATE BIT-NO FOR TEMP. %CYCLE CT == RECORD (ATABS + CTAREA + BITNO * CTSIZE) !* BIT-NO OK IF UNALLOCATED, OR ALLOCATED TO A TEMP WHICH IS NEVER !* ACTIVE IN SAME LOOPS. %IF CT_TEMP = 0 %OR BITVAL (LOOP) = 0 %THEN %EXIT BITNO = BITNO + 1 %IF BITNO > COORDMAX %THEN -> L2 %REPEAT SETVAL (LOOP) DT_LOOP = CT_TEMP CT_TEMP = PTR L2: %FINISH PTR = DT_CHAIN %REPEAT FREETABS = SAVE ! ! ! ! %ROUTINE ZEROBITS ! !********************************************************************* !* SET UP A TABLE AREA & CLEAR BLOCK USE BIT-STRIPS. * !********************************************************************* ! PTR = ALOOPS %WHILE PTR < ALOOPS + FREELOOPS %CYCLE LO == RECORD (PTR) BB == RECORD (ABLOCKS + LO_BLOCK * BLSIZE) B == ARRAY (ABLOCKS+BB_USE,BF) B(I) = 0 %FOR I = 0,1,BSWORDS - 1 PTR = PTR + LOOPRECSIZE %REPEAT CTLENGTH = CTSIZE * COORDMAX CTAREA = CREATETAB (CTLENGTH) CTEND = CTAREA + CTLENGTH PTR = CTAREA %CYCLE CT == RECORD (ATABS + PTR) CT_TEMP = 0 PTR = PTR + CTSIZE %REPEAT %UNTIL PTR >= CTEND ! %END;! ZEROBITS ! ! ! ! %ROUTINE SETVAL (%INTEGER L) ! !********************************************************************* !* SETS GIVEN BIT FOR LOOP L & ALL CONTAINED LOOPS (RECURSIVELY). * !********************************************************************* ! %INTEGER DOWN ! %RECORD (LOOPRECF) %NAME LO1 ! LO1 == RECORD (ALOOPS + L) DOWN = LO1_DOWN %WHILE DOWN # 0 %CYCLE SETVAL (DOWN) LO == RECORD (ALOOPS + DOWN) DOWN = LO_ACROSS %REPEAT BB == RECORD (ABLOCKS + LO1_BLOCK * BLSIZE) SETBIT (ABLOCKS+BB_USE,BITNO) ! %END;! SETVAL ! ! ! ! %INTEGERFUNCTION BITVAL (%INTEGER L) ! !************************************************************************** !* CHECKS WHETHER GIVEN BIT IS SET IN ANY LOOP CONTAINED IN LOOP L * !* (RECURSIVELY). IF SO, SETS BIT FOR THIS LOOP (TO SAVE TIME NEXT * !* TIME. RETURNS BIT VALUE FOR LOOP. * !************************************************************************** ! %INTEGER BIT,DOWN ! %RECORD (BLRECF) %NAME BB ! LO == RECORD (ALOOPS + L) BB == RECORD (ABLOCKS + LO_BLOCK * BLSIZE) DOWN = LO_DOWN GETBIT (ABLOCKS+BB_USE,BITNO,BIT) %IF BIT # 0 %THEN %RESULT = 1 %WHILE DOWN # 0 %CYCLE %IF BITVAL (DOWN) = 1 %THENSTART SETBIT (ABLOCKS+BB_USE,BITNO) %RESULT = 1 %FINISH LO == RECORD (ALOOPS + DOWN) DOWN = LO_ACROSS %REPEAT %RESULT = 0 ! %END;! BITVAL ! %END;! COMMTEMPS ! ! ! ! %ROUTINE PRINTSR ! !************************************************************************* !* PRINT CONTENTS OF STRENGTH REDUCTION TEMPORARIES TABLE. * !************************************************************************* ! %INTEGER PTR ! NEWLINE NEWLINE PRINTSTRING ("STRENGTH REDUCTION TABLE") NEWLINE PRINTSTRING (" IDENT LOOP DUMP INIT FLAGS USE CT WEIGHT") NEWLINE PTR = SRHEAD %WHILE PTR # 0 %CYCLE SR == RECORD (ABLOCKS + PTR << SRSCALE) WRITE (SR_IDENT,6) WRITE (SR_LOOP,6) WRITE (SR_DUMP,6) WRITE (SR_INIT,6) WRITE (SR_FLAGS,6) WRITE (SR_USECT,6) WRITE (SR_WEIGHT,6) NEWLINE PTR = SR_CHAIN %REPEAT ! %END;! PRINTSR ! ! ! ! %ROUTINE PRINTTE ! !************************************************************************* !* PRINT CONTENTS OF VALUE TEMPORARIES TABLE. * !************************************************************************* ! %RECORD (TERECF) %NAME TE ! %INTEGER PTR ! NEWLINE NEWLINE PRINTSTRING ("VALUE TEMPORARIES TABLE") NEWLINE PRINTSTRING (" MODE LOOP INDEX FLAGS") NEWLINE PTR = VALTEMPHEAD %WHILE PTR # 0 %CYCLE TE == RECORD (ADICT + PTR<> DSCALE TE_CHAIN = 0 %UNLESS VALTEMPHEAD=0 %THEN TECH=TECH+ADICT INTEGER (TECH) = TEADDR TECH = ADDR (TE_CHAIN)-ADICT TEPTR_H0 = TEADDR TEPTR_FORM = VALTEMP TEPTR_MODE = M TE_DISP1 = 0 TE_INDEX = TEINDEX TEINDEX = TEINDEX + 1 TE_MODE = M TE_LOOP=LOOP TE_FLAGS=0 %RESULT = TEPTR_W ! %END;! CREATETE ! ! ! ! %INTEGERFUNCTION CREATEDT (%INTEGER M) ! !******************************************************************** !* CREATE A DESTEMP ENTRY AND FILL IN THE EASY FIELDS. * !******************************************************************** ! %INTEGER DTADDR ! %RECORD (RESF) DTPTR %RECORD (DTRECF) %NAME DT ! DTADDR = CREATEDTAB (DTSZ) DT == RECORD (ADICT + DTADDR) DTADDR = DTADDR >> DSCALE DT_CHAIN = 0 %UNLESS DESTEMPHEAD=0 %THEN DTCH=DTCH+ADICT INTEGER (DTCH) = DTADDR DTCH = ADDR (DT_CHAIN)-ADICT DTPTR_H0 = DTADDR DTPTR_FORM = DESTEMP DTPTR_MODE = M DT_DISP2 = 0 DT_INDEX = DTINDEX DTINDEX = DTINDEX + 1 DT_MODE = M DT_LOOP=LOOP DT_FLAGS=0 %RESULT = DTPTR_W ! %END;! CREATEDT ! ! ! %INTEGERFUNCTION CHAFTER (%INTEGER TR) ! !************************************************************************* !* CHAINS A NEW TRIAD INTO THE TEXT BETWEEN THE GIVEN TRIAD AND ITS * !* SUCCESSOR. RETURNS POINTER TO THE NEW TRIAD. * !************************************************************************* ! %INTEGER CHAIN,NEW ! %RECORD (TRIADF) %NAME TT ! TT == RECORD (ATRIADS + TR * TRIADLENGTH) CHAIN = TT_CHAIN NEW = GETTRIAD TT_CHAIN = NEW TT == RECORD (ATRIADS + NEW * TRIADLENGTH) TT_CHAIN = CHAIN %RESULT = NEW ! %END;! CHAFTER ! ! ! ! %ROUTINE ELIM (%INTEGER TR) ! !*************************************************************************** !* REDUCE THE USE CT OF A REPL OR REF TRIAD BY ONE. IF USE CT IS NOW * !* ZERO SET OPERATOR TO NULL, ELSE IF OPD 1 IS A TRIAD INCREASE ITS USE * !* CT BY ONE. * !*************************************************************************** ! %RECORD (TRIADF) %NAME TT ! TT == RECORD (ATRIADS + TR * TRIADLENGTH) TT_USE = TT_USE - 1 %IF TT_USE = 0 %THEN TT_OP = NULL %C %ELSEIF TT_QOPD1 & TEXTMASK # 0 %THENSTART TT == RECORD (ATRIADS + TT_OPD1 * TRIADLENGTH) TT_USE = TT_USE + 1 %FINISH ! %END;! ELIM ! ! ! ! %INTEGERFUNCTION ARBASE (%RECORD (RESF) OPD) ! !************************************************************************* !* FINDS THE BASE ARRAY OF AN ARRAY ACCESSING FORM. * !************************************************************************* ! %INTEGER FORM,H0 ! %RECORD (TRIADF) %NAME TT %RECORD (DTRECF) %NAME DT ! FORM = OPD_FORM H0 = OPD_H0 %CYCLE %IF FORM & IDMASK # 0 %THEN %RESULT = H0 %IF FORM = DESTEMP %THENSTART DT == RECORD (ADICT + H0 << DSCALE) %RESULT = DT_IDENT %FINISH !* ELSE MUST BE TEXT PTR SO REPEAT PROCESS. TT == RECORD (ATRIADS + H0 * TRIADLENGTH) FORM = TT_QOPD1 H0 = TT_OPD1 %REPEAT ! %END;! ARBASE ! ! !* !*********************************************************************** !* * !*********************************************************************** !* * !* T E X T P A S S * !* * !*********************************************************************** !* * !*********************************************************************** !* ! ! 1/12/82 - INSERTED LINE 951 IN INCRTR & CHANGED BTEMP ! ! ! %EXTERNALROUTINE TEXTPASS (%INTEGER BREGTEMP) ! ! %ROUTINESPEC BLOKCHAIN %INTEGERFUNCTIONSPEC GETNEXT %INTEGERFUNCTIONSPEC OPND (%RECORD (RESF) OP,%INTEGER BUSE) %ROUTINESPEC INITTR %ROUTINESPEC INCRTR %ROUTINESPEC ASMTCH %ROUTINESPEC ARRTR %ROUTINESPEC ARGCH %ROUTINESPEC REDUSE (%RECORD (RESF) OP) %ROUTINESPEC KEEPB (%INTEGER TR) %ROUTINESPEC RESETB (%INTEGER TR) %ROUTINESPEC BTEMP (%INTEGER BL) %ROUTINESPEC RESARGS (%INTEGER TR) %ROUTINESPEC CRENT %INTEGERFUNCTIONSPEC BRDUMP(%INTEGER SRTEMP) %INTEGERFUNCTIONSPEC OUTBLOCK (%INTEGER TR) %INTEGERFUNCTIONSPEC BREGOPN (%RECORD (RESF) OP) %ROUTINESPEC PRESVAL (%INTEGER TR) %INTEGERFUNCTIONSPEC DTDUPL (%INTEGER DPTR) %INTEGERFNSPEC TRSPEC(%RECORD(RESF) R) %ROUTINESPEC CHECKBBOEX ! !* DIVIDE OPERATIONS INTO 23 CATEGORIES TO DRIVE TEXT PASSES. %CONSTBYTEINTEGERARRAY OPCAT (0:116) = %C 0, 0, 7, 7, { NULL (01) ADD SUB 7, 7, 3, 12, { MULT DIV NEG ASMT 5, 15, 0, 0, { CVT ARR ARR1 BOP 8, 7, 22, 7, { ASGN (0D) EXP EXP3 7, 0, 3, 7, { AND OR NOT EQUIV 7, 7, 7, 7, { NEQ GT LT NE 7, 7, 7, 7, { EQ GE LE SUBSTR 27, 27, 27, 0, { CHAR CONCAT CHHEAD (1F) 0, 0, 0, 0, { STOD1 STOD2 STODA (23) 0, 0, 0, 0, { EOD1 EOD2 EODA EODB 20, 15, 7, 7, { BRK DEFARR RSUB RDIV 1, 7, 0, 0, { DCHAR ASH (2E) (2F) 21, 13, 1, 24, { STRTIO IOITEM IODO IOSPEC 21, 13, 0, 0, { IO DIOITEM (36) (37) 0, 15, 17, 16, { (38) ARGARR INIT INCR 16, 18, 16, 0, { DECR DINIT PINCR (3F) 0, 10, 9, 11, { NOOP FUN SUBR ARG, 0, 0, 9, 10, { STRTSF ENDSF CALLSF IFUN, 11, 11, 1, 20, { DARG IARG REPL REF, 1, 19, 23, 0, { LOADB STOREB MOO (4F) 6, 6, 6, 6, { JIT JIF JINN JINP, 6, 6, 6, 6, { JINZ JIN JIP JIZ, 4, 14, 2, 1, { CGT GOTO RET STOP, 1, 1, 25, 25, { PAUSE EOT NINT ANINT 1, 0, 1, 7, { STMT ITS PA TOCHAR 7, 7, 25, 7, { DIM DMULT AINT ABS 26, 7, 7, 7, { MOD SIGN MIN MAX 7, 7, 7, 7, { REALL IMAG CMPLX CONJG 7, 7, 7, 7, { LEN ICHAR CHIND DCMPLX 10 { INTRIN ! %CONSTBYTEINTEGERARRAY CORRUPTB(0:29) = %C 0,0,0,0,0, 1,0,0,0,1, 1,0,0,1,0, 0,0,0,0,0, 0,1,1,1,0, 1,1,0,0,0 ! ! %RECORDFORMAT EXRECF (%HALFINTEGER TRIAD,USES) ! %RECORD (EXRECF) %NAME EX %RECORD (SREDF) %NAME SR %RECORD (BLRECF) %NAME BB,BB1 %RECORD (TRIADF) %NAME TT,TT1 %RECORD (CONRECF) %NAME CN %RECORD (CLOOPRECF) %NAME CL %RECORD (DTRECF) %NAME DT ! %RECORD (RESF) BREGOP ! %CONSTINTEGER BBOEXBIT = X'04' %CONSTINTEGER BUSEDBIT = X'02' %CONSTINTEGER BUSEDORBOE = X'06' %CONSTINTEGER NOTBBOEX = X'FB' ! %INTEGER DLOOPPTR,START,LASTBUT1,INITB,BEFBUSE,LASTBUSE,BNEEDED,BUSED %INTEGER BBOEXIT,BCORRUPT,OLDDTCH,BLOCK,I,SAVEB,EXTNSTART,EXTNEND %INTEGER BLOADED,BSAVED ! !************************************************************************** !* PROCESSES THE TEXT FOR EACH BLOCK IN THE CURRENT LOOP, INCLUDING * !* CONTROLLING THE B REGISTER OVER THE LOOP. * !************************************************************************** ! BREGOP_FORM = BREG BREGOP_MODE = INT4 BREGOP_H0 = 0 SAVEB = 0 BLOADED=1 BSAVED=0 BBOEXIT=1 DLOOPPTR = DLOOPHEAD !* PROCESS EACH BLOCK IN LOOP. %WHILE DLOOPPTR # 0 %CYCLE CL == RECORD (ATABS + DLOOPPTR) BLOCK = CL_BLOCK BB == RECORD (ABLOCKS + BLOCK * BLSIZE) START = BB_TEXT CN == RECORD (ATABS + BB_FCON) !* TEST WHETHER THIS BLOCK IS THE BACK TARG OF AN INNER LOOP, SINCE !* INNER LOOPS CAN CORRUPT B-REG. BCORRUPT = 0 %IF BBOEXIT=0 %THEN BLOADED=0 %ELSE BLOADED=1 %IF CN_COUNT # 0 %AND CN_BLOCK(1) # 0 %THENSTART BB1 == RECORD (ABLOCKS + CN_BLOCK(1) * BLSIZE) %IF BB1_DEPTH > LOOPDEPTH %THENSTART BCORRUPT = BB1_TEXT SAVEB = 1 %FINISH %FINISH BLOKCHAIN DLOOPPTR = CL_PDCHAIN %REPEAT !* IF B-REG HAS BEEN CORRUPTED IN LOOP, & SHOULD CONTAIN AN SR-TEMP, !* MAKE SURE THAT 1ST USE OF B-REG IN EACH BLOCK IS OK, & PUT STOREB !* TRIADS AFTER INIT, INCRS & DECRS. %IF SAVEB # 0 %AND BREGTEMP # 0 %THENSTART CHECKBBOEX DLOOPPTR = DLOOPHEAD %WHILE DLOOPPTR # 0 %CYCLE CL == RECORD (ATABS + DLOOPPTR) BTEMP (CL_BLOCK) DLOOPPTR = CL_PDCHAIN %REPEAT SR == RECORD (ABLOCKS + BREGTEMP << SRSCALE) KEEPB (SR_INIT) %FOR I = 1,1,3 %CYCLE %IF SR_INCR(I) # 0 %THEN KEEPB (SR_INCR(I)) %REPEAT %FINISH ! ! ! ! %ROUTINE BLOKCHAIN ! !*************************************************************************** !* REORDERS & OPTIMISES TEXT IN THE GIVEN BLOCK, INCLUDING CONTROLLING THE * !* B REGISTER. * !*************************************************************************** ! %INTEGER PTR,CAT ! %SWITCH PASS1(0:29),PASS2(0:29),PASS3(0:29) ! LASTBUT1 = 0 INITB = 0 BEFBUSE = 0 LASTBUSE = 0 BNEEDED = 0 BUSED = 0 BBOEXIT = 0 %IF SAVEB#0 %THENSTART BLOADED=0 BCORRUPT=1 %FINISH ! !* PASS 1. USES OF REF REPL ETC RESOLVED. ALL USES OF TEMPS TIDIED UP. CURRTRIAD = START %WHILE GETNEXT = 1 %CYCLE TT == RECORD (ATRIADS + CURRTRIAD * TRIADLENGTH) CAT = OPCAT (TT_OP) -> PASS1 (CAT) ! PASS1(0): NEWLINE NEWLINE PRINTSTRING ("ERROR: OPERATOR VALUE ") WRITE (TT_OP,3) NEWLINE PASS1(1): PASS1(27): !* CHAR -> PASS1END PASS1(2):PASS1(3):PASS1(8): TT_RES1_W = OPND (TT_RES1,2) -> PASS1END PASS1(4): !* CGT TT_RES1_W = OPND (TT_RES1,2) ->CHECKB PASS1(5): TT_RES2_W = OPND (TT_RES2,2) %IF TT_MODE<=INT8 %AND TT_MODE2>TT_MODE %THEN ->CHECKB -> PASS1END PASS1(6): !* JIT JIP JINN JINP JINZ JIN JIP JIZ PASS1(7): !* MULT DIV DMULT EXP3 AND OR EQUIV NEQ GT LT NE EQ GE LE RSUB RDIV !* ASH TT_RES1_W = OPND (TT_RES1,2) TT_RES2_W = OPND (TT_RES2,2) -> PASS1END PASS1(19): !* STOREB BSAVED = 1 -> PASS1END PASS1(22): !* EXP TT_RES1_W = OPND(TT_RES1,2) TT_RES2_W = OPND(TT_RES2,2) ->CHECKB PASS1(23): !* MOO TT_RES2_W=OPND(TT_RES2,2) ->CHECKB PASS1(26): !* MOD TT_RES1_W=OPND(TT_RES1,2) PASS1(25): !* NINT ANINT AINT TT_RES2_W = OPND (TT_RES2,2) ->CHECKB PASS1(9): !* SUBR PASS1(10): !* FUN IFUN ARGCH PASS1(21): ! STRTIO IO CHECKB: %IF BLOADED#0 %AND BSAVED=0 %AND BREGTEMP#0 %THENSTART ! KEEPB(PREVTRIAD) SAVEB=1 BSAVED=1 %FINISH BCORRUPT=1 BLOADED=0 -> PASS1END PASS1(11): !* ARG DARG IARG ARGCH TT_RES1_W = OPND (TT_RES1,2) DUMPB:%IF TT_QOPD1 = BREG %THENSTART ! %IF BSAVED=0 %THEN KEEPB(PREVTRIAD) BCORRUPT=1 SAVEB=1 TT_OPD1 = BRDUMP(BREGTEMP) TT_QOPD1 = VALTEMP BSAVED=1 BLOADED=0 %FINISH %IF CAT=13 %THEN ->CHECKB;! for IOITEM, DIOITEM -> PASS1END PASS1(12): TT_RES1_W = OPND (TT_RES1,1) TT_RES2_W = OPND (TT_RES2,2) ASMTCH -> PASS1END PASS1(13): !* IOITEM DIOITEM TT_RES1_W=OPND (TT_RES1,1) %IF BLOADED#0 %AND BSAVED=0 %AND BREGTEMP#0 %THENSTART ! KEEPB(PREVTRIAD) BCORRUPT=1 SAVEB=1 BLOADED=0 BSAVED=1 %FINISH ->DUMPB PASS1(14): LASTBUT1 = PREVTRIAD TT_RES1_W = OPND (TT_RES1,2) -> PASS1END PASS1(15): ARRTR -> PASS1END PASS1(16): INCRTR -> PASS1END PASS1(17): TT_RES2_W = OPND (TT_RES2,2) INITTR -> PASS1END PASS1(18): TT_RES2_W = OPND (TT_RES2,2) DT == RECORD (ADICT + TT_OPD1 << DSCALE) DT_LOOP = LOOP -> PASS1END PASS1(20): TT_OP = REPL ->PASS1END ! PASS1(24): !* IOSPEC TT_RES1_W=OPND (TT_RES1,1) ! PASS1END: %REPEAT !* IF AN INIT TRIAD HAS BEEN FOUND, CHAIN IT NEAR THE END OF THE BLOCK !* (BUT BEFORE GOTO IF PRESENT). %UNLESS INITB = 0 %THENSTART TT == RECORD (ATRIADS + INITB * TRIADLENGTH) TT1 == RECORD (ATRIADS + TT_CHAIN * TRIADLENGTH) %IF TT1_OP = STOREB %THEN TT == TT1 %IF LASTBUT1 = 0 %THEN %C TT1 == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) %C %ELSE TT1 == RECORD (ATRIADS + LASTBUT1 * TRIADLENGTH) TT_CHAIN = TT1_CHAIN TT1_CHAIN = INITB %FINISH ! !* BLOCK-LEVEL DIAGNOSTICS: %IF SRFLAGS & 64 # 0 %THENSTART NEWLINE NEWLINE PRINTSTRING ("BLOCK AFTER OP3B PASS 1") NEWLINE PRBLOCK (BLOCK) PRBLTRIADS (BLOCK) %FINISH ! !* PASS 2. SET UP A TEXT EXTENSION TABLE TO ANALYSE USE CTS TO DETECT !* OUT-OF-BLOCK REFS. EXTNSTART = FREETABS EXTNEND = EXTNSTART - EXTNSIZE CURRTRIAD = START %WHILE GETNEXT = 1 %CYCLE TT == RECORD (ATRIADS + CURRTRIAD * TRIADLENGTH) -> PASS2 (OPCAT (TT_OP)) ! PASS2(0):PASS2(20): NEWLINE NEWLINE PRINTSTRING ("ERROR: OPERATOR VALUE ") WRITE (TT_OP,3) NEWLINE PASS2(1):PASS2(8):PASS2(14):PASS2(16):PASS2(19):PASS2(21): -> PASS2END PASS2(2):PASS2(4):PASS2(6):PASS2(13):PASS2(24): REDUSE (TT_RES1) -> PASS2END PASS2(9): !* SUBR PASS2(17):PASS2(18): PASS2(23): !* MOO PASS2(27): !* CHAR REDUSE (TT_RES2) -> PASS2END PASS2(12): REDUSE (TT_RES1) REDUSE (TT_RES2) -> PASS2END PASS2(3): REDUSE (TT_RES1) CRENT -> PASS2END PASS2(5):PASS2(10):PASS2(25): REDUSE (TT_RES2) CRENT -> PASS2END PASS2(7):PASS2(11):PASS2(15):PASS2(22):PASS2(26): REDUSE (TT_RES1) REDUSE (TT_RES2) CRENT ! PASS2END: %REPEAT ! !* SCAN THRO' TEXT EXTN TABLE LOOKING FOR TRIADS WHICH HAVE OUTSTANDING !* USES, & STORE THEM IN TEMPS. %FOR PTR = EXTNSTART,EXTNSIZE,EXTNEND %CYCLE EX == RECORD (ATABS + PTR) %UNLESS EX_USES = 0 %THENSTART TT == RECORD (ATRIADS + EX_TRIAD * TRIADLENGTH) %IF TT_OP =ARG %OR TT_OP = DARG %OR TT_OP = IARG %C %THEN RESARGS (EX_TRIAD) %C %ELSE PRESVAL (EX_TRIAD) %FINISH %REPEAT FREETABS = EXTNSTART ! BB_FLAGS=BB_FLAGS!BUSED BB_CORRUPT = BCORRUPT %IF BCORRUPT = 0 %AND BLOADED # 0 %THENSTART BB_FLAGS = BB_FLAGS ! BBOEXBIT BBOEXIT=1 %FINISH ! !* BLOCK-LEVEL DIAGNOSTICS: %IF SRFLAGS & 64 # 0 %THENSTART NEWLINE NEWLINE PRINTSTRING ("BLOCK AFTER OP3B PASS 2") NEWLINE PRBLOCK (BLOCK) PRBLTRIADS (BLOCK) %FINISH ! CURRTRIAD = START %WHILE GETNEXT=1 %CYCLE TT==RECORD(ATRIADS+CURRTRIAD*TRIADLENGTH) ->PASS3 (OPCAT (TT_OP)) ! PASS3(0):PASS3(20): PASS3(1):PASS3(8):PASS3(14):PASS3(16):PASS3(19):PASS3(21):PASS3(27): -> PASS3END PASS3(2):PASS3(4):PASS3(6):PASS3(13):PASS3(24): TT_QOPD1 = TRSPEC (TT_RES1) -> PASS3END PASS3(9): !* SUBR PASS3(17):PASS3(18): PASS3(23): !* MOO TT_QOPD2 = TRSPEC (TT_RES2) -> PASS3END PASS3(12): TT_QOPD1 = TRSPEC (TT_RES1) TT_QOPD2 = TRSPEC (TT_RES2) -> PASS3END PASS3(3): TT_QOPD1 = TRSPEC (TT_RES1) -> PASS3END PASS3(5):PASS3(10):PASS3(25): TT_QOPD2 = TRSPEC (TT_RES2) -> PASS3END PASS3(7):PASS3(11):PASS3(15):PASS3(22):PASS3(26): TT_QOPD1 = TRSPEC (TT_RES1) TT_QOPD2 = TRSPEC (TT_RES2) ! PASS3END: %REPEAT ! %END;! BLOKCHAIN ! ! ! ! %INTEGERFUNCTION OPND (%RECORD (RESF) OP,%INTEGER BUSE) ! !************************************************************************** !* CHECKS WHETHER OPERAND REFERS TO A SR-TEMP OR REPL OR REF, & CHANGES * !* ACCORDINGLY. * !* BUSE = 1 POTENTIAL DEFINING OF BREG * !* 2 POTENTIAL USE OF BREG * !* 3 MODIFICATION OF BREG * !* 6 subscript to array el - avoid replacing by destemp * !************************************************************************** ! %INTEGER NEWTR,OPD ! %RECORD (PRECF) %NAME DD %RECORD (TRIADF) %NAME TT,TT1 ! %RECORD (RESF) TEPTR,WOPD ! WOPD = OP %CYCLE OPD = WOPD_H0 %IF WOPD_FORM & TEXTMASK = 0 %THEN %EXIT TT == RECORD (ATRIADS + OPD * TRIADLENGTH) %IF BUSE=6 %THENSTART;! array element - check for dt BUSE=2 %IF TT_OP=REPL %AND TT_QOPD1=DESTEMP %THEN ->L %FINISH %IF TT_OP = REF %THENSTART !* REPLACE REF TRIAD BY ASMT-TO-TE & REPL-TO-TE. TT_OP = REPL %IF TT_QOPD1 & IDMASK # 0 %THENSTART DD == RECORD (ADICT + TT_OPD1 << DSCALE) %IF DD_CLASS & CMNBIT # 0 %THENSTART L: TEPTR_W = CREATETE (TT_MODE) NEWTR = CHAFTER (OPD) TT1 == RECORD (ATRIADS + NEWTR * TRIADLENGTH) TT1_OP = ASMT TT1_RES1 = TEPTR TT1_RES2 = TT_RES1 TT_RES1 = TEPTR %FINISH %FINISH %FINISHELSEUNLESS TT_OP = REPL %OR TT_OP = BRK %THENSTART !* IF TRIAD IS OUT-OF-BLOCK, MUST PRESERVE IN A TEMP. %IF OUTBLOCK (OPD) = 0 %THEN %RESULT = WOPD_W %C %ELSE PRESVAL (OPD) %FINISH !* REPLACE REF TO REPL OR BRK TRIAD BY THEIR OPD1, & TRY AGAIN. ELIM (OPD) WOPD = TT_RES1 %REPEAT !* REFERENCES TO SR-TEMP ARE REPLACED BY B-REG, IF VALID FOR THIS LOOP, !* OR A SUITABLE VALTEMP. %IF WOPD_FORM = SRTEMP %THENSTART %IF OPD = BREGTEMP %THENSTART BUSED = BUSEDBIT %UNLESS BUSE=1 %THENSTART;! unless defining only %IF BLOADED=0 %THENSTART RESETB(PREVTRIAD) BSAVED=1 %FINISH BLOADED=1 %FINISH %UNLESS BUSE=2 %THEN BSAVED=0 %RESULT = BREGOP_W %FINISH WOPD_H0 = BRDUMP(OPD) WOPD_FORM = VALTEMP %RESULT = WOPD_W %FINISH ! %IF WOPD_FORM & IDMASK # 0 %THENSTART ! !* CODE REQUIRED HERE TO OPTIMISE THE ACCESSING OF COMMON ITEMS IN LOOPS !* (EITHER BY DESCRIPTOR OR BY XNB OR CTB). ! ! %FINISH %RESULT = WOPD_W ! %END;! OPND ! ! ! ! %ROUTINE ARGCH ! !*********************************************************************** !* PROCESSES OUT-OF-BLOCK ARGUMENT CHAIN. * !*********************************************************************** ! %INTEGER CHARG,NEWTR ! %RECORD (TRIADF) %NAME TT,TT1 ! TT == RECORD (ATRIADS + CURRTRIAD * TRIADLENGTH) %WHILE TT_QOPD2 # NULL %CYCLE CHARG = TT_OPD2 TT1 == RECORD (ATRIADS + CHARG * TRIADLENGTH) %UNLESS TT1_OP = REPL %OR TT1_OP = BRK %THENSTART %IF OUTBLOCK (CHARG) = 0 %THEN %EXIT !* IF ARG IS OUT-OF-BLOCK, BRING A COPY INTO THIS BLOCK, ADJUSTING !* USE-CTS ACCORDINGLY. NEWTR = CHAFTER (PREVTRIAD) TT_OPD2 = NEWTR TT == RECORD (ATRIADS + NEWTR * TRIADLENGTH) TT_RES1=TT1_RES1 TT_RES2=TT1_RES2 TT_OP=TT1_OP TT_USE=1 %IF TT1_USE # 1 %AND TT1_QOPD1 & TEXTMASK # 0 %THENSTART TT == RECORD (ATRIADS + TT1_OPD1 * TRIADLENGTH) TT_USE = TT_USE + 1 %FINISH TT == RECORD (ATRIADS + NEWTR * TRIADLENGTH) TT_RES1_W = OPND (TT_RES1,2) %IF TT_QOPD1 = BREG %THENSTART TT_OPD1 = BRDUMP(BREGTEMP) TT_QOPD1 = VALTEMP %FINISH %FINISHELSESTART TT_OPD2 = TT1_OPD2 %FINISH ELIM (CHARG) !* LOOP BACK TO CONSIDER NEXT ARG, IF ANY. %REPEAT ! %END;! ARGCH ! ! ! ! %ROUTINE ASMTCH ! !********************************************************************** !* RECHAINS ASMT-TO-TE TRIADS. * !********************************************************************** ! %RECORD (TERECF) %NAME TE ! %INTEGER CHAIN ! %IF TT_QOPD1 = VALTEMP %THENSTART TE == RECORD (ADICT + TT_OPD1 << DSCALE) TE_LOOP = LOOP %IF TT_QOPD2 & TEXTMASK # 0 %THENSTART TT1 == RECORD (ATRIADS + TT_OPD2 * TRIADLENGTH) CHAIN = TT1_CHAIN %UNLESS CHAIN = CURRTRIAD %THENSTART !* RECHAIN ASMT TRIAD AFTER OPD2 TRIAD. TT1_CHAIN = CURRTRIAD TT1 == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) TT1_CHAIN = TT_CHAIN TT_CHAIN = CHAIN CURRTRIAD=PREVTRIAD;! to avoid looping if same text assigned to several Valtemps %FINISH %FINISH %FINISH ! %END;! ASMTCH ! ! %INCLUDE "targ_arrtr" ! ! ! %ROUTINE INCRTR ! !************************************************************************ !* IF OPND1 IS SR-TEMP (I.E. WILL BE B-REG), AND FOLLOWING TRIAD IS * !* ALSO INCR, SWAP THEM. * !* IF OPND1 IS D-TEMP, CHAIN AFTER LAST USE. * !************************************************************************ ! %INTEGER TRID,USETRID ! %RECORD (RESF) OPD1 ! %IF TT_QOPD1 = SRTEMP %THENSTART %IF BLOADED=0 %THEN RESETB(PREVTRIAD) BLOADED=1 BSAVED=0 %CYCLE TRID = TT_CHAIN TT1 == RECORD (ATRIADS + TRID * TRIADLENGTH) %IF TT1_OP # NULL %THEN %EXIT TT_CHAIN = TT1_CHAIN TT1_CHAIN = FREETRIADS FREETRIADS = TRID %REPEAT %UNLESS TT1_OP = INCR %OR TT1_OP = DECR %THEN -> L1 TT_CHAIN = TT1_CHAIN TT == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) TT1_CHAIN = CURRTRIAD TT_CHAIN = TRID CURRTRIAD = TRID TT == TT1 %FINISH %IF TT_QOPD1 # DESTEMP %THEN -> L1 !* TRIAD INCREMENTS A DESCRIPTOR. CHAIN AFTER LAST USE, OR LAST IFUN !* (IF ANY), IN THIS BLOCK. USETRID = 0 OPD1 = TT_RES1 TRID = START TT1 == RECORD (ATRIADS + TRID * TRIADLENGTH) %CYCLE TRID = TT1_CHAIN %IF TRID = CURRTRIAD %THEN %EXIT TT1 == RECORD (ATRIADS + TRID * TRIADLENGTH) %UNLESS TT1_RES1_W = OPD1_W %OR TT1_RES2_W = OPD1_W %THENSTART %UNLESS TT1_OP = IFUN %OR TT1_OP=FUN %C %OR TT1_OP=SUBR %THEN %CONTINUE %FINISHELSESTART %IF TT1_OP = STMT %OR TT1_OP = REPL %OR TT1_OP = NULL %C %THEN %CONTINUE %FINISH USETRID = TRID %REPEAT TT1==RECORD(ATRIADS+USETRID*TRIADLENGTH) %UNLESS USETRID = 0 %OR TT1_OP = ARR %C %OR TT1_OP = DEFARR %OR TT1_OP = ARGARR %C %OR TT1_CHAIN = CURRTRIAD %THENSTART TRID = TT_CHAIN TT_CHAIN = TT1_CHAIN TT1_CHAIN = CURRTRIAD TT1 == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) TT1_CHAIN = TRID TT_OP = PINCR TT_RES2_W = OPND (TT_RES2,2) TT_RES1_W = OPND (TT_RES1,1) CURRTRIAD = PREVTRIAD %FINISHELSESTART L1: TT_RES2_W = OPND (TT_RES2,2) TT_RES1_W = OPND (TT_RES1,1) %FINISH ! %END ! ! ! ! %ROUTINE INITTR ! !********************************************************************** !* REMOVES INIT TRIAD (TOGETHER WITH FOLLOWING STOREB IF PRESENT), * !* FOR CHAINING IN AT END OF BLOCK. * !********************************************************************** ! %INTEGER CHAIN ! %RECORD (TERECF) %NAME TE ! INITB = CURRTRIAD CHAIN = TT_CHAIN TT1 == RECORD (ATRIADS + CHAIN * TRIADLENGTH) %IF TT1_OP = STOREB %THENSTART TE == RECORD (ADICT + TT1_OPD1 << DSCALE) TE_LOOP = LOOP CHAIN = TT1_CHAIN %FINISH TT == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) TT_CHAIN = CHAIN CURRTRIAD = PREVTRIAD ! %END;! INITTR ! ! ! ! %INTEGERFUNCTION BRDUMP(%INTEGER BREGTEMP) ! !***************************************************************************** !* FINDS OR CREATES A VALTEMP ENTRY IN WHICH TO SAVE THE VALUE OF THE * !* SR-TEMP MAPPED ONTO B-REG. * !***************************************************************************** ! %RECORD (SREDF) %NAME SR %RECORD (RESF) TEPTR ! %RECORD (TERECF) %NAME TE ! SR == RECORD (ABLOCKS + BREGTEMP << SRSCALE) %IF SR_DUMP # 0 %THEN %RESULT = SR_DUMP TEPTR_W = CREATETE (INT4) TE == RECORD (ADICT + TEPTR_H0 << DSCALE) TE_FLAGS = SRTEMPBIT SR_DUMP = TEPTR_H0 %RESULT = TEPTR_H0 ! %END;! BRDUMP ! ! ! ! %INTEGERFUNCTION OUTBLOCK (%INTEGER TR) ! !*********************************************************************** !* DECIDES IF GIVEN TRIAD IS DEFINED OUTSIDE CURRENT BLOCK. * !* IF SO RETURNS 1, ELSE 0. * !*********************************************************************** ! %INTEGER TRID ! %RECORD (TRIADF) %NAME TT ! TRID = START %CYCLE TT == RECORD (ATRIADS + TRID * TRIADLENGTH) TRID = TT_CHAIN %IF TRID = TR %THEN %RESULT = 0 %IF TRID = CURRTRIAD %THEN %RESULT = 1 %REPEAT ! %END;! OUTBLOCK ! ! ! ! %ROUTINE PRESVAL (%INTEGER TR) ! !*********************************************************************** !* SAVES INPUT EXPRESSION IN A VALTEMP OR DESTEMP ENTRY, IF NECESSARY. * !*********************************************************************** ! %INTEGER MODE,FLAG,DICT,NEWTR1,NEWTR2,NEWOP,CHAIN ! %RECORD (RESF) QTEMP %RECORD (TRIADF) %NAME TT,TT1,TT2 %RECORD (PRECF) %NAME DD %RECORD (DTRECF) %NAME DT %RECORD (TERECF) %NAME TE ! TT == RECORD (ATRIADS + TR * TRIADLENGTH) MODE = TT_MODE %IF TT_OP = ARGARR %THENSTART %IF MODE = INT2 %OR MODE = CHARMODE %THEN FLAG = ACTARGBIT %C %ELSE FLAG = 0 -> L1 %FINISHELSEIF TT_OP = DEFARR %OR (TT_OP = ARR %AND MODE = CHARMODE) %C %THENSTART FLAG = 0 !* IF EXPRESSION IS A SUBSCRIPTION, EITHER AS LHS OF ASMT, OR AS ACT ARG, !* OR CHAR, WE NEED A DESCRIPTOR, SO SAVE IN A DESTEMP. L1: DICT = ARBASE (TT_RES1) OLDDTCH = DTCH QTEMP_W = CREATEDT (MODE) DT == RECORD (ADICT + QTEMP_H0 << DSCALE) DT_LOOP = 0 DT_FLAGS = FLAG DT_IDENT = DICT NEWOP = DINIT !* CHECK IF DESTEMP SUITABLE FOR GENERATION BY LOADER. %IF TT_QOPD2 & CONSTMASK # 0 %AND TT_QOPD1 & IDMASK # 0 %THENSTART DD == RECORD (ADICT + TT_OPD1 << DSCALE) %IF DD_CLASS & 1 = 0 %THENSTART FLAG = FLAG ! INITLOADBIT DT_FLAGS = FLAG DT_CONST = TT_RES2 QTEMP_H0 = DTDUPL (QTEMP_H0);! REMOVE DUPLICATE IF PRESENT. -> L2 %FINISH %FINISH %FINISHELSESTART !* NOT SUITABLE FOR DESTEMP, SO STORE IN A VALTEMP. QTEMP_W = CREATETE (MODE) TE == RECORD (ADICT + QTEMP_H0 << DSCALE) TE_LOOP = 0 TE_FLAGS = 0 NEWOP = ASMT %FINISH NEWTR1 = CHAFTER (TR) TT1 == RECORD (ATRIADS + NEWTR1 * TRIADLENGTH) CHAIN = TT1_CHAIN TT1 = TT TT1_CHAIN = CHAIN TT1_USE = 1 NEWTR2 = CHAFTER (NEWTR1) TT2 == RECORD (ATRIADS + NEWTR2 * TRIADLENGTH) TT2_OP = NEWOP TT2_OPD2 = NEWTR1 TT2_MODE2 = MODE TT2_QOPD2 = TRIAD TT2_RES1 = QTEMP L2: TT_RES1 = QTEMP TT_OP = REPL ! %END;! PRESVAL ! ! ! ! %INTEGERFUNCTION DTDUPL (%INTEGER DPTR) ! !************************************************************************* !* CHECK FOR DUPLICATE LOADER-INITIALISED DTEMP. IF FOUND DELETE NEW * !* ENTRY AND RETURN POINTER TO OLD ONE. * !************************************************************************* ! %INTEGER PTR ! %RECORD (DTRECF) %NAME DT1,DT2 ! DT1 == RECORD (ADICT + DPTR << DSCALE) PTR = DESTEMPHEAD %CYCLE %IF PTR = DPTR %THEN %RESULT = PTR DT2 == RECORD (ADICT + PTR << DSCALE) %IF DT1_IDENT = DT2_IDENT %AND %C DT1_CONST_W = DT2_CONST_W %AND %C DT1_FLAGS = DT2_FLAGS %THEN %EXIT PTR = DT2_CHAIN %REPEAT DTCH = OLDDTCH INTEGER (DTCH+ADICT) = 0; ! DTCH MUST ALWAYS BE RELATIVE TO ADICT HERE %RESULT = PTR ! %END;! DTDUPL ! ! ! ! %ROUTINE REDUSE (%RECORD (RESF) OP) ! !************************************************************************* !* FINDS TEXT EXTN ENTRY FOR A TRIAD, & REDUCES ITS USE CT BY 1. * !************************************************************************* ! %INTEGER PTR ! %IF OP_FORM & TEXTMASK # 0 %THENSTART %FOR PTR = EXTNSTART,EXTNSIZE,EXTNEND %CYCLE EX == RECORD (ATABS + PTR) %IF EX_TRIAD = OP_H0 %THENSTART EX_USES = EX_USES - 1 %RETURN %FINISH %REPEAT %FINISH ! %END;! REDUSE ! ! ! ! %ROUTINE CRENT ! !*************************************************************************** !* CREATES AN ENTRY IN THE TEXT EXTN TABLE FOR CURRENT TRIAD, & * !* INITIALISES IT. * !*************************************************************************** ! EXTNEND = CREATETAB (EXTNSIZE) EX == RECORD (ATABS + EXTNEND) EX_TRIAD = CURRTRIAD EX_USES = TT_USE ! %END;! CRENT ! ! ! ! %ROUTINE BTEMP (%INTEGER BL) ! !*************************************************************************** !* IF NECESSARY PUTS A LOADB IN FRONT OF FIRST USE OF B-REG IN A BLOCK. * !*************************************************************************** ! %RECORD (BLRECF) %NAME BB,BB1 %RECORD (CONRECF) %NAME CN %RECORD (TRIADF) %NAME TT ! %INTEGER I,PTR,NEXT,TRID ! BB == RECORD (ABLOCKS + BL * BLSIZE) CN == RECORD (ATABS + BB_BCON) %FOR I = 1,1,CN_COUNT %CYCLE %UNLESS CN_BLOCK(I) = 0 %THENSTART BB1 == RECORD (ABLOCKS + CN_BLOCK(I) * BLSIZE) %IF BB1_DEPTH < LOOPDEPTH %THEN %CONTINUE %IF BB1_DEPTH = LOOPDEPTH %AND BB1_FLAGS & BBOEXBIT # 0 %C %THEN %CONTINUE !* B-REG IS NOT BUSY ON EXIT PTR = BB_TEXT TT == RECORD (ATRIADS + PTR * TRIADLENGTH) %CYCLE NEXT = TT_CHAIN TT == RECORD (ATRIADS + NEXT * TRIADLENGTH) %IF (BREGOPN (TT_RES1) = 1 %OR BREGOPN (TT_RES2) = 1) %THENSTART %IF TT_OP = LOADB %THEN ->SCAN %IF TT_OP = INIT %AND TT_QOPD1 = BREG %THEN ->SCAN TRID = CHAFTER (PTR) TT == RECORD (ATRIADS + TRID * TRIADLENGTH) TT_OP = LOADB TT_RES1 = BREGOP TT_QOPD2 = VALTEMP TT_OPD2 = BRDUMP(BREGTEMP) TT_MODE2 = INT4 SCAN: %CYCLE NEXT=TT_CHAIN TT==RECORD(ATRIADS+NEXT*TRIADLENGTH) %IF CORRUPTB(OPCAT(TT_OP))#0 %THEN ->AGAIN %REPEAT %UNTIL TT_OP=STMT %AND TT_USE&SOB#0 %RETURN %FINISH AGAIN: PTR = NEXT %REPEAT %UNTIL TT_OP = STMT %AND TT_USE & SOB # 0 %RETURN %FINISH %REPEAT %IF BB_CORRUPT = 0 %THEN BB_FLAGS = BB_FLAGS ! BBOEXBIT ! %END;! BTEMP ! ! ! ! %ROUTINE RESARGS (%INTEGER TR) ! !************************************************************************** !* ENSURES THAT EXPRESSIONS IN AN OUT-OF-BLOCK ARG-CHAIN ARE SAVED IN * !* VALTEMP OR DESTEMP ENTRIES, IF THEY ARE EXPRESSIONS OR ARRAY ELMTS. * !************************************************************************** ! %RECORD (TRIADF) %NAME TT ! %INTEGER TRID ! TRID = TR %CYCLE TT == RECORD (ATRIADS + TRID * TRIADLENGTH) %IF TT_QOPD1 & TEXTMASK # 0 %THEN PRESVAL (TT_OPD1) TRID = TT_OPD2 %REPEAT %UNTIL TT_QOPD2 & TEXTMASK = 0 ! %END;! RESARGS ! ! ! ! %ROUTINE KEEPB (%INTEGER TR) ! !************************************************************************* !* GENERATES A TRIAD TO PRESERVE CONTENTS OF B-REG IN A VALTEMP. * !************************************************************************* ! %RECORD (TRIADF) %NAME TT ! %INTEGER TRID ! TRID = CHAFTER (TR) TT == RECORD (ATRIADS + TRID * TRIADLENGTH) TT_OP = STOREB TT_QOPD1 = VALTEMP TT_OPD1 = BRDUMP(BREGTEMP) TT_MODE = INT4 TT_RES2 = BREGOP ! %END;! KEEPB ! ! ! ! %ROUTINE RESETB (%INTEGER TR) ! !************************************************************************* !* GENERATES A TRIAD TO RELOAD CONTENTS OF B-REG FROM A VALTEMP. * !************************************************************************* ! %RECORD (TRIADF) %NAME TT ! %INTEGER TRID ! TRID = CHAFTER (TR) TT == RECORD (ATRIADS + TRID * TRIADLENGTH) TT_OP = LOADB TT_RES1 = BREGOP TT_QOPD2 = VALTEMP TT_MODE2 = INT4 TT_OPD2 = BRDUMP(BREGTEMP) TT_MODE = INT4 BSAVED = 1;! avoid redundant stores ! %END;! RESETB ! ! ! ! %INTEGERFUNCTION BREGOPN (%RECORD (RESF) OP) ! !************************************************************************* !* DETERMINE WHETHER THE GIVEN OPERAND IS, OR USES, B-REG. * !************************************************************************* ! %RECORD (TRIADF) %NAME TT ! %IF OP_FORM = BREG %THEN %RESULT = 1 %UNLESS OP_FORM & TEXTMASK # 0 %THEN %RESULT = 0 TT == RECORD (ATRIADS + OP_H0 * TRIADLENGTH) %UNLESS TT_OP = ARR %OR TT_OP = DEFARR %OR TT_OP = ARGARR %C %THEN %RESULT = 0 %IF TT_QOPD2 = BREG %THEN %RESULT = 1 %C %ELSE %RESULT = 0 ! %END;! BREGOPN ! ! ! ! %INTEGERFUNCTION GETNEXT ! !************************************************************************ !* GETS NEXT TRIAD, CHAINING OUT ANY NULLS, AND USING POINTERS CURR- * !* AND PREV-TRIAD. * !************************************************************************ ! PREVTRIAD = CURRTRIAD %CYCLE TT == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) CURRTRIAD = TT_CHAIN %IF CURRTRIAD=0 %THEN %RESULT=0 TT == RECORD (ATRIADS + CURRTRIAD * TRIADLENGTH) %IF TT_OP = STMT %AND TT_USE & SOB # 0 %THEN %RESULT = 0 %UNLESS TT_OP = NULL %THEN %RESULT = 1 TT1 == RECORD (ATRIADS + PREVTRIAD * TRIADLENGTH) TT1_CHAIN = TT_CHAIN TT_CHAIN = FREETRIADS FREETRIADS = CURRTRIAD %REPEAT ! %END;! GETNEXT ! %INTEGERFN TRSPEC(%RECORD(RESF) R) !*********************************************************************** !* ENSURE THAT TRIAD AND ARREL OPERATORS ARE CORRECTLY SET * !* FOR ARREL REFERENCES RELOAD BREG IF NECESSARY * !*********************************************************************** %RECORD(TRIADF)%NAME TR,TT %RECORD(SREDF)%NAME SR %INTEGER CHAIN,CAT %UNLESS R_FORM&TEXTMASK#0 %THEN %RESULT=R_FORM TR==RECORD(ATRIADS+R_H0*TRIADLENGTH) CAT=OPCAT(TR_OP) %IF CAT=15 %AND (TR_USE<2 %OR TR_MODE=CHARMODE) %THENSTART;! ARRAY ELEMENT !* must now check whether this reference will require Breg to be reloaded %IF TR_QOPD2=BREG %THENSTART;! possible CHAIN=TR_CHAIN %WHILE CHAIN#CURRTRIAD %CYCLE TT==RECORD(ATRIADS+CHAIN*TRIADLENGTH) %IF CORRUPTB(OPCAT(TT_OP))#0 %THENSTART %UNLESS TT_OP=CVT %AND TT_MODE>INT8 %THENSTART;! only CVT -> int causes problems SR==RECORD(ABLOCKS+BREGTEMP<