Trailing-Edge
-
PDP-10 Archives
-
decuslib10-04
-
43,50325/delay.bli
There are no other files named delay.bli in the archive.
! 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<RIGHTPART> 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)= %<ADL,ADNR,ADT,ADTL,ADNT,ADTNR>%
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 <OP> A
0;
! A <OP> 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 <OP> 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; ! <ANY> <MAX OR MIN> <ANY>
BEGIN ! <ANY> <MAX OR MIN> <LITERAL>
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 ! <LITERAL> <MAX OR MIN> <LITERAL>
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 <OP> ANYTHING
0;
! ANYTHING <OP> 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 <OP> 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 <OP> 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 <OP> 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 <OP> 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<P1,S1> _ .E1<P1,S1> 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<P,S>) 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