! File: DELAY.BLI ! ! This work was supported by the Advanced Research ! Projects Agency of the Office of the Secretary of ! Defense (F44620-73-C-0074) and is monitored by the ! Air Force Office of Scientific Research. MODULE DELAY(TIMER=EXTERNAL(SIX12))= BEGIN ! DELAY MODULE ! ------------ ! ! SEPT. 1972 ! WULF, WEINSTOCK, WILE, JOHNSSON ! LATER ADDITIONS: ! LEVERETT, KNUEVEN ! ! ! ! THIS MODULE DOES WHATEVER LOCAL OPTIMIZATION IS POSSIBLE BEFORE ! TEMPORARY NAME BINDING. IT ACCEPTS A TREE FROM THE SYNTAX/FLOWAN ! MODULES AND PASSES IT ON TO THE TNBIND MODULE. ! ! SOME OF ITS FUNCTIONS ARE: ! ! 1. TO INITIALIZE AREAS FOR TNBIND AND CODE. FOR EXAMPLE IT MAKES ! SURE THE "CODED" AND "BOUND" BITS ARE ZEROED. IT ALSO ! RELEASES LISTS USED FOR CODE MOTION OPTIMIZATION BY FLOWAN SO ! THAT SPACE IN A GT NODE CAN BE REUSED. ! ! 2. TO CALCULATE COMPLEXITIES AND DECIDE TARGETING FOR CODE AND ! TNBIND. THUS IT CALCULATES A CODESIZE COMPLEXITY AND ! A REGISTER USE COMPLEXITY. ! ! 3. TO USE THE MOST EFFICIENT ADDRESSING POSSIBLE TO EFFECT A ! SAVINGS IN OPERATIONS PERFORMED. THUS IF A IS A REGISTER, ! Z_.(.A+2); WILL GENERATE MOV 2(A),Z, AND Z_..(.A+2); ! WILL GENERATE MOV @2(A),Z; ! IT IS DELAY WHO DETERMINES IF THIS IS POSSIBLE (THE CODE ! IS GENERATED IN "CODE"). ! ! 4. TO ELIMINATE UNNECESSARY OPERATIONS. FOR EXAMPLE: ! A_.A AND 0 BECOMES ! A_0; ! NOTE: THE TREE REMAINS THE SAME, THE "AND" NODE IS SET UP ! TO INDICATE ITS RESULT IS ZERO. ! ! 5. TO CONVERT TO ROUTINE CALLS, THOSE BLISS OPERATIONS THAT ! ARE NOT DEFINED ON A PDP-11 SUCH AS MULTIPLY AND DIVIDE. ! THIS IS DONE ONLY IN THE CASE WHERE THE OPERATION IS NEEDED ! (SEE #4). ! ! ! THE MODULE IS ENTERED BY A CALL ON ROUTINE DELAY. THE PARAMETER ! PASSED IS CALLED A REQUEST WORD (SEE THE REQUEST WORD FIELD DEFINITIONS ! IN THE BODY OF THE MODULE BELOW). ! ! INFORMATION INCLUDED IS: ! ! A. THE ADDRESS OF THE NODE TO BE DELAYED. ! ! B. THE WAY IN WHICH THE RESULT WILL BE USED. (IF ITS A CSE-PARENT ! IT MUST END UP IN A TEMP. IF ITS ON THE LEFT OF A STORE, ! WE ARE USING IT AS AN ADDRESS, ON THE RIGHT AS AN OPERAND). ! ! C. WHAT KIND OF VALUE DO WE NEED. (IF ITS THE "DO" PART OF A ! LOOP, NO VALUE IS NEEDED. IF ITS THE BOOLEAN OF AN "IF" WE NEED ! CONTROL FLOW ONLY. IF ITS THE RIGHT SIDE OF A STORE WE NEED A ! REAL VALUE). ! ! D. MUST THE RESULT BE POSITIVE, OR ARE WE PREPARED TO HANDLE THE ! NEG BIT. ! ! E. MUST THE RESULT BE UNCOMPLEMENTED, OR ARE WE PREPARED TO HANDLE THE ! NOT BIT. ! ! ! THE ROUTINE DELAY PASSES THIS INFORMATION TO THE APPROPRIATE DELAYER ! WITH THE POSSIBLE EXCEPTION OF THE INFORMATION DESCRIBED IN "B" ABOVE. ! THIS INFORMATION IT HANDLES ITSELF UNLESS IT SPECIFIED OPERAND. ! ! EACH OF THE DELAYERS DOES WHAT IT CAN WITH A NODE (INCLUDING ! CALLING DELAY ON EACH OF ITS SUB-NODES) AND RETURNS A RESULT WORD. ! (SEE FIELD INFORMATION IN "DTC.BEG"). ! ! INFORMATION IN THE RESULT WORD INCLUDES: ! ! A. IS THE RESULT A REAL VALUE OR CONTROL FLOW. ! ! B. IS IT A LITERAL. ! ! C. IF ITS A LITERAL, IS ITS VALUE ONE OF THE INTERESTING ! LITERAL CASES. ! ! D. WHAT KIND OF POSITION AND SIZE FIELD IS ASSOCIATED WITH ! THE NODE. ! ! E. SHOULD THE RESULT BE INTERPRETED AS AN IMMEDIATE VALUE. ! ! F. DOES THE NODE INVOLVE A DESTROYABLE TEMPRORARY. ! ! G. IS THE INFORMATION IN THE NODE REALLY THE NEGATIVE ! (COMPLEMENT) OF THE REAL RESULT. ! ! ! AFTER A DELAYER CALLS DELAY ON ITS SUB-NODES, IT CAN WORK WITH THE ! RESULTS BEFORE RETURNING. IF IT DETERMINES A CONDITION THAT IT IS ! UNABLE TO HANDLE, IT CAN CALL THE ROUTINE "LOADNODE" TO FORCE ! WHAT IT HAS INTO A REGISTER. THIS HAS THE RESULT OF GUARANTEEING ! THE PERFORMANCE OF ALL OUTSTANDING NEGATES OR ! COMPLEMENTS ON THE NODE. ! ! WHEN THE FIRST CALL ON DELAY IS RETURNED FROM, NO FURTHER CLEANUP IS ! NECESSARY BEFORE CALLING TNBIND. SWITCHES NOLIST; REQUIRE COMMON.BEG; REQUIRE PREDEF.BEG; REQUIRE GTST.BEG; REQUIRE ST.BEG; REQUIRE GTX.BEG; REQUIRE TN.BEG; REQUIRE LDSF1.BEG; REQUIRE ERROR.BEG; SWITCHES LIST; REQUIRE DTC.BEG; EXTERNAL GETTN, ! FROM THE LOW SEGMENT OLDFIXLIST, ! FROM LSTPKG XSORTENTER; BEGIN STRUCTURE STATEWD[I,J]=(.STATEWD)<.I,.J>; MACRO AWORD=STATEWD$; STRUCTURE COMPACT[WIDTH,NO]=[1+NO/(36/WIDTH)] (.COMPACT+.WIDTH/(36/WIDTH))<.WIDTH MOD (36/WIDTH),WIDTH>; ! ! THE "KFIELDS" CONTROL THE DELAYING DESIRED FOR A NODE. THE ! DELAY ROUTINE PARAMETER "NODESW" IS MAPPED WITH THE LEXEME ! STRUCTURE TO GO WITH THESE FIELDS. ! ! A. TO TEST THE CURRENT NODE FOR A PARTICULAR CONTROL REQUEST, ! USE THE CONSTANT WITH THE SUFFIX "R" (FOR REQUESTED); E. G. ! FOR OPERND, USE OPERNDR. ! ! B. TO SET THE REQUESTED CONTROL FIELDS (ON THE WAY DOWN), USE ! THE CONSTANT SUFFIXED BY "K", ADDED TO THE LEXEME; E. G. ! LDELAY(OPERNDK+REALVALK+NEGNPK+MUNCOMPNK). ! MACRO KFIELDS=25,10$, CKF=34,2$, ! CODE VALUE CONTROL CTKF=32,2$, ! CODE VALUE TYPE (FLOW, REAL, NONE) NPKF=30,2$, ! NEG POS NTKF=28,2$, ! NOT CONTROL NOPTMF=26,2$, ! OP-TO-MEM, CHOICE OF TARGET PATH WLITF=25,1$; ! FOR RESULT OF STORE NODE ! CKF VALUES FIELDK(34,ARBITRARY,0); ! PASSED BY +,- NODES TO BOTH OPNDS FIELDK(34,OPERND,1); ! PASSED BY MOST NODES FIELDK(34,ADDRESS,2); ! PASSED BY DOT, POINTER, & STORE NODES ! (TO THEIR LEFT OPNDS) FIELDK(34,TEMP,3); ! PASSED TO LIST NODES IF CSE'S BIND CKFPOS=34; ! SPECIAL CTKF VALUES FIELDK(34,LEFTSIDE,0); FIELDK(34,RITESIDE,1); ! CTKF VALUES FIELDK(32,REALVAL,0); FIELDK(32,FLOWVAL,1); FIELDK(32,DCVAL,2); FIELDK(32,NORESULT,3); BIND CTKFPOS=32; ! NPKF VALUES FIELDK(30,DCNP,0); FIELDK(30,NEGNP,1); FIELDK(30,POSNP,2); FIELDK(30,MPOSNP,3); ! NTKF VALUES FIELDK(28,DCN,0); FIELDK(28,COMPN,1); FIELDK(28,UNCOMPN,2); FIELDK(28,MUNCOMPN,3); ! NOPTM VALUES FIELDK(26,DCSW,0); FIELDK(26,NSWP,1); FIELDK(26,SWP,2); ! WLIT VALUES FIELDK(25,WANTLIT,1); BIND REQUESTPOS=25; ! REQUEST MACROS MACRO XREQ(VNAME)=(.NODESW[ID(VNAME)Q,2] EQL VNAME)$, X1REQ(VNAME)=(.NODESW[ID(VNAME)Q,1] EQL VNAME)$, ADDRESSR=XREQ(ADDRESS)$, ARBITRARYR=XREQ(ARBITRARY)$, COMPNR=XREQ(COMPN)$, DCNR=XREQ(DCN)$, DCNPR=XREQ(DCNP)$, DCVALR=XREQ(DCVAL)$, FLOWVALR=XREQ(FLOWVAL)$, LEFTSIDER=XREQ(LEFTSIDE)$, MPOSNPR=XREQ(MPOSNP)$, MUNCOMPNR=XREQ(MUNCOMPN)$, NEGNPR=XREQ(NEGNP)$, NORESULTR=XREQ(NORESULT)$, OPERNDR=XREQ(OPERND)$, POSNPR=XREQ(POSNP)$, REALVALR=XREQ(REALVAL)$, TEMPR=XREQ(TEMP)$, DCSWR=XREQ(DCSW)$, NSWPR=XREQ(NSWP)$, SWPR=XREQ(SWP)$, UNCOMPNR=XREQ(UNCOMPN)$, WANTLITR=X1REQ(WANTLIT)$; ! MACROS TO SET THE RESULT WORD (STATE) IN THE CURRENT NODE MACRO SL(V)=NODE[NSLF]_V$, SRF(V)=NODE[NSRFF]_V$, SSL=NODE[NSSLF]_1$, SSP(V)=NODE[NSSPF]_V$, KNEG=NODE[NKNEGF]_1$, KNOT=NODE[NKNOTF]_1$, IDT=NODE[NIDTF]_1$; ! MACROS TO TEST A RESULT WORD MACRO ISIDT(XOP)=.XOP[IDTF]$, ISLIT(XOP)=(.XOP[SLF] AND .XOP[IMMF])$, ISLITLEX(XOP)=(.XOP[SLF])$, ISPOS(XOP)=(NOT .XOP[KNEGF])$, ISSYM(XOP)=(.XOP[LTYPF] EQL BNDVAR)$; ! MACROS TO COPY FIELDS FROM NODES AND RESULTS MACRO CKFIELDS(OP)=.OP[RWORDF]^RESULTPOS$; MACRO RCMO=NODE[RCMOF]_1$, RCMT=NODE[RCMTF]_1$, RCNT=NODE[RCNTF]_1$, RCOPT=NODE[RCOPTF]_1$, RCA=NODE[RCAF]_1$, RCS=NODE[RCSF]_1$, RCC=NODE[RCCF]_1$; ! OTHER BITS MACRO G=RCOPT$, % LABELREQD=NODE[LABELREQDF]_1$, % SYMOFF=NODE[SYMOFFF]_1$; ! MACROS TO SET GT ENTRIES MACRO M(V)=NODE[MODE]_V$, NX(V)=NODE[NODEX]_V$, O(V)=NODE[OFFSETF]_V$, P(POS,SIZ)=(NODE[POSF]_POS; NODE[SIZEF]_SIZ)$, R(REG)=NODE[REGF]_REG$; COMMENT ! LDELAY, RDELAY, UDELAY, AND DLY ! ! THESE MACROS SIMPLIFY THE PROCESS OF DELAYING OPERANDS OF THE ! CURRENT NODE. 'KFLD' IS THE SET OF 'REQUEST WORD' FIELD VALUES ! WHICH ARE PASSED DOWN TO THE SUBNODE AT HAND. ! LDELAY DELAYS THE LEFT SUBNODE, PUTS RESULT WORD IN 'LOP' ! RDELAY DELAYS THE RIGHT SUBNODE, PUTS RESULT WORD IN 'ROP' ! UDELAY DELAYS THE ONLY SUBNODE, PUTS RESULT WORD IN 'UOP'. ! THE INTERFACE BETWEEN THESE THREE AND THE ACTUAL ROUTINE, 'DELAY', ! IS PROVIDED BY MACRO 'DLY'. NOTICE THAT IF THE RESULT WORD AFTER ! 'DELAY' INDICATES (BY ITS 'SLF' BIT) THAT ALTHOUGH A GT-NODE WAS ! DELAYED ITS RESULT WAS A LITERAL VALUE, DLY RETRIEVES THAT LITERAL ! AND PUTS IT IN THE DESIGNATED LOCAL (E.G. 'LOP'). ! AS AN EXAMPLE OF DLY EXPANSION, CONSIDER: ! DLY(LOP,OPR1,REALVALK+...) ! WHICH EXPANDS TO: ! (LOP_NODE[OPR1]_DELAY(REALVALK+...+.NODE[XOPR1]); ! IF .LOP[SLF] AND .LOP[LTYPF] EQL GTTYP THEN ! LOP_CKFIELDS(LOP)+LEXOUT(LITTYP,.LOPST[OFFSETF])) ! MACRO LDELAY(KFLD)=DLY(LOP,OPR1,KFLD)$, RDELAY(KFLD)=DLY(ROP,OPR2,KFLD)$, UDELAY(KFLD)=DLY(UOP,OPR1,KFLD)$, DLY(PROG,NOD,CONT)= (PROG_NODE[NOD]_DELAY(CONT+.NODE[ID(X)NOD]); IF .PROG[SLF] AND .PROG[LTYPF] EQL GTTYP THEN PROG_CKFIELDS(PROG)+LEXOUT(LITTYP,.ID(PROG)ST[OFFSETF]))$; ! MACROS TO MODIFY GT ENTRIES IN "CANONICAL" WAYS. MACRO ADDORSUB(NODE)=ONEOF(.GT[NODE,NODEX],BIT2(SADDOP,SMINOP))$; COMMENT ! CHECKCSE ! ! FUNCTION: ! FORCE A TEMP REQUEST ON THE CURRENT NODE ! IF IT IS A LARGE CSE. OTHERWISE, INDICATE WHETHER OR NOT ! THE CURRENT CKF REQUEST IS "OPERAND". ! VALUE: ! -1 -- IF TEMP REQUEST FORCED ! 0 -- IF OPERAND REQUEST ! 1 -- IF ARBITRARY OR ADDRESS REQUEST, ! OR TEMP REQUEST NOT FORCED HERE ! MACRO CHECKCSE=(IF ISLARGECSE(NODE) THEN (FORCETEMP;-1) ELSE IF NOT OPERNDR THEN (1) ELSE 0)$; COMMENT ! CHECKOPNDCSE ! ! FUNCTION: ! IF ONE OPERAND OF THE CURRENT NODE IS A GT-NODE WHILE THE ! OTHER OPERAND IS NOT (I.E. A LITERAL OR SYMBOL), MAKE SURE ! THAT IF THE GT-NODE OPERAND IS A CSE ITS CSE-CHAIN WON'T ! BE UNDONE. ! VALID, OBVIOUSLY, ONLY ON BINARY OPERATOR NODES; USED ONLY ! ON +,- NODES. ! MACRO CHECKOPNDCSE= BEGIN BIND GTVEC XO1=NODE[OPR1]:XO2=NODE[OPR2], LEXEME LO1=NODE[OPR1]:LO2=NODE[OPR2]; IF .NODE[DONTUNLINK] THEN EXITBLOCK; IF .LO1[LTYPF] EQL GTTYP THEN IF .LO2[LTYPF] NEQ GTTYP THEN EXITBLOCK GT[.XO1[CSPARENT],DONTUNLINK]_ (.GT[.XO1[CSPARENT],NODEX] LEQ MAXOPERATOR); IF .LO2[LTYPF] EQL GTTYP THEN IF .LO1[LTYPF] NEQ GTTYP THEN GT[.XO2[CSPARENT],DONTUNLINK]_ (.GT[.XO2[CSPARENT],NODEX] LEQ MAXOPERATOR); END$; COMMENT ! CLITVALUE ! ! FUNCTION: ! VALID ONLY FOR A LEXEME WHOSE 'SLF' BIT IS ON; GET THE ! LITERAL VALUE WHICH 'LEX' REPRESENTS. ! MACRO CLITVALUE(LEX)=(IF .LEX[LTYPF] EQL LITTYP THEN LITVALUE(.LEX) ELSE (BIND GTVEC N=LEX; .N[OFFSETF]))$; MACRO CODEOFF=NOT .NODE[MUSTGENCODE]$; MACRO DKAYCE=CASE .WHICH OF$; COMMENT ! DEFAULTFIELDVALUES ! ! FUNCTION: ! THIS MACRO, CALLED BY ALMOST ALL THE NODE-SPECIFIC DELAYERS, ! SETS VARIOUS FIELDS IN THE NODE TO 'DEFAULT' VALUES BEFORE ! THE DELAYER STARTS TO DO ITS THING TO THOSE FIELDS. ALSO ! SEE ABOVE, 'MACROS TO SET GT ENTRIES'. ! MACRO DEFAULTFIELDVALUES= (M(GENREG); P(0,16); R(0); O(0); SETRES(RFREALK+LFOTHERK+PFNONEK); NODE[COMPLEXITY]_0; NODE[CXBITS]_0; G)$; COMMENT ! DELAYR ! ! FUNCTION: ! PROVIDES A STANDARD HEADER (PROLOG) FOR ALL OF THE NODE-SPECIFIC ! DELAYERS, AS WELL AS A FEW OTHER ROUTINES. ! NAME OF ROUTINE: 'RNAME' ! ARGUMENTS TO ROUTINE: 'NODE' - A REQUEST WORD; MAPPED TO STVEC STRUCTURE ! 'NODESW' = 'NODE', MAPPED TO STATEWD STRUCTURE ! TO GET AT REQUEST & RESULT FIELDS ! LOCALS IN ROUTINE: ! 'LOP'='LOPST' - STATEWD-STVEC, USUALLY 'LEFT OPERAND' OF AN ! OPERATOR NODE. ! 'ROP'='ROPST' - STATEWD-STVEC, USUALLY 'RIGHT OPERAND' ! 'UOP'='UOPST' - STATEWD-STVEC, USUALLY FIRST OPERAND OF SOME NODE ! 'WHICH' - GENERAL PURPOSE CASE INDEX; SEE ALSO MACRO 'DKAYCE' ! MACRO DELAYR(RNAME)=ROUTINE RNAME(NODE)= BEGIN MAP STVEC NODE; BIND STATEWD NODESW=NODE; LOCAL STATEWD LOP:ROP, WHICH; BIND STATEWD UOP=LOP; BIND STVEC LOPST=LOP:ROPST=ROP:UOPST=UOP;$; MACRO DELAYT(A,B,C,D)=BIND COMPACT CASEPLIT[9,16]= PLIT(PACK4 A, PACK4 B, PACK4 C, PACK4 D)$; COMMENT ! FIXCOND ! ! FUNCTION: ! MAKE SURE THAT VARIOUS OPERANDS OF CONTROL NODES (IF NODES, ! LOOP NODES) ARE GT-NODES, BECAUSE ONLY A GT-NODE HAS AN ASSOCIATED ! 'LABELF' FIELD AND A 'NODE LABEL' AS USED IN CODE GENERATION. ! MACRO FIXCOND(WOP)=(LOCAL LEXEME XOP; BIND STVEC XOPST=XOP; XOP_.WOP; IF .XOP[LTYPF] NEQ GTTYP THEN (LOCAL T; T_.XOP; XOP_WOP_LOADNODE(.XOP); IF .NODE[NODEX] EQL SYNIF THEN IF FLOWVALR THEN (COPYRESULT(.XOP,.T); WOP_STATEMAKE(.WOP); XOPST[RCMTF]_FALSE; XOPST[NSRFF]_RFFLOW) ELSE XOPST[NSRFF]_(IF NORESULTR THEN RFNONE ELSE RFREAL) ELSE XOPST[NSRFF]_RFNONE; XOPST[MUSTGENCODE]_1); .XOP)$; COMMENT ! FORCETEMP ! ! FUNCTION: ! CHANGE THE CURRENT REQUEST WORD TO GET A 'TEMP' CKF REQUEST, WITH ! ASSOCIATED CTKF, NPKF, AND NTKF VALUES. ! MACRO FORCETEMP=NODESW_.NODESW[LEXPART]+TEMPK+REALVALK+MPOSNPK+MUNCOMPNK$; COMMENT ! ISNCSE ! ! FUNCTION: ! PREDICATE WHICH IS TRUE IF 'NODE' IS A 'NAME-CSE' (THAT IS, ! CREATED BY A CALL ON GETLOAD OR GETFAKE). ! MACRO ISNCSE(NODE)=(IF (.NODE[NODEX] EQL SYNNULL OR .NODE[NODEX] EQL SPLUSOP) THEN IF .NODE[REGF] GEQ 8 THEN .GT[.NODE[REGF],BNDTYP] EQL BNDNCSE)$; COMMENT ! LITRESULT ! ! FUNCTION: ! DELAYS THE LITERAL VALUE OF THE CURRENT NODE (IN ITS ! 'OFFSETF' FIELD) AND SETS ITS STATEWORD INFO ACCORDINGLY. ! MACRO LITRESULT=SETRES(DELAY(ARBITRARYK+REALVALK+MUNCOMPNK+MPOSNPK+ LITLEXEME(.NODE[OFFSETF])))$; MACRO MAKEAN(LEX)= IF .LEX[LTYPF] EQL BNDVAR OR .LEX[LTYPF] EQL LITTYP THEN .LEX ELSE LEXOUT((IF .ID(LEX)ST[SYMOFFF] THEN BNDVAR ELSE LITTYP), .ID(LEX)ST[OFFSETF])$; MACRO MAKESTATE=STATEMAKE(.NODE)$; COMMENT ! MINUS2 ! ! FUNCTION: ! DETERMINE (FOR +,- NODE) WHETHER BOTH OF THESE ARE TRUE: ! (1) ONE OF ITS OPERANDS ('XOP') IS LITERAL +-2 ! (2) THE SIGN OF THAT OPERAND IS OPPOSITE THE SIGN OF THE ! OTHER OPERAND. ! MACRO MINUS2(POSORNEG,XOP)=(REGISTER X;X_EXTEND(CLITVALUE(XOP)); IF POSORNEG THEN X_-.X; .X EQL -2)$; MACRO NEGATEOFFSET=O((-.NODE[OFFSETF]) AND #177777)$; MACRO NORESULTCHECK=(IF NORESULTR THEN NORESULTK ELSE REALVALK)$; MACRO NORESULTSET=(SETRES(RFNONEK+LFZEROK+PFNONEK+LITK); NODE[CXBITS]_0; M(ABSOLUTE); NODE[CSCOMPL]_CALCCSCOMPL(.NODE))$; COMMENT ! NORESULTRET ! ! FUNCTION: ! THIS MACRO IS CALLED BY MANY NODE-SPECIFIC DELAYERS JUST AFTER ! 'DEFAULTFIELDVALUES'. THE IDEA IS THAT IF THE CTKF REQUEST IS ! FOR 'NORESULT', E.G. THE CURRENT NODE IS THE 'DO' PART OF A ! WHILE-DO NODE, MOST OF THE ACTIONS OF THAT DELAYER ARE SKIPPED: ! A FEW NECESSARY FIELDS ARE FILLED, THEN 'RETURN' IS EXECUTED. ! MACRO NORESULTRET=IF NORESULTR THEN (NORESULTSET; RSTATE)$; MACRO OFFNEG(XOP)=(LOCAL LEXEME ND;ND_.XOP;ND[KNEGF]_0;XOP_.ND)$; MACRO OFFNOT(XOP)=(LOCAL LEXEME ND;ND_.XOP;ND[KNOTF]_0;XOP_.ND)$; MACRO ONEUSE(N)=(.GT[.GT[.N,CSPARENT],OCCF] EQL 1)$; MACRO OTHEROP(NODEX1,NODEX2)=(.NODE[NODEX] XOR (NODEX1 XOR NODEX2))$; MACRO PACK4(A,B,C,D)=(PCK1(D)^27+PCK1(C)^18+PCK1(B)^9+PCK1(A))$, PCK1(X)=(IF X LSS 0 THEN 1^8+(-X) ELSE X)$; COMMENT ! POF2 ! ! FUNCTION: ! DETERMINE IF X IS A POWER OF 2 OR NOT. ! NOTE THAT X IS PRESUMED TO BE POSITIVE OR ZERO. ! MACRO POF2(X)=((X AND (-X)) EQL X)$; MACRO PULSE(X)=PULSELIST(PULSEDELAY,.NODE[X],0)$; MACRO PULSEINFO=(IF ONEUSE(NODE) THEN ARBITRARYK ELSE TEMPK)+REALVALK+MPOSNPK+MUNCOMPNK$; MACRO RSTATE=RETURN MAKESTATE$; MACRO SETCONTROL=NODE[CORCSEF]_1$; COMMENT ! SETIDTCONTROL ! ! SET THE 'IDT' BIT IN A TYPICAL 'CONTROL' NODE - I.E. PRACTICALLY ! ANY NODE THAT'S NOT AN OPERATOR. ! MACRO SETIDTCONTROL=NODE[NIDTF]_1$; COMMENT ! SETIDTOP ! ! SET OR CLEAR THE 'IDT' BIT IN A TYPICAL BINARY OPERATOR NODE. ! MACRO SETIDTOP=NODE[NIDTF]_NOT ISCSE(NODE)$; COMMENT ! SETIDTUOP ! ! SET OR CLEAR THE 'IDT' BIT IN A TYPICAL (NON-CODE-GENERATING) ! UNARY OPERATOR NODE, SUCH AS DOT, UNARY - , 'NOT'. ! MACRO SETIDTUOP=NODE[NIDTF]_NOT ISCSE(NODE) AND ISIDT(UOP)$; COMMENT ! SETLCONF ! ! SETTLE CONFLICT ! ! FUNCTION: RESOLVE A CONFLICT BETWEEN A NEG OR NOT ! REQUEST FROM THE ANCESTOR NODE, AND THE ! CURRENT NODE'S NEG OR NOT CONDITION, ! BY CALLING LOADNODE IF NECESSARY. ! MACRO SETLCONF(REQST,STATEBIT,RESULT) = (IF (REQST) AND (STATEBIT) THEN LOADNODE(RESULT) ELSE (RESULT)) $; COMMENT ! SETRES ! ! FUNCTION: ! STORE THE RESULT-WORD-FIELDS OF WORD 'N' IN THE ! STATEWORD OF THE CURRENT NODE. ! MACRO SETRES(N)=(NODE[NRWORDF]_(N)^(-RESULTPOS))$; COMMENT ! SETRESULT ! ! FUNCTION: ! CAUSE THE CURRENT NODE TO LOOK LIKE ! THE ALREADY-DELAYED NODE 'XOP' ! MACRO SETRESULT(XOP)=COPYRESULT(.NODE,.XOP)$; COMMENT ! SETRESULTLIT ! ! FUNCTION: ! THE EQUIVALENT OF 'SETRESULT' GIVEN A LITERAL LEXEME ! MACRO SETRESULTLIT(V)=(O(V); R(PC); M(ABSOLUTE); P(0,16); LITRESULT)$; MACRO STOREAN(NODE,LEX)= (NODE[OFFSETF]_.LEX[ADDRF]; IF (NODE[SYMOFFF]_.LEX[LTYPF] EQL BNDVAR) THEN IF .ID(LEX)ST[MODE] EQL INDEXED THEN (NODE[MODE]_INDEXED; R(.ID(LEX)ST[REGF])))$; COMMENT ! SWAPOP ! ! FUNCTION: ! INTERCHANGE THE LEFT-RIGHT RELATIONSHIP OF THE TWO OPERANDS ! OF THE CURRENT (BINARY OPERATOR) NODE. SWAPS THE LEXEMES ! IN THE GT-NODE AND THE LOCAL RESULT WORDS 'LOP' AND 'ROP'; ! ALSO FLIPS THE TPATH BIT. ! MACRO SWAPOP=(SWAP(LOP,ROP); SWAP(NODE[OPR1],NODE[OPR2]); XTPATH)$; MACRO XTPATH=(NODE[TPATH]_.NODE[TPATH] XOR 1)$; COMMENT ! UNDONE, UNDONEPARENT ! ! FUNCTION: ! PREDICATES TO DETERMINE IF 'NODE' WAS A CSE OR CSE PARENT THAT ! WAS UNDONE (BY ROUTINE UNDOCSE). THEY ARE NOT FOOLPROOF (THEY ! WOULD BE TRIPPED UP BY BOGUS-NODE SITUATIONS), BUT IN THE ! CONTEXTS IN WHICH THEY ARE CALLED (SEE PCSEDOT AND UNDOCSE), ! THIS IS NOT A PROBLEM. ! MACRO UNDONE(NODE)=(.NODE[CSPARENT] NEQ .NODE AND ONEUSE(NODE))$, UNDONEPARENT(NODE)=(IF .NODE[CSTHREAD] NEQ 0 THEN .GT[.NODE[CSTHREAD],MUSTGENCODE])$; ! DADD TYPES--MAY BE USEFUL FOR MULTIPLY AND SHIFT. SEE ! ADDCLASS ROUTINE BELOW. BIND ADL=0, ! LITERAL ADNR=1, ! RELOCATABLE NAME ADT=2, ! .TEMP OR .X ADTL=3, ! .TEMP + LITERAL ADNT=4, ! LOCAL OR OWN AND PIC NAMES ADTNR=5; ! .TEMP + RELOCATABLE NAME FORWARD ADDAN, ADDCLASS, CALCCSCOMPL, CKDISTMULT, COMPLICATED, COPYAROUND, COPYRESULT, CREATESWO, DADD, DANDOR, DCALL, DCASE, DCOMP, DDO, DDOT, DELAY, DEFERIT, DEQVXOR, DFTYPE, DIF, DINCR, DLABEL, DLEAVE, DLIT, DMAXMIN, DMULDIVMOD, DNEG, DNOT, DNULL, DPLUS, DPOINTER, DREL, DROTSHIFT, DROUT, DSELECT, DSTORE, DSWAB, DSYM, DWU, EQLPOSSIZE, ISOPTOMEM, XLOADNODE, LOADNODE, MAKEROUTINE, NEGLIT, OPCOMPL, PCSEDOT, PULSEDELAY, SELECTEVALORDER, STATEMAKE, UNDOCSE, UNLINKCSE; ROUTINE ADDAN(LAN,RAN)= BEGIN BIND STVEC LANST=LAN:RANST=RAN; MAP LEXEME LAN:RAN; IF .RAN[LTYPF] EQL LITTYP THEN (IF .RAN[KNEGF] THEN RAN_LITLEXEME(-LITVALUE(.RAN)); IF .LAN[LTYPF] EQL LITTYP THEN RETURN LITLEXEME(LITVALUE(.RAN)+ (IF .LAN[KNEGF] THEN -LITVALUE(.LAN) ELSE LITVALUE(.LAN))); IF LITVALUE(.RAN) EQL 0 THEN RETURN .LAN; ! N+L OR -N+L IF .LAN[KNEGF] THEN RETURN KNEGK+ADDAN(.LAN[LEXPART],KNEGK+.RAN); IF .LANST[TYPEF] EQL LOCALT THEN IF .LANST[REGF] GEQ 8 THEN WARNEM(0,WALOCERR); RETURN CREATESWO(.LAN,.RAN)); ! X+N, X-N IF .LAN[LTYPF] EQL LITTYP THEN RETURN ADDAN(.RAN,.LAN); ! N+N, N-N, -N+N, -N-N IF .LAN[KNEGF] EQL .RAN[KNEGF] THEN RETURN 0; ! N-N, -N+N IF .LAN[KNEGF] THEN SWAP(LAN,RAN); ! N-N IF BASESYM(.LANST) NEQ BASESYM(.RANST) THEN RETURN 0 ELSE RETURN LITLEXEME(.LANST[OFFSETF]-.RANST[OFFSETF]) END; ROUTINE ADDCLASS(LEX)= %% BEGIN MAP LEXEME LEX; BIND STVEC LEXST=LEX; IF .LEX[LTYPF] EQL LITTYP THEN ADL ELSE IF .LEX[LTYPF] EQL BNDVAR THEN IF .LEXST[MODE] EQL INDEXED THEN ADNT ELSE ADNR ELSE IF .LEX[LTYPF] EQL GTTYP THEN IF NOT .LEXST[NIMMF] THEN ADT ELSE IF .LEXST[MODE] EQL GENREG THEN ADT ELSE IF .LEXST[MODE] EQL INDEXED THEN IF .LEXST[REGF] NEQ 0 THEN ADNT ELSE IF .LEXST[SYMOFFF] THEN ADTNR ELSE ADTL ELSE PUNT(ERINVMODE) ELSE PUNT(ERINVLEXT) END; COMMENT ! CALCCSCOMPL ! ! FUNCTION: ! COMPUTE A MEASURE OF THE 'CODE SIZE COMPLEXITY' ! OF THE CURRENT NODE. ! SPECIFICS: ! COMPUTE A COMPLEXITY FOR THE OPERATOR ITSELF, ! THEN ADD IN THE CSCOMPL'S OF ALL THE OPERANDS. ! DELAYR(CALCCSCOMPL) LOCAL CSIZE;CSIZE_OPCOMPL(.NODE);; INCR I FROM 0 TO .NODE[NODESIZEF]-1 DO BEGIN UOP_.NODE[OPERAND(.I)]; IF .UOP[LTYPF] EQL GTTYP THEN CSIZE_.CSIZE+.UOPST[CSCOMPL] END; .CSIZE END; ROUTINE CKDISTMULT(NODE,COMMUTES)= BEGIN REGISTER LEXEME LOP:ROP; BIND LEXEME NODESW=NODE; MAP GTVEC NODE; IF NOT ARBITRARYR THEN RETURN 0; LOP_.NODE[OPR1]; ROP_.NODE[OPR2]; IF .COMMUTES THEN IF (.LOP[LTYPF] EQL LITTYP) THEN IF (.ROP[LTYPF] EQL GTTYP) THEN SWAPOP; IF (.LOP[LTYPF] NEQ GTTYP) OR (.ROP[LTYPF] NEQ LITTYP) THEN RETURN 0; 1 END; ROUTINE COMPLICATED(NODE,SAFE)= BEGIN MAP GTVEC NODE; MAP LEXEME SAFE; BIND LEXEME NODESW=NODE; LOCAL LEXEME UOP; BIND GTVEC UOPST=UOP; BIND COMPPLIT=PLIT(0,1,2,3,10,10,3,4); MACRO ISNOTCOMPLICATED=IF .NODESW[LTYPF] EQL LITTYP THEN IF LITVALUE(.NODE) EQL 0 THEN 0 ELSE 2 ELSE .COMPPLIT[.NODE[MODE]]$, MAYBECOMPLICATED=IF (.NODE[NODEX] LEQ MAXOPERATOR) AND (.NODE[NSSPF] LEQ PF016) THEN .COMPPLIT[.NODE[MODE]] ELSE ISCOMPLICATED$; BIND ISCOMPLICATED=10; IF .NODESW[SSPF] GTR PF016 THEN RETURN ISCOMPLICATED; IF .NODESW[LTYPF] EQL LITTYP THEN IF LEFTSIDER THEN RETURN ISCOMPLICATED; IF .NODESW[LTYPF] NEQ GTTYP THEN RETURN ISNOTCOMPLICATED; IF ISNCSE(NODE) THEN RETURN COMPLICATED(.NODESW[KFIELDS]^REQUESTPOS + LEXOUT(BNDVAR,.ST[.NODE[REGF],OFFSETF]),.SAFE); UOP_.NODE[OPR1]; IF .NODE[NODEX] NEQ SDOTOP THEN MAYBECOMPLICATED ELSE IF .UOP[LTYPF] NEQ GTTYP THEN ISNOTCOMPLICATED ELSE IF LEFTSIDER THEN MAYBECOMPLICATED ELSE IF .UOPST[NODEX] EQL SDOTOP THEN BEGIN UOP_.UOPST[OPR1]; IF .UOP[LTYPF] EQL GTTYP THEN ISCOMPLICATED ELSE IF .UOP[LEXPART] EQL .SAFE[LEXPART] THEN ISCOMPLICATED ELSE ISNOTCOMPLICATED END ELSE MAYBECOMPLICATED END; ROUTINE COPYAROUND(NODE,DNODE)= BEGIN MAP GTVEC NODE:DNODE; BIND LEXEME NODESW=NODE, LEXEME DNODESW=DNODE; LOCAL GTVEC I; BIND LEXEME ISW=I; IF NOT .NODE[DELAYED] THEN BEGIN DNODE[DELAYED]_NODE[DELAYED]_1; IF ISCSECREATION(NODE) THEN BEGIN NODE[CORCSEF]_1; NODE[NIDTF]_0; NODE_.NODE[CSPARENT]; I_.NODE[CSTHREAD]; UNTIL .I EQL 0 DO (IF NOT .I[MUSTGENCODE] THEN (I[STATE]_0;I[DELAYBITS]_0; COPYRESULT(.I,.DNODE[NRWORDF]^RESULTPOS+.DNODESW[LEXPART]); I[CORCSEF]_0; I[DELAYED]_1);I[ADDCOPIED]_.DNODE[ADDCOPIED]; I_.I[CSTHREAD]); END; END; END; COMMENT ! COPYRESULT ! ! FUNCTION: SEE MACRO 'SETRESULT' ! ROUTINE COPYRESULT(XNODE,XOP)= BEGIN REGISTER LEXEME SWRD, STVEC NODE; MAP LEXEME XOP; BIND STVEC XOPST=XOP; NODE_.XNODE; IF ISLITLEX(XOP) THEN RETURN SETRESULTLIT(LITVALUE(.XOP)); IF ISSYM(XOP) THEN (O(.XOP); NODE[SYMOFFF]_1) ELSE IF .XOPST[MODE] NEQ DEFERRED THEN (O(.XOPST[OFFSETF]); NODE[SYMOFFF]_.XOPST[SYMOFFF]); IF ISSYM(XOP) THEN SWRD_.XOP ELSE SWRD_.XOPST[STATE]; SWRD[KNOTF]_.NODE[NKNOTF] XOR .SWRD[KNOTF]; SWRD[KNEGF]_.NODE[NKNEGF] XOR .SWRD[KNEGF]; SWRD[SRFF]_.NODE[NSRFF]; SWRD[IDTF]_.SWRD[IDTF] AND .NODE[NIDTF]; NODE[STATE]_.SWRD; NODE[COPIED]_1; NODE[COMPLEXITY]_IF ISSYM(XOP) THEN 0 ELSE .XOPST[COMPLEXITY]; NODE[CORCSEF]_.XOPST[CORCSEF] OR ISCSECREATION(NODE); P(.XOPST[POSF],.XOPST[SIZEF]); R(.XOPST[REGF]); M(.XOPST[MODE]); END; ! DECLARATIONS AND SUPPORT ROUTINES FOR GENERATING ! LOADS FOR NAMES USED AS CSE'S. REQUIRE NCSE.RTN; EXTERNAL GETLCNT, ! GETLOAD COUNT -- 0 IF NCSE USES MAY BE GENERATED INENABLE; ! 'IN ENABLE' COUNT -- 0 IF NCSE CREATIONS MAY BE GENERATED BIND CHIREMOVE=0, FLSREMOVE=3, FLSENTER=XSORTENTER; MACRO ! FIELD DEFINITIONS FOR NCSE LIST ENTRIES BASE=0,0,0,18$, RLINK=1,0,0,18$, LLINK=1,0,18,18$, DATA1=1,1,0,35$, ! POINTER TO NODE CREATED BY GETLOAD ISCSP=1,1,35,1$, ! TRUE IF THIS LIST ENTRY CREATED BY GETLOAD, ! FALSE IF BY GETFAKE LST1=1,2,18,18$, ! POINTER TO ALPHA (CHI) LIST OF OUTERMOST FORK (LOOP) ! THAT NAME OCCURS ON LST2=1,2,0,18$, ! POINTER TO ALPHA (CHI) LIST THAT NAME MUST BE PUT ON REMOVE=1,1,18,18$; COMMENT ! FLSINSERT ! ! FUNCTION: ! ADDS AN ENTRY TO THE CURRENT NCSE LIST (THE ONE FOR THE ! PARTICULAR FORK-BRANCH/LOOP-BODY WE ARE IN). 'TOG' IS THE ! ISCSP BIT. ! MACRO FLSINSERT(NODE,TOG)=ENLST(.FLSTK,MAKITEM(NODE OR TOG^35,0,2))$; COMMENT ! MERGE ! ! FUNCTION: ! MERGE TWO NCSE LISTS ('NAMES1' AND 'NAMES2'; THE RESULTING LIST ! WILL BE 'NAMES1'). WHEN MERGING LISTS FROM TWO BRANCHES OF THE ! SAME FORK, 'ALPHLST' WILL BE A POINTER TO THE APPROPRIATE ALPHA ! LIST; THEN, IF ANY ENTRY ON 'NAMES2' DUPLICATES AN ENTRY ON ! 'NAMES1' AND THE LATTER WAS CREATED BY 'GETLOAD', THAT NAME-CSE ! WILL BE FORCED ONTO THE ALPHA LIST. ! ROUTINE MERGE(NAMES1,NAMES2,ALPHLST)= BEGIN MAP LSTHDR NAMES1:NAMES2:ALPHLST; REGISTER ITEM I:J:K; K_.NAMES2[BASE]; UNTIL (J_.K[RLINK]) EQL .K DO BEGIN LOCAL DATA; IF .ALPHLST EQL 0 THEN EXITBLOCK ENLST(.NAMES1,.J); DATA_.J[DATA1]; I_.NAMES1[BASE]; UNTIL (I_.I[RLINK]) EQL .NAMES1[BASE] DO BEGIN IF .DATA GTR .I[DATA1] THEN EXITLOOP; IF .DATA EQL .I[DATA1] THEN BEGIN IF .I[ISCSP] THEN (I[LST1]_0; I[LST2]_.ALPHLST); RELITEM(.J,3); EXITBLOCK END END; LINK(DELINK(.J),.I[LLINK]) END END; COMMENT ! MARKLSTNAMES ! ! FUNCTION: ! UPDATE THE LST1 FIELDS OF ALL NCSE LIST ENTRIES CREATED BY GETLOAD ! WITHIN A FORK OR LOOP CONSTRUCT. 'NAMELST' IS THE LIST OF SAID ! NCSE LIST ENTRIES, AND 'LST' IS THE APPROPRIATE ALPHA OR CHI LIST. ! ROUTINE MARKLSTNAMES(NAMELST,LST)= BEGIN MAP LSTHDR NAMELST; LOCAL ITEM I; I_.NAMELST[BASE]; UNTIL (I_.I[RLINK]) EQL .NAMELST[BASE] DO IF .I[ISCSP] THEN I[LST1]_.LST END; MACRO NOGETFAKE=INENABLE_.INENABLE+1$, OKGETFAKE=INENABLE_.INENABLE-1$; COMMENT ! GETFAKE ! ! CREATE AN NCSE USE. ! SWITCHES EXPAND; ROUTINE GETFAKE(N)= BEGIN MAP GTVEC N; LOCAL GTVEC NODE; NODE_FASTLEXOUT(GTTYP,GETSPACE(GT,BASEGTNODESIZE)); MOVECORE(.N,.NODE,BASEGTNODESIZE); NODE[NODEX]_SYNNULL; NODE[NODESIZEF]_0; NODE[CSPARENT]_.N; NODE[CSTHREAD]_.N[CSTHREAD]; N[CSTHREAD]_.NODE; N[OCCF]_.N[OCCF]+1; FLSINSERT(.N,0); RSTATE END; SWITCHES NOEXPAND; MACRO NOGETLOAD=GETLCNT_.GETLCNT+1$, OKGETLOAD=GETLCNT_.GETLCNT-1$; COMMENT ! GETLOAD ! ! CREATE AN NCSE PARENT. ALSO, GIVE IT A TEMP NAME ! AND MARK THE TN 'REGISTER OR FORGET IT'. ! ROUTINE GETLOAD(N,L)= BEGIN MAP GTVEC N; LOCAL GTVEC NODE:T; NODE_XLOADNODE(.N OR IMMK); NODE[CSCOMPL]_1; T_NODE[REGF]_GETTN(); T[REQD]_RFREQDB; T[BNDTYP]_BNDNCSE; T[OFFSETF]_.N; NODE[MODE]_INDEXED; NODE[CORCSEF]_1; NODE[NIDTF]_0; NODE[SIZEF]_.N[SIZEF]; NODE[GTLDF]_-1; RCMT; NCSE[.L,NCGT]_.NODE; FLSINSERT(.NODE,1); RSTATE END; REQUIRE CSWO.RTN; DELAYR(DADD) LOCAL WCSE,CODET, LTYPE, RTYPE, AWORD CXB, SUBTRACT, LEXEME SUM; BIND STVEC SUMST=SUM; MACRO CODECASES= (DETCXB; IF .CXB[CXOPF] THEN NODE[NODEX]_SMINOP; IF .CXB[CXMOVNF] THEN RCNT; IF .CXB[CXTPATHF] THEN (SWAPALL; IF SWPR THEN NODESW[NOPTMF]_NSWP); IF .CXB[CXKNEGF] THEN NODE[NKNEGF]_1; RCMT; IF .NODE[NKNEGF] THEN (IF ISPOS(SUM) THEN IF .NODE[SYMOFFF] THEN RCS ELSE NEGATEOFFSET) ELSE IF NOT ISPOS(SUM) THEN RCS; IF NOT .NODE[RCSF] AND .NODE[OFFSETF] NEQ 0 THEN M(INDEXED))$, CXTPATHS=3$, CXTPATHF=3,1$, CXOPF=2,1$, CXKNEGF=1,1$, CXMOVNF=0,1$, C4(A,B,C,D)=(((D^8+C)^8+B)^8+A)$, C5(A,B,C,D,E)=(((((A AND 3)^1+(B AND 1))^1+(C AND 1))^1+(D AND 1))^1+(E AND 1))$, DELAYCASES= BEGIN NODE[CXBITS]_0; IF ISLIT(ROP) THEN IF LITVALUE(.ROP) EQL 0 THEN EXITCOMPOUND (SETRESULT(LOP); NODE[NIMMF]_0; NODE[ADDCOPIED]_1); IF .RTYPE EQL ADL THEN CASE .LTYPE OF SET % L +- L % (M(ABSOLUTE); LITRESULT); % +-NR + L % IF .SUM[KNEGF] AND MPOSNPR THEN (RCMO; RCNT) ELSE (M(ABSOLUTE); SETRES(.SUM)); % +-.T + L % (M(INDEXED); IF TNOTINDEX THEN RCMT; IF NOT ISPOS(LOP) THEN (IF NOT MPOSNPR THEN (KNEG; NEGATEOFFSET) ELSE (IF OPERNDR AND NOT NSWPR THEN (RCOPT; M(GENREG); XTPATH; RCMO; NODE[NODEX]_SMINOP) ELSE (RCMT; RCNT)))); %+-(.T+L) + L % (M(INDEXED); IF NOT ISPOS(LOP) THEN IF MPOSNPR THEN (RCMT; RCNT) ELSE (KNEG; NEGATEOFFSET)); % +-NT + L % (M(INDEXED); IF NOT ISPOS(SUM) THEN (IF MPOSNPR THEN (M(GENREG); RCMT; RCNT; RCS) ELSE (RCMT; (KNEG; NEGATEOFFSET)))); % +-(.T+NR) + L % (M(INDEXED); IF NOT ISPOS(SUM) THEN (IF MPOSNPR THEN (RCMT; RCNT; RCS; M(GENREG)) ELSE KNEG)) TES ELSE (M(INDEXED); IF ISPOS(ROP) THEN CASE .LTYPE-1 OF SET % +-NR + NR % (RCMT; IF NOT ISPOS(LOP) THEN RCNT); % +-.T + NR % (IF TNOTINDEX THEN RCMT; IF NOT ISPOS(LOP) THEN (RCMT; IF OPERNDR AND NOT NSWPR THEN (RCOPT; M(GENREG); XTPATH; NODE[NODEX]_SMINOP) ELSE RCNT)); % +-(.T+L) + NR % IF NOT ISPOS(LOP) THEN (RCMT; RCNT); % OTHER CASES REDELAYED % TES ELSE (CASE .LTYPE-1 OF SET % +-NR - NR % (IF .SUM NEQ 0 THEN SETRESULTLIT(.SUM) ELSE (RCMT; IF (MPOSNPR OR OPERNDR) THEN (IF NOT ISPOS(LOP) THEN RCNT; RCS; M(GENREG)) ELSE (IF ISPOS(LOP) THEN RCNT; KNEG))); % +-.T - NR % (IF TNOTINDEX THEN RCMT; IF (MPOSNPR OR OPERNDR) THEN (RCMT; IF NOT ISPOS(LOP) THEN RCNT; RCS; M(GENREG)) ELSE (IF ISPOS(LOP) THEN (RCMT; RCNT); KNEG)); % +-(.T+L) - NR% (IF (MPOSNPR OR OPERNDR) THEN (RCMT; IF NOT ISPOS(LOP) THEN RCNT; RCS; M(GENREG)) ELSE (IF ISPOS(LOP) THEN (RCMT; RCNT); KNEG)); TES)) END$, DETAN(OP,WH)=CASE WH OF SET .OP; .OP; ZERO; LITLEXEME(.ID(OP)ST[OFFSETF]); .OP; LEXOUT(BNDVAR,.ID(OP)ST[OFFSETF]) TES$, DETCXB= BEGIN ! WOW !!! IT SURE DOESN'T TASTE LIKE TOMATO JUICE STRUCTURE V8[I]=(.V8+.I/4)<8*(.I MOD 4),8>; BIND V8 CAP=PLIT( C4( 0, 4,#14, 2), C4(#10,#16,#14,#12), C4( 0, 4, 6, 2), C4(0 , 4,#14, 2), C4( 0,#16, 6, 2), C4(#10,#16,#14,#12), C4( 0, 4, 6, 2), C4( 0,#16, 6, 2), C4( 0, 4,#14, 2), C4(#10,#16,#14,#12), C4( 0, 4, 6, 2), C4( 0, 4,#14, 2), C4( 0, 4,#14, 5), C4(#10,#11,#14,#15), C4( 0, 4, 1, 5), C4( 0, 4,#14, 5)); CXB_ .CAP[C5(.NODESW[NPKF],ISIDT(LOP),ISIDT(ROP) AND NOT NSWPR, .LOP[KNEGF],.ROP[KNEGF])]; END$, DETOFFSET= BEGIN LOCAL LEXEME LAN:RAN; LAN_DETAN(LOP,.LTYPE); RAN_DETAN(ROP,.RTYPE); LAN[KNEGF]_.LOP[KNEGF]; RAN[KNEGF]_.ROP[KNEGF]; IF (SUM_ADDAN(.LAN,.RAN)) EQL 0 THEN STOREAN(NODE,ROP) ELSE STOREAN(NODE,SUM) END$, PRELIMSWAP=(SWAPALL; NODESW[NOPTMF]_ IF NSWPR THEN SWP ELSE IF SWPR THEN NSWP ELSE DCSW)$, SPECIALCASES=IF ONEOF(.LTYPE,BIT2(ADNT,ADTNR)) AND ONEOF(.RTYPE,BIT3(ADNT,ADTNR,ADNR)) THEN (NODE[OPR1]_LOP_XLOADNODE(.LOP); LTYPE_ADT; IF .RTYPE GEQ ADNT THEN SWAPALL)$, SWAPALL=(SWAP(LOP,ROP);SWAP(LTYPE,RTYPE);SWAP(NODE[OPR1],NODE[OPR2]))$, TNOTINDEX=(IF .LOPST[MODE] NEQ GENREG OR .LOP[SSPF] GTR PF016 THEN 1 ELSE NOT .LOP[IDTF] AND (OPERNDR OR TEMPR))$; WCSE_CHECKCSE; IF .WCSE GTR 0 THEN CHECKOPNDCSE; IF .NODE[NODEX] EQL SMINOP THEN (NODE[NODEX]_SADDOP;SUBTRACT_TRUE) ELSE SUBTRACT_0; CODET_NORESULTCHECK; LDELAY(.CODET+MUNCOMPNK+ARBITRARYK+(IF NEGNPR THEN NEGNPK ELSE DCNPK)); RDELAY(.CODET+MUNCOMPNK+ARBITRARYK+(IF NEGNPR AND ISPOS(LOP) THEN NEGNPK ELSE DCNPK)); ROP[KNEGF]_.ROP[KNEGF] XOR .SUBTRACT; LTYPE_ADDCLASS(.LOP); RTYPE_ADDCLASS(.ROP); DEFAULTFIELDVALUES; NORESULTRET; % COMPLEX OPERAND ON THE LEFT--ALWAYS THE TARGET % IF .LTYPE LSS .RTYPE THEN PRELIMSWAP ELSE IF .LTYPE EQL .RTYPE THEN IF .LTYPE EQL ADT THEN IF .LOPST[MODE] NEQ GENREG THEN IF .ROPST[MODE] EQL GENREG THEN PRELIMSWAP; SPECIALCASES; DETOFFSET; IF .LTYPE EQL ADT THEN IF .RTYPE EQL ADL THEN IF MINUS2((.LOP[KNEGF] XOR .ROP[KNEGF]),ROP) THEN IF NOT TNOTINDEX THEN IF .LOP[IDTF] THEN (WCSE_0; FORCETEMP); IF .RTYPE LEQ ADNR THEN BEGIN IF .WCSE GTR 0 THEN (UNDOCSE(.NODE); IF .LOP[LTYPF] EQL GTTYP THEN LOP[IDTF]_.LOPST[NIDTF]); DELAYCASES END ELSE CODECASES; IF NOT .NODE[ADDCOPIED] THEN BEGIN IF .NODE[MODE] EQL INDEXED THEN IF .NODE[OFFSETF] EQL 0 THEN M(GENREG) ELSE IF TEMPR OR OPERNDR THEN (RCA; M(GENREG)); IF .NODE[MODE] EQL ABSOLUTE THEN IF TEMPR THEN (RCMO; M(GENREG)); END; IF SELECTEVALORDER(.NODE) THEN SWAPOP; IF SWPR THEN IF .NODE[NODEX] NEQ SMINOP THEN XTPATH; IF .NODE[TPATH] THEN LOP_.ROP; IF .NODE[RCMTF] THEN IF .LOP[IDTF] AND .LOP[IMMF] THEN NODE[RCMTF]_0; NODE[NIDTF]_(.NODE[MODE] EQL GENREG OR .NODE[MODE] EQL INDEXED) AND NOT ISCSE(NODE) AND (.NODE[RCMTF] OR ISIDT(LOP)); IF NOT .NODE[NIDTF] THEN IF (.NODE[RCAF] OR .NODE[RCSF]) THEN RCMT; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DANDOR) ROUTINE DAND(NODE,LOP,ROP)= BEGIN MAP STVEC NODE; BIND STATEWD NODESW=NODE; MAP LEXEME LOP:ROP; BIND STVEC LOPST=LOP:ROPST=ROP; LOCAL LEXEME X,Y; X_LITVALUE(.ROP); Y_1^.LOPST[SIZEF]-1; X_.X AND .Y; IF NOT REALVALR THEN IF NOT .X THEN RETURN (SETRESULTLIT(0);1) ELSE RETURN (SETRESULT(LOP);1) ELSE IF .X EQL 0 THEN RETURN (SETRESULTLIT(0);1) ELSE IF .X EQL .Y THEN RETURN (SETRESULT(LOP);1); 0 END; ROUTINE DOR(NODE,LOP,ROP)= BEGIN MAP STVEC NODE; BIND STATEWD NODESW=NODE; MAP LEXEME LOP:ROP; BIND STVEC LOPST=LOP:ROPST=ROP; LOCAL LEXEME X,Y; X_LITVALUE(.ROP); Y_1^.LOPST[SIZEF]-1; IF NOT REALVALR THEN IF NOT .X THEN RETURN (SETRESULT(LOP);1) ELSE RETURN (SETRESULTLIT(1);1) ELSE IF .X EQL (.X OR .Y) THEN RETURN (SETRESULTLIT(.X);1) ELSE IF .X EQL 0 THEN RETURN(SETRESULT(LOP);1); 0 END; LOCAL CODET,AOT,NLT,SWAPPED; IF CHECKCSE GTR 0 THEN UNDOCSE(.NODE); CODET_.NODESW[CTKF]^CTKFPOS; AOT_.NODE[NODEX] EQL SOROP; LDELAY(.CODET+DCNK+MPOSNPK+OPERNDK); IF FLOWVALR OR NORESULTR THEN NOGETLOAD; RDELAY(.CODET+DCNK+MPOSNPK+OPERNDK); IF FLOWVALR OR NORESULTR THEN OKGETLOAD; DEFAULTFIELDVALUES; IF NOT REALVALR THEN SRF(RFFLOW); NORESULTRET; RCMT; SWAPPED_FALSE; IF ISLIT(LOP) AND NOT ISLIT(ROP) THEN (SWAPPED_TRUE; SWAPOP); WHICH_.LOP[SLF]+.ROP[SLF]; DKAYCE SET ! X AND X 0; ! X AND L BEGIN IF .LOPST[NODEX] EQL .NODE[NODEX] AND NOT .LOPST[COPIED] THEN BEGIN ! CHANGE, E.G., "EXPR AND 3 AND 4" TO "EXPR AND 7". LOCAL X,Y,LEXEME LEX; LEX_.LOPST[OPR2]; IF NOT ISLIT(LEX) THEN EXITBLOCK; X_CLITVALUE(ROP); Y_CLITVALUE(LEX); Y_IF .AOT THEN .X OR .Y ELSE .X AND .Y; COPYRESULT(.LOPST,.LOPST[OPR1]); LOPST[NSRFF]_RFNONE; LOPST_NODE[OPR1]_STATEMAKE(.LOPST); X_.CODET+DCNK+MPOSNPK+OPERNDK; LEX_DLIT(.X+LEXOUT(LITTYP,.Y)); ROP_.NODE[OPR2]; IF .ROP[LTYPF] EQL GTTYP THEN (ROPST[OFFSETF]_.Y; ROPST[NRWORDF]_.LEX[RWORDF]; ROPST[NSRFF]_RFNONE) ELSE NODE[OPR2]_.LEX; ROP_.LEX END; IF (IF .AOT THEN DOR ELSE DAND)(.NODE,.LOP,.ROP) THEN (SRF(RFNONE); NODE[TPATH]_0; RETURN SETLCONF(MUNCOMPNR,.NODE[NKNOTF],MAKESTATE)); END; ! L AND L (SETRESULTLIT(LITVALUE(IF .AOT THEN .LOP OR .ROP ELSE .LOP AND .ROP)); SRF(RFNONE); NODE[TPATH]_0; RSTATE); TES; IF FLOWVALR THEN IF NOT ISLIT(LOP) THEN IF ISLIT(ROP) THEN ROP_NODE[OPR2]_XLOADNODE(.ROP); IF .SWAPPED THEN SWAPOP; IF SELECTEVALORDER(.NODE) THEN SWAPOP; IF DCSWR THEN NODE[TPATH]_0 ELSE IF SWPR THEN XTPATH; IF NOT .AOT THEN IF DCSWR THEN IF .LOP[KNOTF] XOR .ROP[KNOTF] THEN NODE[TPATH]_(IF .ROP[KNOTF] THEN 0 ELSE 1); SETIDTOP; RETURN SETLCONF(MUNCOMPNR,.NODE[NKNOTF],MAKESTATE) END; DELAYR(DCALL) LOCAL STVEC LNKG, L; LNKG_.NODE[OPR1]; SELECT .LNKG[LNKGTF] OF NSET SPECLNKGT: EXITSELECT; IHBLISLNKGT: L_OPERNDK; OTHERWISE: L_ADDRESSK; HBLISLNKGT: (NOGETLOAD; NOGETFAKE); ALWAYS: RDELAY(.L+REALVALK+MUNCOMPNK+MPOSNPK); HBLISLNKGT: (OKGETLOAD; OKGETFAKE) TESN; INCR I FROM 2 TO .NODE[NODESIZEF]-1 DO DLY(UOP,OPERAND(.I),REALVALK+MUNCOMPNK+MPOSNPK+OPERNDK); SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); NODE[RUCOMPL]_16; RSTATE END; DELAYR(DCASE) MACRO ALPHAPART=OPR1$, ! CHANGE WHEN CG FIXES OMEGAPART=OPERAND(.NODE[NODESIZEF]-1)$, ! XCHOICEPART=XOPR2$, CHOICEPART=OPR2$; LOCAL SAVFLS,FLSTK1,CODET,CODEN; CODET_.NODESW[CTKF]^CTKFPOS; IF NOT EMPTY(.NODE[OMEGAPART]) THEN CODET_NORESULTCHECK; IF .CODET NEQ REALVALK THEN CODEN_DCNK ELSE CODEN_MUNCOMPNK; PULSE(ALPHAPART); NOGETLOAD; PULSE(OMEGAPART); OKGETLOAD; DLY(UOP,CHOICEPART,OPERNDK+REALVALK+MPOSNPK+MUNCOMPNK); IF NOT ISIDT(UOP) THEN UOP_NODE[CHOICEPART]_XLOADNODE(.UOP); SAVFLS_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); FLSTK1_MAKHDR(FLSREMOVE,FLSENTER); INCR I FROM 2 TO .NODE[NODESIZEF]-2 DO (DLY(UOP,OPERAND(.I), OPERNDK+.CODET+.CODEN+MPOSNPK); MERGE(.FLSTK1,.FLSTK,.NODE[ALPHAPART])); OLDFIXLIST(.NODE[ALPHAPART]); OLDFIXLIST(.NODE[OMEGAPART]); MARKLSTNAMES(.FLSTK1,.NODE[ALPHAPART]); MERGE(.SAVFLS,.FLSTK1,0); RELITEM(.FLSTK,2);RELITEM(.FLSTK1,2); FLSTK_.SAVFLS; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; IF .CODET NEQ REALVALK THEN SRF(RFFLOW); SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DCOMP) MACRO COMPVAL=NODE[OPERAND(.NODE[NODESIZEF]-1)]$; INCR I TO .NODE[NODESIZEF]-2 DO DLY(UOP,OPERAND(.I),MUNCOMPNK+MPOSNPK+NORESULTK+ARBITRARYK); DLY(UOP,OPERAND(.NODE[NODESIZEF]-1),.NODESW[KFIELDS]^REQUESTPOS); ! NOTE: LAST OPERAND IS A COUNT FIELD IF ISSYM(UOP) THEN UOP_COMPVAL_XLOADNODE(.UOP); DEFAULTFIELDVALUES; NORESULTRET; SETRESULT(UOP); SETCONTROL; NODE[NIDTF]_.UOP[IDTF]; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DDO) MACRO CHIPART=OPERAND(1)$, RHOPART=OPERAND(0)$; LOCAL SAVFLS; RHOPULSE(PULSEDELAY,.NODE[RHOPART]); PULSE(CHIPART); SAVFLS_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); DLY(LOP,OPR3,ARBITRARYK+NORESULTK+MPOSNPK+MUNCOMPNK); LOP_FIXCOND(NODE[OPR3]); DLY(ROP,OPR4,OPERNDK+FLOWVALK+DCNPK+DCNK); MARKLSTNAMES(.FLSTK,.NODE[CHIPART]); MERGE(.SAVFLS,.FLSTK,0); RELITEM(.FLSTK,2); FLSTK_.SAVFLS; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DDOT) LOCAL GTVEC PNODE; NODE_PCSEDOT(.NODE); UDELAY(NORESULTCHECK+ADDRESSK+MPOSNPK+MUNCOMPNK); DEFAULTFIELDVALUES; IF .UOP[LTYPF] EQL GTTYP THEN ! IF .UOPST[MODE] EQL INDEXED ! NODE IS OF THE FORM .(A + #N) AND .UOPST[REGF] EQL 0 THEN ! IF .GT[.GT[.UOPST[CSPARENT],OPR1],MODE] EQL GENREG ! "A" IS GENREG THEN (PNODE_.NODE; DO PNODE[CHPDFR]_1 WHILE (PNODE_.PNODE[CSTHREAD]) NEQ 0); NODE[RCOPTF]_0; ! DOT NEVER GENERATES CODE NORESULTRET; SETRESULT(UOP); NODE[NSLF]_0; NODE[NIMMF]_0; NODE[CORCSEF]_.NODE[CORCSEF] OR ISCSECREATION(NODE); NODE[NIDTF]_ IF .UOP[SSPF] GTR PF016 THEN 0 ELSE .UOP[IDTF] AND NOT ISCSE(NODE); NODE[CSCOMPL]_IF ISCSEUSE(NODE) THEN 0 ELSE IF .UOP[LTYPF] EQL GTTYP THEN .UOPST[CSCOMPL] ELSE OPCOMPL(.NODE); IF TEMPR THEN BEGIN NODE_LOADNODE(.NODE); IF (IF .UOP[LTYPF] EQL BNDVAR THEN ISSTVAR(UOP) ELSE IF .UOP[LTYPF] EQL GTTYP THEN BEGIN PNODE_.UOPST[CSPARENT]; IF .PNODE[NODEX] EQL SPLUSOP THEN BEGIN LOCAL LEXEME OPR1LEX; OPR1LEX_.PNODE[OPR1]; IF .OPR1LEX[LTYPF] EQL BNDVAR THEN ISSTVAR(OPR1LEX) END END) THEN BEGIN LOCAL GTVEC TN; TN_NODE[REGF]_GETTN(); TN[REQD]_RFREQDB; TN[OFFSETF]_.UOP[ADDRF] END; END; RSTATE END; COMMENT ! DELAY ! ! FUNCTION: ! MAIN COMMON ROUTINE THROUGH WHICH ALL DELAYING IS DONE. ! PERFORMS FUNCTIONS COMMON TO DELAYING OF ALL TYPES OF NODES, ! AND PROVIDES FOR CENTRAL DISPATCHING TO ALL OF THE NODE- ! SPECIFIC DELAYERS. A NODE-SPECIFIC DELAYER IN TURN CALLS ! THIS ROUTINE TO DELAY SUBNODES AND GET THE RESULT WORDS. ! THE WHOLE RECURSIVE DELAYING PROCESS IS KICKED OFF BY ! ROUTINE 'DELAYDRIVER' WHICH CALLS DELAY ON THE TOP NODE ! OF THE GRAPH TABLE TREE. ! GLOBAL DELAYR(DELAY) MACRO CLEARDELAYBITS=(BIND D=.NODE[DONTUNLINK]; NODE[DELAYBITS]_0; NODE[DONTUNLINK]_D)$; BIND XXXX=0; LOCAL GTVEC DNODE:SAVNODE; BIND LEXEME DNODESW=DNODE; BIND OPDPLIT=PLIT( DADD, !ADD DSWAB, !SWAB DMULDIVMOD,!DIV DDOT, !DOT DADD, !SUB DMULDIVMOD,!MOD DMULDIVMOD,!MUL DNEG, !NEG DPLUS, !PLUS DROTSHIFT,!SHIFT 0, !BIT DREL, !GTR DREL, !LEQ DREL, !LSS DREL, !GEQ DREL, !EQL DREL, !NEQ DNOT, !NOT DEQVXOR,!EQV DANDOR, !AND DANDOR, !OR DEQVXOR,!XOR 0, !FADR 0, !FDVR 0, !FIX 0, !FLOAT 0, !FMPR 0, !FNEG 0, !FSBR DREL, !GTRU DREL, !LEQU DREL, !LSSU DREL, !GEQU DREL, !EQLU DREL, !NEQU DROTSHIFT,!ROT DMAXMIN,!MAX DMAXMIN,!MIN PUNT, !CARRY PUNT, !OVERFLOW DSTORE, !STORE 0, !ERROR DCASE, !CASE DFTYPE, !FAKE-PARM DFTYPE, !FAKE-STORE DWU, !WHILE-DO DWU, !UNTIL-DO DROUT, !DECLARE-ROUTINE DCOMP, !COMPOUND DINCR, !INCR DINCR, !DECR DIF, !IF DDO, !DO-WHILE DDO, !DO-UNTIL 0, !CREATE 0, !EXCHJ DSELECT,!SELECT DLEAVE, !EXITLOOP DLABEL, !LABEL 0, !MODULE 0, !PLIT DCALL, !PARAMETER-LIST DPOINTER, !POINTER 0, !SQUARE-BRACKET DLEAVE, !LEAVE DLEAVE, !RETURN DNULL, !NULL DNULL, !INLINE DFTYPE, !ENABLE DFTYPE, !SIGNAL DFTYPE);!MFPI,ETC. IF .NODESW[LTYPF] EQL GTTYP THEN BEGIN LOCAL DTYPE,NODX; DNODE_.NODE; IF .NODE[DELAYED] THEN ! ! IF A NODE HAS ALREADY BEEN DELAYED AT THIS POINT, ! THEN IT'S A CSE USE OF SOME SORT. DEPENDING ON THE ! REQUEST WORD FIELD VALUES, CERTAIN DECISIONS THAT ! WERE MADE FOR ITS PARENT NODE AND PASSED AROUND ! TO THE USES (BY ROUTINE 'COPYAROUND') MAY HAVE TO ! BE "TAKEN BACK" FOR THIS PARTICULAR USE. ! BEGIN DNODE_MAKESTATE; !!! NODE[LISTBIT]_1; IF TEMPR THEN IF .NODE[MODE] NEQ GENREG THEN DNODE_ XLOADNODE(.DNODE); IF ADDRESSR THEN DNODE_DEFERIT(.DNODE) ELSE IF ADDORSUB(.NODE[CSPARENT]) THEN IF NOT .DNODE[ADDCOPIED] THEN DNODE[NIMMF]_1; IF OPERNDR THEN IF NOT ONEOF(ADDCLASS(.DNODE),BIT2(ADL,ADT)) THEN DNODE_ XLOADNODE(.DNODE); IF FLOWVALR THEN SRF(.NODE[NSRFF] OR RFFLOW) ELSE IF REALVALR THEN SRF(.NODE[NSRFF] OR RFREAL); RETURN (.DNODE[NRWORDF]^RESULTPOS+LEXOUT(GTTYP,.DNODE)) END; IF ISCSEUSE(NODE) ! SUBNODE OF A LIST NODE THEN (SAVNODE_.NODE; NODESW[ADDRF]_.NODE[CSPARENT]; IF .NODE[BOGUSBIT] THEN NONBOGUS(NODE)) ELSE SAVNODE_0; NODX_.NODE[NODEX]; CASE (DTYPE_.NODESW[CKF]) OF SET %0% 0; ! ARBITRARY %1% 0; ! OPERAND %2% IF .NODX NEQ SDOTOP THEN IF .NODX NEQ SYNPOI THEN NODESW[CKF]_ARBITRARY; %3% IF .NODX NEQ SDOTOP THEN IF .NODX NEQ SYNPOI THEN NODESW[CKF]_ARBITRARY ELSE DTYPE_-1 ELSE DTYPE_-1 TES; !!! NODE[LISTBIT]_0; RELFLOW(.NODE); CLEARDELAYBITS; DNODE_(.OPDPLIT[.NODX])(.NODE); IF .DTYPE NEQ ADDRESS THEN IF (.NODX EQL SADDOP) OR (.NODX EQL SMINOP) THEN IF NOT .NODE[ADDCOPIED] THEN DNODE[NIMMF]_1; IF .DTYPE EQL TEMP THEN DNODE_LOADNODE(.DNODE); COPYAROUND(.NODE,.DNODE); IF .DTYPE EQL ADDRESS THEN DNODE_DEFERIT(.DNODE); IF .SAVNODE EQL 0 THEN SAVNODE_.DNODE ELSE (SAVNODE[NSRFF]_.NODE[NSRFF]; NODESW[ADDRF]_.SAVNODE; NODX_-1); IF FLOWVALR THEN SRF(.NODE[NSRFF] OR RFFLOW); IF .NODX LSS 0 AND ONEUSE(NODE) THEN RETURN DELAY(.SAVNODE) ELSE RETURN (.DNODE[NRWORDF]^RESULTPOS+LEXOUT(GTTYP,.SAVNODE)); END ELSE IF .NODESW[LTYPF] EQL BNDVAR THEN (DNODE_DSYM(.NODE); IF .DNODESW[LTYPF] EQL GTTYP THEN IF FLOWVALR THEN DNODE[NSRFF]_RFBOTH; .DNODE) ELSE IF .NODESW[LTYPF] EQL LITTYP THEN DLIT(.NODE) ELSE PUNT(ERINVLEXT) END; DELAYR(DEFERIT) MACRO CANNOTDEFER=((.NODESW[SSPF] GTR PF016))$; IF .NODE[NODEX] EQL SYNPOI THEN RETURN .NODE; IF CANNOTDEFER THEN (NODE_LOADNODE(.NODE);M(1);RETURN .NODE); IF ADDORSUB(.NODE[CSPARENT]) THEN IF .NODE[MODE] EQL INDEXED THEN IF NOT .NODE[ADDCOPIED] THEN RETURN(NODE[NIMMF]_0; .NODE) ELSE (UOP_.NODE[OPR1]; IF .UOP[LTYPF] EQL GTTYP THEN IF .UOPST[NODEX] EQL SDOTOP THEN (UOP_.UOPST[OPR1]; IF .UOP[LTYPF] NEQ BNDVAR THEN RETURN .NODE) ELSE RETURN .NODE ELSE RETURN .NODE); CASE .NODE[MODE] OF SET M(1); M(7); M(3); IF NOT .NODE[ADDCOPIED] THEN IF NOT .PICSW THEN M(7) ELSE (NODE_LOADNODE(.NODE);M(1)); PUNT(490); PUNT(490); M(7); (NODE_LOADNODE(.NODE); M(1)) TES; .NODE END; DELAYR(DEQVXOR) LDELAY(NORESULTCHECK+OPERNDK+MPOSNPK+DCNK); RDELAY(NORESULTCHECK+OPERNDK+MPOSNPK+DCNK); DEFAULTFIELDVALUES; IF NOT REALVALR THEN SRF(RFFLOW); NORESULTRET; RCMT; IF SELECTEVALORDER(.NODE) THEN SWAPOP; NODE[TPATH]_0; IF .LOP[KNOTF] XOR .ROP[KNOTF] THEN NODE[NODEX]_OTHEROP(SEQVOP,SXOROP); OFFNOT(NODE[OPR1]);OFFNOT(NODE[OPR2]); CASE .LOP[SLF]+.ROP[SLF] OF SET ! A A 0; ! A L BEGIN LOCAL X,Y; X_Y_0; IF FLOWVALR THEN (Y_1;X_(LITVALUE(.ROP) EQV (.NODE[NODEX] EQL SXOROP))) ELSE IF Y_(LITVALUE(.ROP) EQL 0) THEN X_.NODE[NODEX] EQL SEQVOP ELSE IF Y_(EXTEND(LITVALUE(.ROP)) EQL -1) THEN X_.NODE[NODEX] EQL SXOROP; IF .Y THEN BEGIN SRF(RFNONE); SETRESULT(LOP); IF .X THEN KNOT; RETURN SETLCONF(MUNCOMPNR,.NODE[NKNOTF],MAKESTATE) END; END; ! L L BEGIN SRF(RFNONE); SETRESULTLIT(IF .NODE[NODEX] EQL SEQVOP THEN LITVALUE(.LOP) EQV LITVALUE(.ROP) ELSE LITVALUE(.LOP) XOR LITVALUE(.ROP)); RSTATE END; TES; IF COMPNR THEN BEGIN KNOT; NODE[NODEX]_OTHEROP(SEQVOP,SXOROP); END; SETIDTOP; RSTATE END; DELAYR(DFTYPE) LOCAL CODET,CODEK; CODET_NORESULTCHECK; CODEK_OPERNDK; SELECT .NODE[NODEX] OF NSET SYNENABLE: (NOGETLOAD; NOGETFAKE); SFPARM: CODET_REALVALK; SYNSIGNAL: CODET_REALVALK; SYNMOVP: (CODET_REALVALK; CODEK_ADDRESSK); ALWAYS: UDELAY(.CODET+.CODEK+MUNCOMPNK+MPOSNPK); SYNENABLE: (OKGETLOAD; OKGETFAKE) TESN; SETCONTROL; DEFAULTFIELDVALUES; IF .NODE[NODEX] NEQ SFPARM THEN NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); NODE[RUCOMPL]_16; RSTATE END; DELAYR(DIF) MACRO OMEGAPART=OPERAND(4)$, ALPHAPART=OPERAND(0)$; ! WHEN CG FIXES => 0 LOCAL SAVFLS,FLSTK1,CODET,CODEN; PULSE(ALPHAPART); NOGETLOAD; PULSE(OMEGAPART); OKGETLOAD; DLY(UOP,OPR2,OPERNDK+FLOWVALK+DCNPK+DCNK); SAVFLS_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); CODET_.NODESW[CTKF]^CTKFPOS; IF NOT EMPTY(.NODE[OMEGAPART]) THEN CODET_NORESULTCHECK; IF .CODET NEQ REALVALK THEN CODEN_DCNK ELSE CODEN_MUNCOMPNK; DLY(LOP,OPR3,OPERNDK+.CODET+MPOSNPK+.CODEN); FLSTK1_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); DLY(ROP,OPR4,OPERNDK+.CODET+MPOSNPK+.CODEN); LOP_FIXCOND(NODE[OPR3]); ROP_FIXCOND(NODE[OPR4]); OLDFIXLIST(.NODE[ALPHAPART]); OLDFIXLIST(.NODE[OMEGAPART]); MERGE(.FLSTK1,.FLSTK,.NODE[ALPHAPART]); MARKLSTNAMES(.FLSTK1,.NODE[ALPHAPART]); MERGE(.SAVFLS,.FLSTK1,0); RELITEM(.FLSTK,2);RELITEM(.FLSTK1,2); FLSTK_.SAVFLS; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; IF .CODET NEQ REALVALK THEN SRF(RFFLOW); SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DINCR) MACRO RHOPART=OPERAND(4)$, CHIPART=OPERAND(5)$; LOCAL SAVFLS; RDELAY(OPERNDK+REALVALK+MUNCOMPNK+MPOSNPK); ! NOTE: OPERNDR/TEMPR FOR NEXT LINE SET IN FLOWAN INCR I FROM 2 TO 3 DO DLY(UOP,OPERAND(.I), (.NODE[OPERAND(.I)] AND TEMPK)+REALVALK+MPOSNPK+MUNCOMPNK); RHOPULSE(PULSEDELAY,.NODE[RHOPART]); PULSE(CHIPART); SAVFLS_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); DLY(UOP,OPERAND(6),ARBITRARYK+NORESULTK+MPOSNPK+MUNCOMPNK); UOP_FIXCOND(NODE[OPERAND(6)]); MARKLSTNAMES(.FLSTK,.NODE[CHIPART]); MERGE(.SAVFLS,.FLSTK,0); RELITEM(.FLSTK,2); FLSTK_.SAVFLS; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DLABEL) LOP_.NODE[OPR1]; ROP_.NODE[OPR2]; ROPST[STOPNCSEBIT]_0; IF NORESULTR THEN ROPST[ALIVEF]_0 ELSE ROPST[ALIVEF]_1; LDELAY((IF ADDRESSR AND (.LOP[LTYPF] EQL GTTYP) THEN ARBITRARYK ELSE .NODESW[CKF]^CKFPOS) +NORESULTCHECK +MPOSNPK+MUNCOMPNK); ! MAYBE WANT TO DELAY THE LABEL NODE TOO!!! IF .ROPST[STOPNCSEBIT] THEN OKGETLOAD; ! UNDO THE "NOGETLOAD" DONE AT ! A "LEAVE" TO LABEL. SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; IF NOT .ROPST[LEFTBIT] THEN SETRESULT(UOP); SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DLEAVE) LOCAL CODET; ROP_.NODE[OPR2]; NOGETLOAD; IF (IF .NODE[NODEX] EQL SYNEXIT THEN (NOT .ROPST[ALIVEF])) THEN CODET_NORESULTK ELSE CODET_REALVALK; UDELAY(.CODET+MUNCOMPNK+MPOSNPK+OPERNDK); IF (IF .NODE[NODEX] EQL SYNEXIT THEN (NOT .ROPST[STOPNCSEBIT])) THEN ROPST[STOPNCSEBIT]_1 ELSE OKGETLOAD; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DLIT) LOCAL LNODE, ABSVAL; ABSVAL_ABS EXTEND(LITVALUE(.NODE)); LNODE_(IF NOT ADDRESSR THEN IMMK)+ RFREALK+PFNONEK+LITK+.NODESW[LEXPART]+ (IF .ABSVAL LEQ 2 THEN (.ABSVAL+1)^LFZEROQ ELSE IF POF2(.ABSVAL) THEN LF2NK ELSE IF POF2(.ABSVAL+1) THEN LF2NM1K ELSE LFOTHERK); IF TEMPR THEN XLOADNODE(.LNODE) ELSE .LNODE END; DELAYR(DMAXMIN) MACRO USELEFTOPND=(SETRESULT(LOP);SRF(RFNONE); RETURN SETLCONF(MPOSNPR,.NODE[NKNEGF],MAKESTATE))$;; LDELAY(NORESULTCHECK+OPERNDK+DCNPK+MUNCOMPNK); RDELAY(NORESULTCHECK+OPERNDK+(IF .LOP[KNEGF] THEN NEGNPK ELSE DCNPK)+MUNCOMPNK); DEFAULTFIELDVALUES; NORESULTRET; IF SELECTEVALORDER(.NODE) THEN SWAPOP; IF DCSWR THEN NODE[TPATH]_0 ELSE IF SWPR THEN XTPATH; SETIDTOP; CASE .LOP[SLF]+.ROP[SLF] OF SET 0; ! BEGIN ! IF LITVALUE(.ROP) EQL 1^15 !(MOST NEGATIVE 16-BIT NUMBER) THEN IF .NODE[NODEX] EQL SMAXOP THEN USELEFTOPND ELSE (SETRESULTLIT(1^15);SRF(RFNONE);RSTATE); IF LITVALUE(.ROP) EQL 1^15-1 !(MOST POSITIVE 16-BIT NUMBER) THEN IF .NODE[NODEX] EQL SMINNOP THEN USELEFTOPND ELSE (SETRESULTLIT(1^15-1);SRF(RFNONE);RSTATE); IF .LOPST[NODEX] EQL OTHEROP(SMAXOP,SMINNOP) THEN BEGIN LOCAL X,Y,LEXEME LEX; LEX_.LOPST[OPR2]; IF NOT ISLIT(LEX) THEN EXITCASE; X_EXTEND(LITVALUE(.ROP)); Y_EXTEND(CLITVALUE(LEX)); IF IF .NODE[NODEX] EQL SMAXOP THEN .X GEQ .Y ELSE .Y GEQ .X THEN (SETRESULTLIT(.X);LOPST[NSRFF]_SRF(RFNONE);RSTATE) END END; BEGIN ! LOCAL X,Y; X_EXTEND(LITVALUE(.LOP)); Y_EXTEND(LITVALUE(.ROP)); IF .NODE[NODEX] EQL SMAXOP THEN X_ IF .X GTR .Y THEN .X ELSE .Y ELSE X_ IF .Y GTR .X THEN .X ELSE .Y; SETRESULTLIT(.X); SRF(RFNONE); RSTATE END; TES; CASE .LOP[KNEGF] + .ROP[KNEGF] OF SET 0; IF .LOP[KNEGF] THEN LOP_NODE[OPR1]_LOADNODE(.LOP) ELSE ROP_NODE[OPR2]_LOADNODE(.ROP); BEGIN OFFNEG(NODE[OPR1]); OFFNEG(NODE[OPR2]); NX(OTHEROP(SMAXOP,SMINNOP)); KNEG END; TES; SETIDTOP; RETURN SETLCONF(MPOSNPR,.NODE[NKNEGF],MAKESTATE) END; DELAYR(DMULDIVMOD) !NOTE: DIV/MOD ARE NOT COMMUTATIVE. IF TPATH THEN THE !OPERANDS ARE IN REVERSE ORDER. LOCAL C,X,Y,S,TOG; FUNCTION CONVSHIFT(POSORNEG)= BEGIN IF (.ROP[SSLF] EQL LF2N) OR (.ROP[SSLF] EQL LFPM2) THEN BEGIN X_35-FIRSTONE(ABS(Y_EXTEND(LITVALUE(.ROP)))); X_.X*.POSORNEG; IF .C THEN BEGIN SETRESULT(LOP); NODE[OFFSETF]_(.NODE[OFFSETF])^.X AND #177777 END; NODE[NODEX]_SSHIFTOP; ROP_NODE[OPR2]_DELAY(ARBITRARYK+REALVALK+MPOSNPK+MUNCOMPNK+LITLEXEME(.X)); NODE[CSCOMPL]_.LOPST[CSCOMPL]+(LITVALUE(.ROP) MOD 8); IF .X LSS 0 AND .LOP[KNEGF] THEN LOP_NODE[OPR1]_XLOADNODE(.LOP); NODE[NKNEGF]_(.LOP[KNEGF] XOR (.Y LSS 0)); RETURN SETLCONF(MPOSNPR,.NODE[NKNEGF],MAKESTATE) END; END; S_0; C_0; IF .NODE[NODEX] EQL SMULOP THEN C_CKDISTMULT(.NODE,TRUE); LDELAY(NORESULTCHECK+MUNCOMPNK+(IF .C THEN ARBITRARYK ELSE OPERNDK) +(IF NEGNPR THEN NEGNPK ELSE POSNPK)); RDELAY(NORESULTCHECK+MUNCOMPNK+OPERNDK +(IF NEGNPR XOR .LOP[KNEGF] THEN NEGNPK ELSE POSNPK)); IF .C THEN C_(ADDCLASS(.LOP) EQL ADTL); DEFAULTFIELDVALUES; NORESULTRET; IF ISLIT(LOP) AND NOT ISLIT(ROP) THEN SWAPOP; SETIDTOP; CASE .LOP[SLF] + .ROP[SLF] OF SET ! ANYTHING ANYTHING 0; ! ANYTHING L IF .NODE[NODEX] EQL SMULOP THEN BEGIN NODE[TPATH]_0;SETIDTOP; IF .ROP[SSLF] EQL LFZERO THEN (SETRESULTLIT(0);SRF(RFNONE);RSTATE); IF .ROP[SSLF] EQL LFPM1 THEN (IF EXTEND(LITVALUE(.ROP)) LSS 0 THEN NODE[NKNEGF]_NOT .NODE[NKNEGF]; SETRESULT(LOP); SRF(RFNONE); RETURN SETLCONF(MPOSNPR,.NODE[NKNEGF],MAKESTATE)); IF (TOG_CONVSHIFT(1)) NEQ 0 THEN RETURN .TOG; IF .C THEN NODE[OFFSETF]_(LITVALUE(.LOPST[OFFSETF])* LITVALUE(.ROP)) AND #177777 END ELSE BEGIN IF .ROP[SSLF] EQL LFZERO THEN IF .NODE[TPATH] THEN (SETRESULTLIT(0);SRF(RFNONE);RSTATE) ELSE WARNEM(0,DIVERR); IF .ROP[SSLF] EQL LFPM1 THEN IF NOT .NODE[TPATH] THEN (IF EXTEND(LITVALUE(.ROP)) LSS 0 THEN NODE[NKNEGF]_NOT .NODE[NKNEGF]; IF .NODE[NODEX] EQL SDIVOP THEN SETRESULT(LOP) ELSE SETRESULTLIT(0); SRF(RFNONE); RETURN SETLCONF(MPOSNPR, .NODE[NKNEGF],MAKESTATE)); IF NOT .NODE[TPATH] THEN IF .NODE[NODEX] EQL SDIVOP THEN IF (TOG_CONVSHIFT(-1)) NEQ 0 THEN RETURN .TOG END; ! L L; BEGIN X_EXTEND(LITVALUE(.LOP)); Y_EXTEND(LITVALUE(.ROP)); SELECT .NODE[NODEX] OF NSET SMULOP:EXITSELECT X_.X*.Y; SDIVOP:EXITSELECT X_.X/.Y; SMODOP:EXITSELECT X_.X MOD .Y TESN; SETRESULTLIT(.X); SRF(RFNONE); RSTATE END; TES; SETCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); IF (.LOP[KNEGF] XOR .ROP[KNEGF]) AND MPOSNPR THEN (NODE_MAKEROUTINE(.NODE); XLOADNODE(.NODE)) ELSE MAKEROUTINE(.NODE) END; DELAYR(DNEG) UDELAY(NORESULTCHECK+OPERNDK+MUNCOMPNK+(IF NEGNPR THEN POSNPK ELSE NEGNPK)); DEFAULTFIELDVALUES; NORESULTRET; SETRESULT(UOP); SETIDTUOP; NODE[NKNEGF]_NOT .NODE[NKNEGF]; SETLCONF(MPOSNPR,.NODE[NKNEGF],MAKESTATE) END; DELAYR(DNOT) UDELAY(.NODESW[CTKF]^CTKFPOS+OPERNDK+MPOSNPK+(IF UNCOMPNR THEN COMPNK ELSE UNCOMPNK)); DEFAULTFIELDVALUES; NORESULTRET; IF NOT REALVALR THEN SRF(RFFLOW); SETRESULT(UOP); SETIDTUOP; NODE[NKNOTF]_NOT .NODE[NKNOTF]; SETLCONF(MUNCOMPNR,.NODE[NKNOTF],MAKESTATE) END; DELAYR(DNULL) SETCONTROL; DEFAULTFIELDVALUES; RSTATE END; DELAYR(DPLUS) UDELAY(.NODESW[KFIELDS]^REQUESTPOS); DEFAULTFIELDVALUES; NORESULTRET; SETRESULT(UOP); NODE[COMPLEXITY]_.UOPST[COMPLEXITY]; RSTATE END; DELAYR(DPOINTER) LOCAL DFLG,POSIT,SIZ; DFLG_0; NODE_PCSEDOT(.NODE); UDELAY(NORESULTCHECK+.NODESW[CKF]^CKFPOS+(MPOSNPK+MUNCOMPNK)); DEFAULTFIELDVALUES; NORESULTRET; POSIT_LITVALUE(.NODE[OPERAND(1)]); SIZ_LITVALUE(.NODE[OPERAND(2)]); IF .POSIT EQL 0 THEN IF .SIZ EQL 16 THEN (SETRESULT(UOP); P(0,16); RSTATE); IF NOT ADDRESSR THEN (SETRESULT(UOP); NODE[NIMMF]_0; P(0,16); RSTATE); IF .POSIT EQL 8 THEN IF .SIZ EQL 8 THEN IF .UOP[LTYPF] NEQ LITTYP THEN IF .UOPST[MODE] EQL INDEXED+DEFERRED THEN (UOPST[MODE]_INDEXED; UOP_NODE[OPR1]_XLOADNODE(.UOP); DFLG_1); NODE[RCOPTF]_0; SETRESULT(UOP); IF .DFLG THEN M(DEFERRED); P(.POSIT,.SIZ); NODE[NSLF]_NOTLIT; ! A POINTER IS NEVER A LITERAL! NODE[NIMMF]_0; SETIDTUOP; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DREL) MACRO BOTHNEG=.LOP[KNEGF] AND .ROP[KNEGF]$, CONVERSEREL=(IF SIGNEDREL THEN .CRELPLIT[.NODE[NODEX]-SGTROP] ELSE .CRELPLIT[.NODE[NODEX]-SGTRUOP]+SGTRUOP-SGTROP)$, SIGNEDREL=.NODE[NODEX] LEQ SNEQOP$; BIND CRELPLIT=PLIT(SLSSOP,SGEQOP,SGTROP,SLEQOP,SEQLOP,SNEQOP); LOCAL CODET; IF NOT REALVALR THEN UNDOCSE(.NODE); CODET_NORESULTCHECK; LDELAY(.CODET+MUNCOMPNK+DCNPK+OPERNDK); RDELAY(.CODET+MUNCOMPNK+DCNPK+OPERNDK); DEFAULTFIELDVALUES; IF NOT REALVALR THEN SRF(RFFLOW); NORESULTRET; SETIDTOP; CASE .LOP[SLF]+.ROP[SLF] OF SET ! EXP EXP IF BOTHNEG THEN BEGIN OFFNEG(NODE[OPR2]); OFFNEG(NODE[OPR1]); NX(CONVERSEREL); END ELSE IF .LOP[KNEGF] THEN LOP_NODE[OPR1]_XLOADNODE(.LOP) ELSE IF .ROP[KNEGF] THEN ROP_NODE[OPR2]_XLOADNODE(.ROP); ! EXP L BEGIN LOCAL LEXEME L:EXP; BIND GTVEC LST=L:EXPST=EXP; IF ISLIT(LOP) THEN (L_.LOP; EXP_.ROP) ELSE (L_.ROP; EXP_.LOP); IF ONEOF(.NODE[NODEX],BIT2(SNEQOP,SEQLOP)) THEN IF .EXP[LTYPF] EQL GTTYP THEN IF .EXPST[NODEX] EQL SANDOP AND NOT ISCSE(EXP) AND NOT .EXPST[COPIED] THEN BEGIN BIND LEXEME EXPL=EXPST[OPR1]:EXPR=EXPST[OPR2]; IF .EXPL[KNOTF] OR .EXPR[KNOTF] THEN EXITBLOCK; L_LITVALUE(.L); IF .L EQL 0 OR POF2(.L) AND (IF ISLIT(EXPL) THEN CLITVALUE(EXPL) EQL .L ELSE IF ISLIT(EXPR) THEN CLITVALUE(EXPR) EQL .L ELSE 0) THEN BEGIN EXPST[NODEX]_SBITOP; SETRESULT(EXP); EXPST[NKNOTF]_.L NEQ 0 XOR .NODE[NODEX] EQL SNEQOP; EXPST[NSRFF]_.NODE[NSRFF]; SRF(RFNONE); EXITCASE END; END; IF .EXP[KNEGF] THEN BEGIN IF ISLIT(LOP) THEN (NODE[OPR1]_NEGLIT(.NODE[OPR1]); OFFNEG(NODE[OPR2])) ELSE (NODE[OPR2]_NEGLIT(.NODE[OPR2]); OFFNEG(NODE[OPR1])); NX(CONVERSEREL); END; END; ! L L BEGIN REGISTER X,Y; X_LITVALUE(.LOP); Y_LITVALUE(.ROP); IF SIGNEDREL THEN BEGIN X_EXTEND(.X); Y_EXTEND(.Y); WHICH_.NODE[NODEX]-SGTROP; END ELSE WHICH_.NODE[NODEX]-SGTRUOP; SETRESULTLIT(DKAYCE SET .X GTR .Y; .X LEQ .Y; .X LSS .Y; .X GEQ .Y; .X EQL .Y; .X NEQ .Y TES); SRF(RFNONE); END TES; IF SELECTEVALORDER(.NODE) THEN SWAPOP; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DROTSHIFT) LOCAL C,D,E; C_0; IF .NODE[NODEX] EQL SSHIFTOP THEN C_CKDISTMULT(.NODE,FALSE); IF .C THEN C_(EXTEND(LITVALUE(.NODE[OPR2])) GTR 0); LDELAY(NORESULTCHECK+MUNCOMPNK+MPOSNPK+(IF .C THEN ARBITRARYK ELSE OPERNDK)); RDELAY(NORESULTCHECK+MUNCOMPNK+MPOSNPK+OPERNDK); IF .C THEN C_(ADDCLASS(.LOP) EQL ADTL); DEFAULTFIELDVALUES; NORESULTRET; SETIDTOP; IF NOT ISLIT(ROP) THEN (SETIDTCONTROL;RETURN MAKEROUTINE(.NODE)); IF (D_EXTEND(LITVALUE(.ROP))) EQL 0 THEN (SETRESULT(LOP);SRF(RFNONE)); E_.LOPST[CSCOMPL]+(ABS(.D) MOD 8); IF .C THEN BEGIN SETRESULT(LOP); NODE[CSCOMPL]_.E; NODE[OFFSETF]_.NODE[OFFSETF]^.D AND #177777; RSTATE END; NODE[CSCOMPL]_.E; RSTATE END; DELAYR(DROUT) LOCAL L,STVEC LR; LR_.NODE[OPR2]; LR_.LR[LNKGNMF]; L_IF .LR[LNKGTF] EQL INTRRPTLNKGT THEN NORESULTK ELSE REALVALK; LDELAY(.L+MUNCOMPNK+MPOSNPK+OPERNDK); SETCONTROL; DEFAULTFIELDVALUES; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); IF ISLIT(LOP) THEN SETRESULTLIT(LITVALUE(.LOP)) ELSE SETRESULT(LOP); RSTATE END; DELAYR(DSELECT) MACRO LASTOPERAND=OPERAND(.NODE[NODESIZEF]-1)$;; DLY(UOP,OPR1, (IF (UOP_.NODE[OPR1];.UOP[LTYPF] NEQ LITTYP) THEN TEMPK ELSE OPERNDK) +REALVALK+MPOSNPK+MUNCOMPNK); IF .UOP[LTYPF] EQL GTTYP THEN BEGIN UOPST[NIDTF]_0; UOP_.NODE[OPR1]; UOP[IDTF]_0; NODE[OPR1]_.UOP; END; DEFAULTFIELDVALUES; ! DONE HERE, BEFORE .NODE[ROTHER] IS SET INCR I FROM 1 TO .NODE[NODESIZEF]-3 DO IF (UOP_.NODE[OPERAND(.I)];.UOP[LTYPF] NEQ SELTYP) THEN (IF NOT .I THEN NOGETLOAD; DLY(UOP,OPERAND(.I), (IF .I THEN REALVALK ELSE NORESULTCHECK) + MPOSNPK+MUNCOMPNK+OPERNDK); IF NOT .I THEN OKGETLOAD) ELSE (NODE[ROTHER]_1; IF .UOP EQL LEXOTHERWISE THEN IF .NODE[LASTOPERAND] EQL ZERO THEN NODE[LASTOPERAND]_LITLEXEME(.I)); SETCONTROL; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; DELAYR(DSTORE) LOCAL LHS,RHS,LEXEME X; MACRO MAKETN(XOP)= BEGIN LOCAL GTVEC TNC; TNC_NODE[REGF]_GETTN(); TNC[REQD]_MEMREQDB; TNC[REGF]_.XOP END$, FIXRESULT(XOP)=(IF .XOP[LTYPF] EQL LITTYP THEN SETRESULT(XOP) ELSE MAKETN(XOP); SRF(RFNONE))$; LOCAL NEWMODE,WLITT,CODET; X_ISOPTOMEM(.NODE[OPR1],.NODE[OPR2]); IF .X[LEXPART] NEQ 0 THEN (UNLINKCSE(.X); X[LEXPART]_0); LDELAY(ADDRESSK+REALVALK+MPOSNPK+MUNCOMPNK); WLITT_WANTLITR OR ONEOF(.LOP[SSPF],BIT2(PFE1,PFOTHER)); CODET_IF TEMPR THEN TEMPK ELSE OPERNDK; RDELAY(.CODET+REALVALK+MPOSNPK+MUNCOMPNK+.X+.WLITT^WANTLITQ); DEFAULTFIELDVALUES; IF NORESULTR THEN (NORESULTSET; IF ISSYM(LOP) OR SELECTEVALORDER(.NODE) THEN SWAPOP; RSTATE); IF NOT ISSYM(ROP) THEN IF NOT TEMPR THEN IF WANTLITR AND ISLIT(ROP) THEN FIXRESULT(ROP) ELSE BEGIN LHS_COMPLICATED(LEFTSIDEK+.LOP[LEXPART],0); RHS_COMPLICATED(RITESIDEK+.ROP[LEXPART],.LOP); IF .LHS LSS 10 AND .LHS LEQ .RHS AND (.RHS GEQ 10 OR NOT (ADDRESSR AND (IF .LOP[LTYPF] NEQ LITTYP THEN .LOPST[MODE] EQL INDEXED+DEFERRED))) THEN IF NOT ADDRESSR THEN (FIXRESULT(LOP); IF .LOP[LTYPF] EQL LITTYP THEN NODE[IMMF]_0) ELSE (IF .LOP[LTYPF] EQL LITTYP THEN NEWMODE_0 ELSE NEWMODE_CASE .LOPST[MODE] OF SET DEFERRED; DEFERRED; DEFERRED; DEFERRED; -1; -1; DEFERRED; (M(DEFERRED);-1); TES; IF .NEWMODE GEQ 0 THEN (FIXRESULT(LOP);M(.NEWMODE))) ELSE IF .RHS LSS 10 THEN FIXRESULT(ROP); END; IF ISSYM(LOP) OR SELECTEVALORDER(.NODE) THEN SWAPOP; RSTATE END; DELAYR(DSWAB) UDELAY(OPERNDK+NORESULTCHECK+MPOSNPK+MUNCOMPNK); DEFAULTFIELDVALUES; NORESULTRET; SETIDTOP; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); NODE[RUCOMPL]_.UOPST[RUCOMPL]; RSTATE END; DELAYR(DSYM) MACRO SYMSTATE=.NODESW[LEXPART]+RFREALK+.LPFK$; LOCAL LPFK; IF NOT ISADDR(NODE) THEN PUNT(ERSYMOR); LPFK_(IF .NODE[SIZEF] EQL 8 AND ADDRESSR THEN PF08K ELSE PFNONEK); IF TEMPR THEN RETURN XLOADNODE(SYMSTATE+IMMK); IF ADDRESSR THEN BEGIN LOCAL L; L_NCSEARCH(.NODE); IF .L GEQ 0 THEN IF .NCSE[.L,NCGT] EQL 0 THEN RETURN IF .GETLCNT EQL 0 THEN GETLOAD(.NODE,.L) ELSE SYMSTATE ELSE RETURN IF .INENABLE EQL 0 THEN GETFAKE(.NCSE[.L,NCGT]) ELSE SYMSTATE END ELSE IF .NODE[MODE] EQL INDEXED THEN RETURN LOADNODE(SYMSTATE+IMMK) ELSE IF .NODE[TYPEF] EQL LOCALT OR FLOWVALR THEN RETURN XLOADNODE(SYMSTATE+IMMK); (IF NOT ADDRESSR THEN IMMK)+SYMSTATE END; DELAYR(DWU) MACRO RHOPART=OPERAND(0)$, CHIPART=OPERAND(1)$; LOCAL SAVFLS; RHOPULSE(PULSEDELAY,.NODE[RHOPART]); PULSE(CHIPART); SAVFLS_.FLSTK; FLSTK_MAKHDR(FLSREMOVE,FLSENTER); DLY(LOP,OPR3,OPERNDK+FLOWVALK+DCNPK+DCNK); DLY(ROP,OPR4,ARBITRARYK+NORESULTK+MPOSNPK+MUNCOMPNK); ROP_FIXCOND(NODE[OPR4]); MARKLSTNAMES(.FLSTK,.NODE[CHIPART]); MERGE(.SAVFLS,.FLSTK,0); RELITEM(.FLSTK,2); FLSTK_.SAVFLS; SETCONTROL; DEFAULTFIELDVALUES; NORESULTRET; SETIDTCONTROL; NODE[CSCOMPL]_CALCCSCOMPL(.NODE); RSTATE END; COMMENT ! EQLPOSSIZE ! ! THIS ROUTINE IS CRUCIAL TO SIMPLE-STORE DISCOVERY (SEE 'SIMPLESTORE' ! IN TNBIND, 'ISOPTOMEM' IN DELAY), AND TO THAT PORTION OF POSITION-SIZE ! TARGETING WHICH STEMS FROM SIMPLE-STORE DISCOVERY (I.E., RECOGNITION ! AND CORRECT CODE GENERATION FOR EXPRESSIONS LIKE ! E1 _ .E1 OP E2 ! FOR CERTAIN SPECIAL CASES OF THE OPERATOR 'OP', COUPLED WITH SPECIAL ! CASES OF P1 AND S1; SEE 'ISPSOK' IN TNBIND). ! ! FUNCTION: A PREDICATE. ! IMAGINE FOR A MOMENT THAT "POINTER" NODES (E) COULD BE COMMON ! SUB-EXPRESSIONS OF EACH OTHER. THEN THIS ROUTINE WOULD RETURN 1 IF ! ITS ARGUMENTS WERE (1) IDENTICAL LEXEMES, OR (2) ON THE SAME CSE ! CHAIN. (THERE IS ONE HITCH: IF A IS A BYTE VARIABLE, A<0,8> IS ! CONSIDERED IDENTICAL TO A; THIS IS BECAUSE ADDRESSING OF THE TWO IS ! IDENTICAL.) AS IT IS, EQLPOSSIZE HAS TO DO SOME EXTRA PROCESSING ! OF POINTER NODES, CHECKING WHETHER THEIR 'E' SUBNODES ARE IDENTICAL ! LEXEMES (OR ON THE SAME CSE CHAIN). ! ! CALLED FROM: ISOPSUB (DELAY), ISNEGNOT (TNBIND), SIMPLESTORE (TNBIND) ! GLOBAL ROUTINE EQLPOSSIZE(LEX1,LEX2)= BEGIN MAP LEXEME LEX1:LEX2; BIND GTVEC NODE1=LEX1:NODE2=LEX2; LOCAL POS1,POS2,SIZE1,SIZE2; IF .LEX1 EQL .LEX2 THEN RETURN TRUE; CASE .LEX1[LTYPF]-1 OF SET % LITTYP % (POS1_0; SIZE1_16); % BNDVAR % (POS1_.NODE1[POSF]; SIZE1_.NODE1[SIZEF]); % GTTYP % (IF .NODE1[NODEX] EQL SYNPOI THEN (POS1_LITVALUE(.NODE1[OPR2]); SIZE1_LITVALUE(.NODE1[OPR3]); NODE1_.NODE1[OPR1]; IF .LEX1[LTYPF] NEQ GTTYP THEN EXITCASE) ELSE (POS1_0; SIZE1_16); LEX1[ADDRF]_.NODE1[CSPARENT]) TES; CASE .LEX2[LTYPF]-1 OF SET % LITTYP % (POS2_0; SIZE2_16); % BNDVAR % (POS2_.NODE2[POSF]; SIZE2_.NODE2[SIZEF]); % GTTYP % (IF .NODE2[NODEX] EQL SYNPOI THEN (POS2_LITVALUE(.NODE2[OPR2]); SIZE2_LITVALUE(.NODE2[OPR3]); NODE2_.NODE2[OPR1]; IF .LEX2[LTYPF] NEQ GTTYP THEN EXITCASE) ELSE (POS2_0; SIZE2_16); LEX2[ADDRF]_.NODE2[CSPARENT]) TES; IF .POS1 NEQ .POS2 THEN RETURN 0; IF .SIZE1 NEQ .SIZE2 THEN RETURN 0; RETURN .LEX1[LEXPART] EQL .LEX2[LEXPART] END; ROUTINE ISOPTOMEM(LHS,RHS)= BEGIN MAP STVEC LHS:RHS; BIND LEXEME LRHS=RHS; LOCAL X; MACRO EXSEL=EXITSELECT$; MACRO MAYCRAVESWAP= ONEOF(.RHS[NODEX],BIT6(SADDOP,SMINOP, SANDOP,SOROP, SMAXOP,SMINNOP))$; ROUTINE ISOPSUB(LH,SUBRH)= BEGIN LOCAL GTVEC Z; MAP GTVEC LH:SUBRH; BIND LEXEME LLH=LH:LSUBRH=SUBRH:LZ=Z; IF .LSUBRH[LTYPF] NEQ GTTYP THEN RETURN 0; IF .SUBRH[NODEX] NEQ SDOTOP THEN RETURN 0; IF (Z_.SUBRH[OPR1]) EQL .LH THEN RETURN .LSUBRH[LEXPART]; IF EQLPOSSIZE(.Z,.LH) THEN (IF .LZ[LTYPF] EQL GTTYP THEN GT[.Z[CSPARENT],DONTUNLINK]_TRUE; RETURN -1); RETURN 0 END; IF .LRHS[LTYPF] NEQ GTTYP THEN RETURN DCSWK; IF .RHS[NODEX] GTR MAXOPERATOR THEN RETURN DCSWK; IF (X_ISOPSUB(.LHS,.RHS[OPR1])) GTR 0 THEN RETURN NSWPK+.X; IF .X EQL -1 THEN RETURN NSWPK; IF NOT MAYCRAVESWAP THEN RETURN DCSWK; IF (X_ISOPSUB(.LHS,.RHS[OPR2])) GTR 0 THEN RETURN SWPK+.X; IF .X EQL -1 THEN RETURN SWPK; DCSWK END; DELAYR(XLOADNODE) BIND ALLOWNEG=0, ALLOWCOMP=0; UOP_.NODE; NODE_GETSPACE(GT,BASEGTNODESIZE+1); NODE[OCCF]_1; NODE[TYPEF]_GRAPHT; NODE[CSPARENT]_.NODE; NODE[CSTHREAD]_0; NODE[STATE]_0; NODE[NODEX]_SPLUSOP; NODE[NODESIZEF]_1; NODE[OPR1]_.UOP; DEFAULTFIELDVALUES; NODE[RCCF]_0; !DEFAULTFIELD TURNS ON AS GENCODE BIT NODE[MUSTGENCODE]_1; IF .UOP[IMMF] AND .UOP[LTYPF] NEQ LITTYP THEN IF .UOPST[TYPEF] EQL GRAPHT THEN IF .UOPST[MODE] EQL INDEXED THEN (RCA; O(.UOPST[OFFSETF]); NODE[SYMOFFF]_.UOPST[SYMOFFF]; UOPST[OLDRCMTF]_(NOT .UOPST[RCMTF]); UOPST[RCMTF]_1); IF ALLOWNEG THEN NODE[NKNEGF]_.UOP[KNEGF] ELSE IF .UOP[KNEGF] THEN (RCNT; IF .NODE[RCAF] THEN (NODE[RCAF]_0; RCS)); IF ALLOWCOMP THEN NODE[NKNOTF]_.UOP[KNOTF] ELSE IF .UOP[KNOTF] THEN RCC; RCMT; IF NOT ISLITLEX(UOP) THEN IF .UOP[LTYPF] EQL GTTYP THEN NODE[COMPLEXITY]_.UOPST[COMPLEXITY]; M(GENREG); NODE[NIDTF]_1; RSTATE END; DELAYR(LOADNODE) BIND ALLOWNEG=0, ALLOWCOMP=0; LOCAL SIZE; IF ISLITLEX(NODESW) THEN RETURN XLOADNODE(.NODE); IF .NODE[TYPEF] NEQ GRAPHT THEN RETURN XLOADNODE(.NODE); IF .NODE[NODESIZEF] EQL 0 THEN RETURN XLOADNODE(.NODE); SIZE_BASEGTNODESIZE+.NODE[NODESIZEF]; UOP_LEXOUT(GTTYP,GETSPACE(GT,.SIZE)); MOVECORE(.NODE,.UOPST,.SIZE); UOPST[CSTHREAD]_0; UOPST[CSPARENT]_.UOP; UOPST[OCCF]_1; NODE[OPR1]_UOP_.UOP[LEXPART]+(.NODE[NRWORDF]^RESULTPOS); NODE[STATE]_0; IF .NODE[NODESIZEF] GTR 1 THEN RELEASESPACE(GT,.NODESW[ADDRF]+BASEGTNODESIZE+1,.NODE[NODESIZEF]-1); NODE[NODEX]_SPLUSOP; NODE[NODESIZEF]_1; DEFAULTFIELDVALUES; NODE[RCCF]_0; !DEFAULTFIELD TURNS ON AS GENCODE BIT NODE[MUSTGENCODE]_1; IF .UOP[IMMF] THEN IF .UOPST[MODE] EQL INDEXED THEN (UOPST[RCAF]_1; UOPST[RCMTF]_1); IF ALLOWNEG THEN NODE[NKNEGF]_.UOP[KNEGF] ELSE IF .UOP[KNEGF] THEN (RCNT; IF .NODE[RCAF] THEN (NODE[RCAF]_0; RCS)); IF ALLOWCOMP THEN NODE[NKNOTF]_.UOP[KNOTF] ELSE IF .UOP[KNOTF] THEN RCC; RCMT; ! MAY BE TURNED OF BY SIMPLESTORE NODE[COMPLEXITY]_.UOPST[COMPLEXITY]; M(GENREG); R(0); SETIDTOP; RSTATE END; DELAYR(MAKEROUTINE) LOCAL GTVEC RNODE:FNODE,Z[2],LEXEME Q; RNODE_GETSPACE(GT,BASEGTNODESIZE+.NODE[NODESIZEF]+2); MOVECORE(.NODE,.RNODE,BASEGTNODESIZE); RNODE[NODESIZEF]_.RNODE[NODESIZEF]+2; RNODE[NODEX]_SYNPAR; RNODE[OPR1]_.DFLTLNKGLX; RNODE[CSPARENT]_.RNODE; RNODE[MUSTGENCODE]_1; RNODE[OCCF]_1; UOP_RNODE[OPR2]_(SELECT .NODE[NODEX] OF NSET SMULOP:EXITSELECT .LEXMUL; SDIVOP:EXITSELECT .LEXDIV; SMODOP:EXITSELECT .LEXMOD; SROTOP:EXITSELECT .LEXROT; SSHIFTOP:EXITSELECT .LEXSHIFT TESN); UOPST[PRNEXF]_1; IF .NODE[TPATH] THEN (Z[0]_.NODE[OPR2];Z[1]_.NODE[OPR1]) ELSE (Z[0]_.NODE[OPR1];Z[1]_.NODE[OPR2]); INCR I FROM 2 TO 3 DO BEGIN BIND GTVEC NODE=FNODE; FNODE_GETSPACE(GT,BASEGTNODESIZE+1); FNODE[FLOLSTBIT]_0; FNODE[NODESIZEF]_1; FNODE[NODEX]_SFPARM; FNODE[TYPEF]_GRAPHT; FNODE[MUSTGENCODE]_1; FNODE[OCCF]_1; FNODE[OFFSETF]_FNODE[REGF]_LZERO; FNODE[FPARENT]_FNODE[CSPARENT]_.FNODE; FNODE[OPR1]_.Z[.I-2]; SETCONTROL; DEFAULTFIELDVALUES; SETIDTCONTROL; RNODE[OPERAND(.I)]_MAKESTATE END; NODE[OPR1]_LEXOUT(GTTYP,.RNODE); RELEASESPACE(GT,NODE[OPR2],.NODE[NODESIZEF]-1); NODE[FLOLSTBIT]_0; RNODE[FLOLSTBIT]_0; NODE[NODESIZEF]_1; NODE[NODEX]_SFSTORE; SETCONTROL; DEFAULTFIELDVALUES; SETIDTCONTROL; NODE[CSCOMPL]_0; RSTATE END; ROUTINE NEGLIT(NODE)= BEGIN MAP GTVEC NODE; BIND LEXEME LEX=NODE; REGISTER X; X_DELAY(REALVALK+ARBITRARYK+MUNCOMPNK+MPOSNPK+ LITLEXEME(-CLITVALUE(NODE))); IF .LEX[LTYPF] EQL LITTYP THEN .X ELSE (SETRES(.X); .NODE[STATE]) END; ROUTINE ODDFIELD(NODE)= BEGIN MAP STVEC NODE; ! TRUE IF NOT <0,16> OR <0,8> IN A PTR NODE IF LITVALUE(.NODE[OPR2]) NEQ 0 THEN 1 ELSE IF LITVALUE(.NODE[OPR3]) EQL 16 THEN 0 ELSE IF LITVALUE(.NODE[OPR3]) EQL 8 THEN 0 ELSE 1 END; COMMENT ! OPCOMPL ! ! COMPUTE A CRUDE MEASURE OF THE CODE SIZE OF A NODE. ! ROUTINE OPCOMPL(NODE)= BEGIN MAP GTVEC NODE; SELECT .NODE[NODEX] OF NSET SSHIFTOP: (NODE_.NODE[OPR2]; IF NOT ISLIT(NODE) THEN 8 ELSE (NODE_ABS(CLITVALUE(NODE)); IF .NODE GEQ 8 THEN 16-.NODE ELSE .NODE)); SYNPOI:IF .NODE[POSF] EQL 0 THEN 1 ELSE IF .NODE[POSF] EQL 8 THEN 2 ELSE 8; SADDOP: SUMBITS(.NODE[RCBITS]); OTHERWISE: 1; TESN END; DELAYR(PCSEDOT) MACRO MAKETMP=TEMPK+NORESULTCHECK+MUNCOMPNK+MPOSNPK$, XUDELAY(Z)=(IF NOT UNDOCSE(.NODE) THEN (FORCETEMP; RETURN .NODE) ELSE (UOPST[DONTUNLINK]_TRUE; UDELAY(Z); RETURN .NODE))$; IF TEMPR THEN (UOP_.NODE[OPR1]; IF .UOP[LTYPF] EQL BNDVAR THEN IF .UOPST[MODE] EQL GENREG THEN NODESW[CKF]_OPERND); IF ISCSE(NODE) THEN IF NOT(TEMPR) THEN BEGIN LOCAL T; T_0; UOP_.NODE[OPR1]; IF .UOP[LTYPF] EQL GTTYP THEN BEGIN IF ISCSE(UOP) THEN T_-1 ELSE IF UNDONE(UOPST) THEN T_(IF .UOPST[NODEX] EQL SDOTOP THEN .UOPST[CHPDFR]) ELSE SELECT .UOPST[NODEX] OF NSET SDOTOP: EXITSELECT (T_-1); SADDOP: EXITSELECT IF .GT[.NODE[CSPARENT],OCCF] LEQ 3 THEN T_-1 ELSE XUDELAY(MAKETMP); SMINOP: EXITSELECT IF .GT[.NODE[CSPARENT],OCCF] LEQ 3 THEN T_-1 ELSE XUDELAY(MAKETMP); SYNPOI: EXITSELECT IF ODDFIELD(.NODE[OPR1]) THEN T_0 ELSE T_-1; OTHERWISE: XUDELAY(MAKETMP); TESN; END ELSE IF .UOP[LTYPF] EQL BNDVAR THEN BEGIN NODE[CHPDFR]_1; IF .UOPST[MODE] EQL GENREG THEN T_1 ELSE IF NOT ISLARGECSE(NODE) THEN T_1; END ELSE IF .UOP[LTYPF] EQL LITTYP THEN BEGIN IF NOT ISLARGECSE(NODE) THEN T_1; END; CASE .T+1 OF SET % T = -1 % IF NOT UNDOCSE(.NODE) THEN FORCETEMP; % T = 0 % FORCETEMP; % T = 1 % UNDOCSE(.NODE) TES; END; .NODE END; ROUTINE PULSEDELAY(NODE,CONT)= BEGIN MAP GTVEC NODE; LOCAL FLG; FLG_.NODE[MUSTGENCODE]; NODE[MUSTGENCODE]_TRUE; NODE[DONTUNLINK]_TRUE; DELAY(.NODE+(PULSEINFO OR .CONT^CKFPOS)); NODE[MUSTGENCODE]_.FLG; NODE[NIDTF]_0 END; DELAYR(SELECTEVALORDER) LOCAL LRUC, RRUC, MUC, LCSC, RCSC; BIND INCREMENT=16, BANDWIDTH=INCREMENT/2; MACRO EQUIV(M1,M2)=(ABS (M1-M2) LEQ BANDWIDTH)$, MAX(X,Y)=(IF X LSS Y THEN Y ELSE X)$, RUTERMC(X)=(IF .X[LTYPF] NEQ GTTYP THEN 0 ELSE .ID(X)ST[RUCOMPL])$, CCTERMC(X)=(IF .X[LTYPF] NEQ GTTYP THEN 0 ELSE .ID(X)ST[CORCSEF])$, CSTERMC(X)=(IF .X[LTYPF] NEQ GTTYP THEN 0 ELSE .ID(X)ST[CSCOMPL])$; LOP_.NODE[OPR1]; ROP_.NODE[OPR2]; ! IF CSE OR CONTROL, OR CONTAINS CSE OR CONTROL--NO COMPLEXITY ! AND NO SWITCH EVAL ORDER. IF NODE[CORCSEF]_CCTERMC(LOP) OR CCTERMC(ROP) OR ISCSECREATION(NODE) THEN (NODE[CSCOMPL]_NODE[RUCOMPL]_0; RETURN .LOP[LTYPF] NEQ GTTYP); ! DETERMINE REGISTER USE COMPLEXITY LRUC_RUTERMC(LOP); RRUC_RUTERMC(ROP); MUC_MAX(.LRUC,.RRUC); NODE[RUCOMPL]_ (IF ISCSEUSE(NODE) THEN INCREMENT/(.NODE[OCCF]-1) ELSE IF EQUIV(.LRUC,.RRUC) THEN .MUC+INCREMENT ELSE .MUC); ! DETERMINE FLOW USE COMPLEXITY LCSC_CSTERMC(LOP); RCSC_CSTERMC(ROP); NODE[CSCOMPL]_IF ISCSEUSE(NODE) THEN 0 ELSE .LCSC+.RCSC+OPCOMPL(.NODE); ! DETERMINE WHETHER TO SWITCH OR NOT IF ISLIT(LOP) AND NOT ISLIT(ROP) THEN 1 ELSE IF ISLIT(ROP) THEN 0 ELSE IF FLOWVALR THEN .RCSC LSS .LCSC ELSE .RRUC GTR .LRUC END; COMMENT ! STATEMAKE ! ! FUNCTION: ! SET UP THE POSITION/SIZE INFORMATION IN THE CURRENT NODE'S ! STATEWORD, AND THEN BUILD THE RESULT WORD FOR THIS (DELAYED) ! NODE. ! VALUE: ! THE RESULT WORD FOR THIS NODE. ! DELAYR(STATEMAKE) REGISTER SIZ,POSIT; SIZ_.NODE[SIZEF]; POSIT_.NODE[POSF]; NODE[NSSPF]_ (IF .SIZ EQL 1 THEN PFE1 ELSE IF .POSIT EQL 0 THEN IF .SIZ EQL 8 THEN PF08 ELSE IF .SIZ EQL 16 THEN PF016 ELSE PFOTHER ELSE IF (.POSIT EQL 8) AND (.SIZ EQL 8) THEN PF88 ELSE PFOTHER); .NODE[NRWORDF]^RESULTPOS+LEXOUT(GTTYP,.NODE) END; COMMENT ! UNDOCSE ! ! FUNCTION: ! COMPLETELY UNDO THE CSE CHAIN THAT 'NODE' IS PART OF. TURNS ON ! 'MUSTGENCODE' BITS ALL DOWN THE CHAIN, BUT DOESN'T BOTHER THE ! 'CSTHREAD' AND 'CSPARENT' FIELDS. CHAINS HEADED BY BOGUS NODES, ! OR ANY CHAINS CONTAINING FAKE CSE'S, NCSE'S, OR ALPHA OR OMEGA ! LIST NODES, OR ANY OTHER NODES WHOSE 'DONTUNLINK' BITS HAVE BEEN ! SET, ARE NOT TOUCHED, I.E. LEFT INTACT. ! ROUTINE UNDOCSE(NODE)= BEGIN MAP GTVEC NODE; LOCAL GTVEC PNODE:PN; BIND LEXEME SN=PN; IF ONEUSE(NODE) THEN RETURN TRUE; PN_PNODE_.NODE[CSPARENT]; IF .PN[DONTUNLINK] THEN RETURN FALSE; WHILE (PNODE_.PNODE[CSTHREAD]) NEQ 0 DO IF .PNODE[NODEX] EQL SYNNULL OR .PNODE[DONTUNLINK] THEN RETURN (PN[DONTUNLINK]_TRUE; FALSE); PN[OCCF]_1; PNODE_.PN; WHILE (PNODE_.PNODE[CSTHREAD]) NEQ 0 DO (PNODE[MUSTGENCODE]_1;PNODE[CHPDFR]_.PN[CHPDFR]); PNODE_.PN; DECR I FROM .PNODE[NODESIZEF]-1 TO 0 DO BEGIN SN_.PNODE[OPERAND(.I)]; IF .SN[LTYPF] EQL GTTYP THEN (PN_.PN[CSPARENT]; IF NOT UNDONEPARENT(PN) THEN IF (PN[OCCF]_.PN[OCCF]+1) EQL 2 THEN IF .PN[DELAYED] THEN (PN[DELAYED]_0; COPYAROUND(.PN,.PN))) END; RETURN TRUE END; COMMENT ! UNLINKCSE ! ! FUNCTION: ! TAKES A NODE OUT OF A CSE CHAIN, IF IT IS IN ONE, WHILE LEAVING ! THE REST OF THE CHAIN INTACT. ACTUALLY CHANGES 'CSTHREAD' AND ! 'CSPARENT' FIELDS. WILL NOT TOUCH A NODE WHICH IS ON AN ALPHA ! OR OMEGA LIST, IS A BOGUS NODE, OR IS THE CSPARENT OF THE CHAIN ! ITSELF, OR FOR ANY OTHER REASON HAS ITS 'DONTUNLINK' BIT SET. ! ROUTINE UNLINKCSE(NODE)= BEGIN MAP STVEC NODE; BIND LEXEME LN=NODE; REGISTER STVEC L; NODE_.LN[ADDRF]; IF .NODE[DONTUNLINK] THEN RETURN; IF (L_.NODE[CSPARENT]) EQL .NODE THEN RETURN; WHILE .L[CSTHREAD] NEQ 0 DO BEGIN IF .L[CSTHREAD] EQL .NODE THEN BEGIN L[CSTHREAD]_.NODE[CSTHREAD]; L_.NODE[CSPARENT]; IF .L[OCCF] GTR 1 THEN L[OCCF]_.L[OCCF]-1; NODE[CSPARENT]_.NODE; NODE[CSTHREAD]_0; NODE[MUSTGENCODE]_1; NODE[OCCF]_1; NODE[DELAYED]_0; RETURN END; L_.L[CSTHREAD]; END; END; COMMENT ! DELAYDRIVER ! ! FUNCTION: ! (1) SETS UP THE HEADER FOR THE MAIN NCSE LIST. ! (2) INVOKES DELAYING ON THE TOP NODE OF THE GRAPH TABLE TREE. ! (3) RUNS DOWN THE NCSE LIST PUTTING EACH NCSE PARENT ON THE ! ALPHA OR CHI LIST POINTED TO BY ITS LST2 FIELD. ! GLOBAL ROUTINE DELAYDRIVER(LEX)= BEGIN MAP LEXEME LEX; GETLCNT_INENABLE_0; IF .FLSTK NEQ 0 THEN RELLST(.FLSTK); FLSTK_MAKHDR(FLSREMOVE,FLSENTER); DELAY(ARBITRARYK+NORESULTK+MPOSNPK+MUNCOMPNK+.LEX[LEXPART]); BEGIN REGISTER ITEM I:J; I_.FLSTK; UNTIL (I_.I[RLINK]) EQL .FLSTK DO IF (J_.I[LST2]) NEQ 0 THEN IF .J[REMOVE] EQL CHIREMOVE % CHI LIST % THEN LINK(MAKITEM(.I[DATA1],1),.J[LLINK]) % ALPHA LIST % ELSE LINK(MAKITEM(1,.I[DATA1],2),.J[LLINK]) END END; END; END ELUDOM