! File: CODE.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 CODE(TIMER=EXTERNAL(SIX12))= BEGIN ! ! CODE MODULE ! ------------ ! ! SEPT. 1972 ! WULF,JOHNSSON,WEINSTOCK ! LATER ADDITIONS: ! LEVERETT,KNUEVEN ! ! ! THIS MODULE PRODUCES THE ACTUAL PDP-11 MACHINE CODE. IT IS ! EXECUTED AFTER DELAYING AND TEMP-NAME BINDING. THEREFORE ESSENTIALLY ! ALL RELEVANT INFORMATION IS KNOWN. THE PRIMARY FUNCTION OF 'CODE', ! IN ADDITION TO GENERATING THE CODE, IS TO DO THE (RATHER EXTENSIVE) ! SPECIAL CASE ANALYSIS TO PRODUCE LOCALLY OPTIMAL CODE. THUS, FOR ! EXAMPLE, IT IS CODE THAT DETERMINES THE OPTIMAL SEQUENCE OF MASKING, ! ROTATE AND/OR SHIFT, AND 'SWAB' INSTRUCTIONS TO ISOLATE A SUBFIELD ! AND TO ALIGN IT AT A SPECIFIED LOCATION IN A WORD. ! ! THE MAJOR PORTIONS OF CODE ARE: ! ! 1. CODE/LABEL PLACEMENT ! THESE ROUTINES ACTUALLY EMIT THE CODE AND/OR ! LABELS IN A FORM SUITABLE FOR PROCESSING ! BY THE 'FINAL' MODULE. THE CODE REPRESENTATION ! CREATED BY THE ROUTINES IS A DOUBLY LINKED ! LIST -- ITS PRECISE FORM IS IRRELEVANT TO ! THIS MODULE, HOWEVER. ! ! 2. 'VERY-TEMP' ALLOCATION ! IN A FEW CASES THE FACT THAT AN ADDITIONAL ! TEMPORARY IS NEEDED IS NOT KNOWN UNTIL CODE-GENERATION ! TIME, THUS THE TEMPORARIES WILL NOT HAVE ! BEEN ALLOCATED BY 'TNBIND'. THE NECESSARY ! ROUTINES ARE DUPLICATED FROM TNBIND IN ORDER ! ALLOCATE THESE TEMPS 'ON THE FLY' DURING ! CODE-GENERATION. THE SAME PHILOSOPHY FOR ! ALLOCATION IS USED IN CODE AS IN TNBIND, ! ESPECIALLY WRT. LON'S AND FON'S,AS IN ! TNBIND. THEREFORE THEY WILL NOT BE DISCUSSED ! HERE. ! ! 3. ADDRESS GENERATION ! THIS SET OF ROUTINES, OF WHICH 'GMA' AND ! 'GMA8' ARE THE PRINCIPAL ONES, ARE SERVICE ! ROUTINES WHICH GENERATE THE ADDRESS FORMAT ! NEEDED BY 'FINAL'. THE PARAMETER ! TO EACH OF THESE ROUTINES IS A LEXEME -- ! IT MAY BE A LITERAL LEXEME, ST-LEXEME, OR ! GT-LEXEME. IN EACH CASE THE APPROPRIATE ADDRESS ! IS GENERATED. ! THE DIFFERENCE BETWEEN GMA AND GMA8 IS ONLY ! THAT GMA8 GENERATES THE ADDRESS OF THE HIGH ! BYTE OF THE WORD. ! ! 4. MOVE GENERATION ! THESE ROUTINES, PRIMARILY 'SIMPLEMOVE' AND ! 'GENMOVE', ARE SERVICE ROUTINE WHICH WILL ! GENERATE A DATA MOVE -- IF (AND ONLY IF) ! ONE IS ACTUALLY REQUIRED. SIMPLEMOVE ALWAYS ! MOVES AN ENTIRE WORD. GENMOVE WILL MOVE AN ! ARBITRARY FIELD OF ONE WORD TO AN ARBITRARY ! FIELD OF ANOTHER WORD. GENMOVE MAKES EXTENSIVE ! USE OF THE FIELD-ISOLATION AND ALIGNMENT ! ROUTINES -- SEE BELOW. ! ! 5. FIELD ISOLATION AND ALIGNMENT ! THIS SET OF ROUTINES PROVIDES THE PRIMITIVES ! FOR ISOLATING AN ARBITRARY SUBFIELD OF A ! WORD AND ALIGNING THE FIELD TO AN ARBITRARY ! POSITION IN THE WORD. ! ! 6. COMPARISON GENERATION ! THIS SET OF SERVICE ROUTINES GENERATES ! COMPARISONS BETWEEN ARBITRARY OPERANDS, WHICH ! IN PARTICULAR MAY BE SUBFIELDS OF A WORD, AND ! GENERATES BRANCHES TO SPECIFIED LABELS. THIS ! IS IN GENERAL A SIMPLE TASK, BUT THE SPECIAL ! CASE ANALYSIS IS ESPECIALLY EXTENSIVE HERE. ! ! 7. NODE-SPECIFIC ROUTINES ! CODE GENERATION IS EFFECTED BY AN EXECUTION-ORDER ! TREE WALK AND CALLING NODE-SPECIFIC ROUTINES ! AT EACH NODE. THESE ROUTINES ACTUALLY CONTROL ! THE CODE TO BE GENERATED FOR EACH NODE. THIS ! SECTION CONTAINS THESE ROUTINES. A GOOD EXAMPLE ! OF THE SPECIAL CASE ANALYSIS DONE BY THESE ! ROUTINES MAY BE FOUND BY LOOKING AT 'GID' WHICH ! GENERATES THE CODE FOR INCR/DECR STATEMENTS. ! ! 8. CODE & FREEUNDER ! THE SWITCHING TO THE NODE-SPECIFIC ROUTINES ! IS DONE HERE, AS ELSEWHERE IN THE COMPILER, ! BY SWITCHING THROUGH A 'PLIT'. THE ROUTINE ! 'CODE' ACTS AS THE CENTRAL SWITCHING AGENT. ! AS EACH NODE IS COMPLETED BY CODE THE ROUTINE ! 'FREEUNDER' IS CALLED BY IT TO RELEASE THE ! SPACE FOR THAT PORTION OF THE TREE WHICH IS ! NO LONGER NEEDED. THUS THE SPACE CONSUMED BY ! THE EMITTED CODE IS LARGELY THAT ! RELEASED FROM THE TREE. ! ! 9. CODEDRIVER ! THIS ROUTINE IS CALLED FROM 'GENIT' IN ! DRIVER TO INITIATE THE CODE GENERATION PROCESS. ! IT DOES THE NECESSARY INITIALIZATION AND ! CLEAN-UP. ! SWITCHES NOLIST; REQUIRE COMMON.BEG; REQUIRE PREDEF.BEG; REQUIRE IOMACS.BEG; REQUIRE GTST.BEG; REQUIRE ST.BEG; REQUIRE GTX.BEG; REQUIRE LDSF1.BEG; REQUIRE DTC.BEG; REQUIRE TN.BEG; REQUIRE JBEG.BEG; SWITCHES LIST; BEGIN ! MISC. EXTERNALS FOR CODE ONLY EXTERNAL BRAK1, ! (POINTER TO) FIRST CODE CELL CODENAME, ! 5 WORDS DESCRIBING CURRENT ROUTINE (MODULE) DYTEMPS, ! HEIGHT OF SIMULATED RUN-TIME STACK LNKTYPE, ! LINKAGE TYPE SET BY GCALL, SIGNAL TO CKREGSCHNGD LOC, ! USED TO SET 'MINLOCF' FIELDS ! (PROBABLY NOT NEEDED AT THIS STAGE) STVEC NCELL, ! LATEST CODE/LABEL CELL NLHEAD, ! LIST OF "NAMES" USED BY GMA NODVT, ! GTR 0 IF DYTEMPS MAY NOT BE USED AS VERYTEMPS NOVTCNT, ! GTR 0 IF -(SP) MAY NOT BE USED AS VERYTEMP PLSTCNT, ! GTR 0 IF FREEUNDER MUST NOT FREE SPACE REGSCHNGD, ! BIT MASK OF REGISTER WHOSE CONTENTS HAVE BEEN ! (POTENTIALLY) ALTERED BY EMITTED CODE SAMETOG, ! GTR 0 IF GMA MAY NOT EMIT CODE SIGLAB, ! LABEL OF 1ST EMITTED JUMP TO $SIGNL STATICSIZE, ! SET BY TNBIND; NUMBER OF STATIC TEMPS VTEMPS, ! STACK OF VTEMP LISTS VTN; ! NODE CURRENTLY BEING CODED (SET BY CODE; ! SIGNAL TO MAKEPUSHVT) MACRO ACCUM1=0,0,36$, ACCUM2=1,0,36$; STRUCTURE VECTOR[I] = [I] (.VECTOR + .I)<0,36>; STRUCTURE ADRWD[P,S] = .ADRWD<.P,.S>; EXTERNAL AFTER, ! FROM FINAL ALTERSRCDST, OPBYTES, OPERTYPE, GETCELL, ! FROM THE LOW SEGMENT GETTN, NEWCODECELL, NEWLABCELL, PUSHBOT, PUSHTOP; ! TEMP CODE PRINT FOR DEBUG !-------------------------- ROUTINE OCODE(OP,S,D)= BEGIN BIND PDP11PRT=PLIT( '; UUO', 'MOV','MOVB','CMP','CMPB','BIT','BITB', 'BIC','BICB','BIS','BISB','ADD','SUB', 'CLR','CLRB','COM','COMB','INC','INCB', 'DEC','DECB','NEG','NEGB','ADC','ADCB', 'SBC','SBCB','TST','TSTB','ROR','RORB', 'ROL','ROLB','ASR','ASRB','ASL','ASLB', 'JMP','SWAB','JSR','RTS','HALT','WAIT', 'RTI','IOT','RESET','EMT','TRAP', 'BR','NBR','BNE','BEQ','BGE','BLT','BLE','BGT', 'BPL','BMI','BHI','BLOS','BVC','BVS','BHIS','BLO', 'NOP','CLC','CLVC','.WORD','.CASE', 'MFPI','MFPD','MTPI','MTPD'); BIND REGNAMES=PLIT( 'R$0', 'R$1', 'R$2', 'R$3', 'R$4', 'R$5', 'SP', 'PC'); ROUTINE OADR(A)= BEGIN MACRO R=18,3$, M=21,3$, OFS=0,18$; OUTPUT(" ");OUTPXLIM(REGNAMES[.A],3);OUTPUT(":"); OUTDEC(.A,1);OUTPUT(":");OUTDEC(.A,6); END; CRLF;TAB;OUTPXLIM(PDP11PRT[.OP],5);TAB; OADR(.S);OUTPUT(",");OADR(.D);CRLF END; ROUTINE OLAB(L)= BEGIN CRLF;OUTPUT("L");OUTDEC(.L,6);OUTPUT(":");CRLF; END; ! LABEL HANDLING ! -------------- ROUTINE GENLABEL=NEWLABCELL(LABNAME(COMPLABT,GETLABEL())); ROUTINE PLACELABEL(LAB)= BEGIN NCELL_AFTER(.NCELL,.LAB); NCELL[MINLOCF]_.LOC END; ROUTINE REFLABEL(LAB,FRM,OTYPE)= BEGIN LOCAL GTVEC REF; REF_GETCELL(REFCELLT,REFCELLSIZE); REF[REFEF]_.LAB; REF[REFRF]_.FRM; REF[OPTYPEF]_.OTYPE; PUSHBOT(.REF[REFEF],.REF); BUILDOPD(LABELTYPE,RELATIVE,PC,.REF) END; ROUTINE IMMLAB(LAB,FRM,OTYPE)= BEGIN LOCAL GTVEC REF; REF_GETCELL(REFCELLT,REFCELLSIZE); REF[REFEF]_.LAB; REF[REFRF]_.FRM; REF[OPTYPEF]_.OTYPE; PUSHBOT(.REF[REFEF],.REF); BUILDOPD(LABELTYPE,IMMEDIATE,PC,.REF) END; ROUTINE NODELABEL(NODE)= BEGIN MAP GTVEC NODE; IF .NODE[LABELF] EQL 0 THEN NODE[LABELF]_NEWLABCELL(LABNAME(COMPLABT,GETLABEL())); .NODE[LABELF] END; ROUTINE USERLABEL(LABST)= BEGIN MAP STVEC LABST; IF .LABST[LABCELLF] EQL 0 THEN LABST[LABCELLF]_NEWLABCELL(LABNAME(USERLABT,.LABST)); .LABST[LABCELLF] END; ! LIST-OF-NAME-DESCRIPTORS HANDLING ! ----------------------------------- ROUTINE SEARCHLL(HEAD,LAB)= BEGIN MAP STVEC HEAD; REGISTER STVEC PTR; PTR_.HEAD[PREVF]; WHILE .LAB LSS .PTR[LABNAMF] DO PTR_.PTR[PREVF]; IF .LAB EQL .PTR[LABNAMF] THEN .PTR ELSE AFTER(.PTR,NEWLABCELL(.LAB)) END; ! EMIT CODE INTO INSTRUCTION STREAM ! --------------------------------- ROUTINE PUTADR(XADR,XA,BYTES) = BEGIN REGISTER STVEC ADR,ADRWD A; BIND ADRVARSTR IMMEDZERO = ADRPLIT(#12,7,IMMEDAT,NORMNAME,0); BIND NORMALVEC ADRTYPE = PLIT (REGAT,MEMAT,MEMAT,INDAT,MEMAT,INDAT,MEMAT,INDAT, UNUSED,UNUSED,IMMEDAT,MEMAT,UNUSED,UNUSED,MEMAT,INDAT); ADR_.XADR; A_.XA; COPYADR(.ADR,IMMEDZERO); IF (.A[OPDREGF] EQL 6) OR .A[OPDMODEF] THEN BYTES_2; ADR[AFORM]_.A[OPDMODEF]; IF .A[OPDREGF] EQL 7 THEN ADR[AFORM]_.ADR[AFORM]+8 ELSE ADR[AREG]_.A[OPDREGF]; IF ONEOF(.ADR[AFORM],BIT6(6,7,#12,#13,#16,#17)) THEN SELECT .A[OPDTYPEF] OF NSET NORMALT: (ADR[AOFFSET]_.A[OPDF]; IF .A<17,1> THEN ADR[ANAMET]_FORMALNAME; EXITSELECT); NAMET: (ADR[AOFFSET]_.ST[.A[OPDF],SYMOFFSETF]; ADR[ANAME]_.ST[.A[OPDF],SYMNAMEF]; EXITSELECT); LABELTYPE: (ADR[ANAMET]_LABELNAME; ADR[ANAME]_.A[OPDF]; EXITSELECT); ERRORT: (ADR[ANAMET]_ERRORNAME; ADR[AOFFSET]_.A[OPDF]) TESN; IF .ADR[AREG] EQL SP AND .ADR[ANAME] EQL 0 AND .ADR[AFORM] NEQ 0 THEN ADR[ANAME]_1; IF ONEOF(.ADR[AFORM],BIT2(2,3)) THEN BEGIN ADR[AOFFSET]_-.BYTES; ADR[ADELTA]_.BYTES; END ELSF ONEOF(.ADR[AFORM],BIT2(4,5)) THEN ADR[ADELTA]_-.BYTES; ADR[ATYPE]_.ADRTYPE[.ADR[AFORM]] END; ROUTINE CKREGSCHNGD(OP,S,D)= BEGIN MACRO NOTER(X)=REGSCHNGD<.X[OPDREGF],1>_TRUE$, NOTEZ=REGSCHNGD<0,1>_TRUE$; MACRO RS(X)= IF .X[OPDMODEF] EQL GENREG THEN NOTER(X)$, CR(X)= IF ONEOF(.X[OPDMODEF],BIT4(AUTOINCR,AUTOINCR+DEFERRED, AUTODECR,AUTODECR+DEFERRED)) THEN NOTER(X)$; MAP ADRWD S:D; CASE .OPERTYPE[.OP] OF SET % NOOP % IF .OP EQL PIOT THEN NOTEZ; % ONEOP % (IF .ALTERSRCDST[.OP] THEN RS(S); CR(S)); % TWOOP % (CR(D); IF .ALTERSRCDST[.OP] THEN RS(D); CR(S)); % BROP % CR(S); % JSROP % (CR(D); NOTEZ; IF .LNKTYPE NEQ HBLISLNKGT THEN RS(S)); % RTSOP % RS(S); % TRAPOP % NOTEZ; % WORDOP,CASEOP % 0; 0 TES; END; ROUTINE PUTCODE(WHERE,OPT,OP,S,D)= BEGIN LOCAL BYTES; MAP ADRWD S:D; ROUTINE DUMMY=.VREG; DUMMY(.OP,.S,.D); !!!!!!!DEBUG CKREGSCHNGD(.OP,.S,.D); NCELL_AFTER(.NCELL,.WHERE); NCELL[MINLOCF]_LOC_.LOC+1; NCELL[OPTYPEF]_.OPT; NCELL[OPF]_.OP; BYTES_.OPBYTES[.OP]; IF HASSOURCE(.OP) THEN PUTADR(SRCP(.NCELL),.S,.BYTES); IF HASDEST(.OP) THEN PUTADR(DSTP(.NCELL),.D,.BYTES); CASE .OPERTYPE[.OP] OF SET IF .OP EQL PINLINE THEN NCELL[INLNARG]_.S; 0; 0; 0; NCELL[SRCREG]_.S[OPDREGF]; NCELL[SRCREG]_.S[OPDREGF]; NCELL[SRCOFFSET]_.S[OPDF]; IF .D THEN NCELL[HYDWORD]_TRUE; 0 TES; .NCELL END; BIND OPTYPLIT=PLIT ( INLINET, ! INLINE UNUSED, ! PMOV=1, UNUSED, ! PMOVB=2, UNUSED, ! PCMP=3, UNUSED, ! PCMPB=4, UNUSED, ! PBIT=5, UNUSED, ! PBITB=6, UNUSED, ! PBIC=7, UNUSED, ! PBICB=8, UNUSED, ! PBIS=9, UNUSED, ! PBISB=10, ADDIOPT, ! PADD=11, ADDIOPT, ! PSUB=12, UNUSED, ! PCLR=13, UNUSED, ! PCLRB=14, UNUSED, ! PCOM=15, UNUSED, ! PCOMB=16, UNUSED, ! PINC=17, UNUSED, ! PINCB=18, UNUSED, ! PDEC=19, UNUSED, ! PDECB=20, UNUSED, ! PNEG=21, UNUSED, ! PNEGB=22, UNUSED, ! PADC=23, UNUSED, ! PADCB=24, UNUSED, ! PSBC=25, UNUSED, ! PSBCB=26, UNUSED, ! PTST=27, UNUSED, ! PTSTB=28, UNUSED, ! PROR=29, UNUSED, ! PRORB=30, UNUSED, ! PROL=31, UNUSED, ! PROLB=32, UNUSED, ! PASR=33, UNUSED, ! PASRB=34, UNUSED, ! PASL=35, UNUSED, ! PASLB=36, UNUSED, ! PJMP=37, UNUSED, ! PSWAB=38, UNUSED, ! PJSR=39, UNUSED, ! PRTS=40, UNUSED, ! PHALT=41, UNUSED, ! PWAIT=42, UNUSED, ! PRTI=43, UNUSED, ! PIOT=44, UNUSED, ! PRESET=45, UNUSED, ! PEMT=46, UNUSED, ! PTRAP=47, UNCONDJMPT, ! PBR=48, UNCONDJMPT, ! PNBR=49, CONDJMPT, ! PBNE=50, CONDJMPT, ! PBEQ=51, CONDJMPT, ! PBGE=52, CONDJMPT, ! PBLT=53, CONDJMPT, ! PBLE=54, CONDJMPT, ! PBGT=55, CONDJMPT, ! PBPL=56, CONDJMPT, ! PBMI=57, CONDJMPT, ! PBHI=58, CONDJMPT, ! PBLOS=59, CONDJMPT, ! PBVC=60, CONDJMPT, ! PBVS=61, CONDJMPT, ! PBHIS=62, CONDJMPT, ! PBLO=63, UNUSED, ! PNOP=64, UNUSED, ! PCLC=65, UNUSED, ! PCLVC=66, UNUSED, ! PWORD=67, CASPARAMT, ! PCASE=68, UNUSED, ! PMFPI=69, UNUSED, ! PMFPD=70, UNUSED, ! PMTPI=71, UNUSED ! PMTPD=72, ); ROUTINE ISLIT(L)= BEGIN MAP LEXEME L; BIND GTVEC N=L; IF .L[LTYPF] EQL LITTYP THEN RETURN .L[IMMF] ELSE IF .N[TYPEF] NEQ GRAPHT THEN RETURN 0 ELSE IF .L[SLF] THEN RETURN .L[IMMF] ELSE RETURN 0 END; ROUTINE CLITVALUE(L)= BEGIN MAP LEXEME L; BIND GTVEC N=L; IF .L[LTYPF] EQL LITTYP THEN LITVALUE(.L) ELSE LITVALUE(.N[OFFSETF]) END; MACRO ISZERO(L)= (ISLIT(L) AND CLITVALUE(L) EQL 0)$; ROUTINE ISIMMEDIATE(ADR)= BEGIN BIND X=(BUILDOPD(NORMALT,IMMEDIATE,PC,0)^(-18)); .ADR<18,18> EQL X END; ROUTINE EMIT(OP,S,D)= BEGIN LOCAL CELL,TYPE; CELL_NEWCODECELL(); CASE (TYPE_.OPTYPLIT[.OP]) OF SET % 0 - UNUSED % IF .OP EQL PJMP THEN TYPE_UNCONDJMPT; % 1 - CASEPARAMT % (D_REFLABEL(.D,.CELL,.TYPE); S_REFLABEL(.S,.CELL,.TYPE)); % 2 - INLINET % 0; % 3 - UNCONDJMPT % S_REFLABEL(.S,.CELL,.TYPE); % 4 - ADDIOPT % IF NOT ISIMMEDIATE(.S) THEN TYPE_UNUSED; % 5 - CONDJMPT % S_REFLABEL(.S,.CELL,.TYPE) TES; PUTCODE(.CELL,.TYPE,.OP,.S,.D) END; ROUTINE NOTECODE=.NCELL; ROUTINE ANYCODESINCE(C)=.C NEQ .NCELL; ! GET HIGHLY TEMPORARY CELLS WITHIN A NODE LIFE ! --------------------------------------------- EXTERNAL ! FROM TRY.BLI TRYFIT, OPENLIST, TRYOPREG, TRYCLREG, TRYSPDYTEMP, TRYDYTEMPS, TRYOPSTEMPS; REQUIRE TRY.BEG; MAP GTVEC VTN, PLSTSTK VTEMPS; MACRO ISOKPUSHVT=(.NOVTCNT EQL 0)$, OKTOPDYTEMP=(.NODVT EQL 0 AND .DYTEMPS GEQ 2)$, OKALLDYTMPS=(.NODVT EQL 0 AND .DYTEMPS GEQ 4)$; MACRO SETNOPUSHVT=NOVTCNT_.NOVTCNT+1$, RESETPUSHVT=NOVTCNT_.NOVTCNT-1$, SETNODYNVT=NODVT_.NODVT+1$, RESETDYNVT=NODVT_.NODVT-1$; ROUTINE TRYOPVTEMPS(T)= BEGIN ! TRY THE OPEN VERY TEMPS INCR I FROM 0 TO .VTEMPS[CURD] DO IF TRYFIT(.T,VTEMPS[LSELEM(.I)]<0,0>) THEN SUCCESS; FAIL END; MACRO RLINK = 1,0,0,18 $; ! COPIED FROM FLOW.BEG ROUTINE TRYCLVTEMPS(T)= BEGIN ! OPEN A NEW VERY TEMP LOCAL GTVEC TX; PUSHSTK(VTEMPS); OPENLIST(VTEMPS[TOS]); TRYFIT(.T,VTEMPS[TOS]<0,0>); ! NOTE THIS WILL (SHOULD) ALWAYS WORK FORALLTN(TX,VTEMPS[TOS], (TX[BNDTYP]_BNDLOCAL; TX[REGF]_SP; TX[MODE]_INDEXED; TX[OFFSETF]_.VTEMPS[CURD]*2)) END; ROUTINE COPYTNDATA(TN)= BEGIN MACRO COPYF(FLD)=TN[FLD]_.L[REPFLD(FLD)]$; MAP GTVEC TN; LOCAL TNREPR L; L_.TN[BNDLSTHDR]; L_.L[RLINK]; COPYF(BNDTYP); COPYF(REGF); COPYF(OFFSETF); COPYF(MODE); END; ROUTINE MARKANDCOPY(TN)= BEGIN MAP GTVEC TN; LOCAL TNREPR LST:L, N; LST_.TN[BNDLSTHDR]; N_.LST-REGS[0]<0,0>; L_.LST[RLINK]; L[REPFLD(BNDTYP)]_BNDREG; L[REPFLD(REGF)]_.N; COPYTNDATA(.TN) END; ROUTINE MAKEPUSHVT(T)= BEGIN MAP GTVEC T; IF .VTN[DTDELETE] EQL DTDONTCARE THEN VTN[DTDELETE]_.DYTEMPS; T[BNDTYP]_BNDPUSH; T[REGF]_SP; T[MODE]_INDEXED; T[OFFSETF]_-(.MAXLOCALS+.STATICSIZE+.DYTEMPS+2) END; ROUTINE VERYTEMP(X)= BEGIN REGISTER GTVEC T; MAP GTVEC X; T_GETTN(); T[LONFU]_T[LONLU]_.LON; T[FONFU]_T[FONLU]_.FON; SELECT TRUE OF NSET IF .X GEQ 8 THEN IF .X[BNDLSTHDR] NEQ 0 THEN TRYFIT(.T,.X[BNDLSTHDR]): EXITSELECT COPYTNDATA(.T); TRYOPREG(.T): EXITSELECT COPYTNDATA(.T); IF OKTOPDYTEMP THEN TRYSPDYTEMP(.T,(.DYTEMPS-2)/2): EXITSELECT COPYTNDATA(.T); ISOKPUSHVT: EXITSELECT MAKEPUSHVT(.T); IF OKALLDYTMPS THEN TRYDYTEMPS(.T): EXITSELECT COPYTNDATA(.T); TRYOPSTEMPS(.T): EXITSELECT COPYTNDATA(.T); TRYCLREG(.T): EXITSELECT MARKANDCOPY(.T); TRYOPVTEMPS(.T): EXITSELECT COPYTNDATA(.T); ALWAYS: TRYCLVTEMPS(.T) TESN; RETURN .T END; ROUTINE VERYTMPREG= BEGIN REGISTER GTVEC T; T_GETTN(); T[LONFU]_T[LONLU]_.LON; T[FONFU]_T[FONLU]_.FON; SELECT TRUE OF NSET TRYOPREG(.T): EXITSELECT COPYTNDATA(.T); IF OKTOPDYTEMP THEN TRYSPDYTEMP(.T,(.DYTEMPS-2)/2): EXITSELECT COPYTNDATA(.T); ISOKPUSHVT: EXITSELECT MAKEPUSHVT(.T); ALWAYS: T_0 TESN; RETURN .T END; ! ROUTINES TO HANDLE GENERATION OF MACHINE ADDRESSING FORMATS ! ------------------------------------------------------------ MACRO ALOCAL(X)=BUILDOPD(NORMALT,INDEXED,SP,XLO(X))$, DEFER(Z)=((Z) OR ((DEFERRED)^POSMODEF))$, INDEXEDBY(R,X,T)=BUILDOPD(T,INDEXED,REGNUM(R),X)$, LOCALOFFSET(ZZZ)=(((.MAXLOCALS+.STATICSIZE+.DYTEMPS)+.ZZZ[OFFSETF])AND #177777)$, MAKLIT(L)= (LITLEXEME((L) AND #177777)+LITK+IMMK)$, MAKNAM(N)= (LEXOUT(0,N)+LITK+IMMK)$, MAKNAMDESC(Z1,Z2)=((Z1)^18+((Z2)AND#177777))$, MAX(A,B)=(IF(A) GTR (B) THEN (A) ELSE (B))$, MIN(A,B)=(IF(A) LSS (B) THEN (A) ELSE (B))$, NODEFER(Z)=((Z) AND (NOT((DEFERRED)^POSMODEF)))$, NXTBYTEADR(A)=BUMPBYTEADR(A,1)$, PROGCTR=BUILDOPD(NORMALT,GENREG,PC,UNUSED)$, PUSHED=BUILDOPD(NORMALT,AUTODECR,SP,UNUSED)$, POPPED=BUILDOPD(NORMALT,AUTOINCR,SP,UNUSED)$, REG1=XREG(1)$, REG5=XREG(5)$, REGZERO=XREG(0)$, RO= RETURN BUILDOPD$, STACKPTR=BUILDOPD(NORMALT,GENREG,SP,UNUSED)$, XLO(X)=(((.MAXLOCALS+.STATICSIZE+.DYTEMPS)+X) AND #177777)$, XREG(X)=BUILDOPD(NORMALT,GENREG,X,UNUSED)$, XTOS=BUILDOPD(NORMALT,DEFERRED,SP,UNUSED)$, ZPOPPED=BUILDOPD(NORMALT,AUTOINCR,0,UNUSED)$; FORWARD GMA, ISREG, NOMOVREQD, REGNUM; BIND FORMALK=1^17; BIND IMMK=1^23; ROUTINE NAMEDESC(N)= BEGIN MAP STVEC N; LOCAL L, STVEC B; B_BASESYM(.N); L_.N[OFFSETF]-.B[OFFSETF]; SEARCHLL(.NLHEAD,MAKNAMDESC(.B,.L)) END; ROUTINE BUMPNAMEDESC(D,N)= BEGIN D_@(.D+1); SEARCHLL(.NLHEAD,MAKNAMDESC(.D<18,18>,.D<0,18>+.N)) END; ROUTINE BUMPBYTEADR(ADR,N)= BEGIN MAP ADRWD ADR; CASE .ADR[OPDMODEF] OF SET PUNT(581); (ADR[OPDMODEF]_INDEXED; ADR[OPDF]_.N); ADR[OPDF]_IF .ADR[OPDTYPEF] EQL NORMALT THEN .ADR[OPDF]+.N ELSE BUMPNAMEDESC(.ADR[OPDF],.N); ADR[OPDF]_IF .ADR[OPDTYPEF] EQL NORMALT THEN .ADR[OPDF]+.N ELSE BUMPNAMEDESC(.ADR[OPDF],.N); PUNT(581); PUNT(581); ADR[OPDF]_IF .ADR[OPDTYPEF] EQL NORMALT THEN .ADR[OPDF]+.N ELSE BUMPNAMEDESC(.ADR[OPDF],.N); ADR[OPDF]_IF .ADR[OPDTYPEF] NEQ NORMALT THEN BUMPNAMEDESC(.ADR[OPDF],.N) ELSE BEGIN LOCAL GTVEC T; T_VERYTEMP(0); EMIT(PMOV,NODEFER(.ADR),GMA(.T)); IF ISREG(.T) THEN RO(NORMALT,INDEXED,REGNUM(.T),.N); EMIT(PADD,GMA(MAKLIT(.N)),GMA(.T)); RETURN DEFER(GMA(.T)); END; TES; .ADR END; ROUTINE ISIDT(N)= BEGIN MAP GTVEC N; BIND LEXEME L=N; IF .L[LTYPF] EQL GRAPHT THEN .N[NIDTF] ELSE 0 END; %< ROUTINE ISSIMPSTOR(O1,O2)= BEGIN MAP GTVEC O1:O2; LOCAL GTVEC T; IF (T_.O2[REGF]) LSS 8 THEN 0 ELSE IF .T[TYPEF] NEQ TEMPNAMET THEN 0 ELSE (.T[REGF] EQL (#777777 AND .O1)) END; ! ONLY CALLED FROM THE NOW-DEFUNCT ISSIMPLEOPND. >% ROUTINE FORGOTTEN(NODE,OP1)= BEGIN MAP GTVEC NODE,LEXEME OP1; BIND GTVEC GTOP1=OP1; LOCAL GTVEC TN; IF (TN_.NODE[REGF]) LSS 8 THEN RETURN 0; IF .TN[BNDTYP] EQL BNDNCSE THEN RETURN 1; IF .TN[REQD] NEQ MEMREQDB THEN RETURN 0; IF .TN[REGF] EQL .OP1[ADDRF] THEN RETURN 1; IF .OP1[LTYPF] NEQ GTTYP THEN RETURN 0; FORGOTTEN(.OP1,.GTOP1[OPR1]) END; %< ROUTINE ISSIMPLEOPND(LEX)= BEGIN MAP LEXEME LEX; BIND GTVEC NODE=LEX; MACRO LASTOPND=OPERAND(.NODE[NODESIZEF]-1)$;; CASE .LEX[LTYPF] OF SET 0; 1; !LITTYP 1; !BNDVAR IF .NODE[LISTBIT] THEN 1 !GTTYP ELSE IF .NODE[NODESIZEF] EQL 0 THEN 1 ELSE SELECT .NODE[NODEX] OF NSET SPLUSOP: FORGOTTEN(.NODE,.NODE[OPR1]); SDOTOP: IF .NODE[MODE] THEN 1 ELSE IF .NODE[MODE] EQL INDEXED THEN 1 ELSE ISSIMPLEOPND(.NODE[OPR1]); SADDOP: IF .NODE[ADDCOPIED] THEN ISSIMPLEOPND(.NODE[OPR1]); SMINOP: IF .NODE[ADDCOPIED] THEN ISSIMPLEOPND(.NODE[OPR1]); SFSTORE: 1; SYNPOI: IF .LEX[SSPF] LEQ PF016 THEN ISSIMPLEOPND(.NODE[OPR1]) ELSE 1; SSTOROP: (LOCAL O1,O2; IF .NODE[TPATH] THEN (O1_.NODE[OPR2];O2_.NODE[OPR1]) ELSE (O1_.NODE[OPR1];O2_.NODE[OPR2]); IF ISSIMPSTOR(.O1,.O2) THEN 0 ELSE NOMOVREQD(.O1,.O2) AND ISSIMPLEOPND(.O2)); SYNIF: ISSIMPLEOPND(.NODE[OPR3]) OR ISSIMPLEOPND(.NODE[OPR4]) OR NOT EMPTY(.NODE[LASTOPND]); SYNCASE: (INCR I FROM 2 TO .NODE[NODESIZEF]-2 DO IF ISSIMPLEOPND(.NODE[OPERAND(.I)]) THEN RETURN 1; RETURN NOT EMPTY(.NODE[LASTOPND])); SYNSEL: 1; SYNCOMP: ISSIMPLEOPND(.NODE[LASTOPND]); OTHERWISE: 0 TESN TES END; >% ! SEE LITCOMPARE; FINAL NOW DOES TST ELIMINATION. ROUTINE ISDESTROYABLE(N)= BEGIN MAP GTVEC N; BIND LEXEME L=N; IF .L[LTYPF] EQL GTTYP THEN .N[NIDTF] AND .N[MODE] EQL GENREG ELSE IF .L[LTYPF] EQL LITTYP THEN 0 ELSE IF .N[TYPEF] EQL TEMPNAMET THEN (.N[LONLU] LEQ .LON AND .N[FONLU] LEQ .FON) ELSE 0 END; ROUTINE ISREG(R)= BEGIN MAP GTVEC R; BIND LEXEME LEXR=R; IF .LEXR[LTYPF] EQL LITTYP THEN RETURN 0; IF .LEXR[LEXPART] LSS 8 THEN RETURN 1; SELECT .R[TYPEF] OF NSET REGT: RETURN 1; LOCALT: IF .R[REGF] LSS 8 THEN RETURN 0 ELSE RETURN ISREG(.R[REGF]); TEMPNAMET: BEGIN IF .R[BNDTYP] EQL BNDREG THEN RETURN 1; IF .R[REQD] EQL MEMREQDB THEN IF .R[BNDTYP] EQL 0 OR .R[BNDTYP] EQL BNDPREF THEN IF NOT .R[TNLITBIT] THEN RETURN ISREG(.R[REGF]); RETURN 0 END; GRAPHT: IF .R[MODE] EQL GENREG THEN RETURN ISREG(.R[REGF]); ALWAYS: RETURN 0 TESN END; ROUTINE REGNUM(R)= BEGIN MAP GTVEC R; IF .R LEQ 7 THEN .R ELSE REGNUM(.R[REGF]) END; ROUTINE LOCDEF(NODE)= BEGIN MAP GTVEC NODE; WHILE .NODE[REGF] GTR 8 DO NODE_.NODE[REGF]; .NODE END; ROUTINE LOCDF1(NODE)= BEGIN MAP GTVEC NODE; WHILE BEGIN IF .NODE[TYPEF] EQL TEMPNAMET THEN IF .NODE[TNLITBIT] THEN RETURN .NODE[TNLITLEX]; .NODE[REGF] GTR 8 END DO NODE_.NODE[REGF]; .NODE END; ROUTINE GETOFFSET(NODE)= BEGIN MAP GTVEC NODE; IF NOT(.NODE[SYMOFFF]) THEN LITVALUE(.NODE[OFFSETF]) ELSE BEGIN LOCAL STVEC S; S_ .NODE[OFFSETF]; IF .S[TYPEF] EQL LOCALT THEN LOCALOFFSET(S) ELSE IF .S[TYPEF] EQL FORMALT THEN (LOCALOFFSET(S)+FORMALK) ELSE NAMEDESC(.NODE[OFFSETF]) END END; ROUTINE ISCHEAP(NODE)= BEGIN MAP GTVEC NODE; BIND LEXEME LEX=NODE; IF ISREG(.NODE) THEN RETURN 1; NODE_LOCDF1(.NODE); IF .LEX[LTYPF] EQL LITTYP THEN RETURN 0; IF ISSTVAR(NODE) THEN IF .NODE[MODE] NEQ GENREG THEN RETURN 0; NODE_LOCALOFFSET(NODE); .NODE EQL 0 OR .NODE EQL 1^16-2 END; ROUTINE GMOFF(NODE)= BEGIN MAP GTVEC NODE; IF .NODE[SYMOFFF] THEN RETURN GMA(MAKNAM(.NODE[OFFSETF])) ELSE RO(NORMALT,IMMEDIATE,PC,LITVALUE(.NODE[OFFSETF])); END; ROUTINE GMA(LEX)= BEGIN MAP LEXEME LEX; BIND GTVEC NODE=LEX; LOCAL GTVEC S,L,T; ! IF NAMING A REGISTER IF .LEX GEQ 0 THEN IF .LEX LSS 8 THEN RO(NORMALT,GENREG,.LEX,0); ! NOW HANDLE LITERAL LEXEMES IF .LEX[LTYPF] EQL LITTYP THEN IF .LEX[IMMF] THEN RO(NORMALT,IMMEDIATE,PC,CLITVALUE(.LEX)) ELSE RO(NORMALT,ABSOLUTE,PC,CLITVALUE(.LEX)); ! IN ALL REMAINING CASES WE USE THE TYPE FIELD IN THE NODE IF .NODE[TYPEF] EQL TEMPNAMET THEN BEGIN IF .NODE[BNDTYP] EQL BNDPUSH THEN IF LOCALOFFSET(NODE) GTR 1^15 %LSS 0% THEN (DYTEMPS_.DYTEMPS+2;RETURN PUSHED) ELSE RO(NORMALT,INDEXED,SP,LOCALOFFSET(NODE)); IF .NODE[REQD] EQL MEMREQDB THEN IF .NODE[BNDTYP] EQL 0 OR .NODE[BNDTYP] EQL BNDPREF THEN IF .NODE[TNLITBIT] THEN RETURN GMA(.NODE[TNLITLEX]) ELSE RETURN GMA(LEXOUT(.LEX[LEFTPART],.NODE[REGF])); IF .NODE[BNDTYP] EQL BNDREG THEN RO(NORMALT,GENREG,.NODE[REGF],0); RO(NORMALT,.NODE[MODE],.NODE[REGF],LOCALOFFSET(NODE)); END; ! GRAPH TABLE CASES IF .NODE[TYPEF] EQL GRAPHT THEN BEGIN REGISTER NMODE,O,TY; IF .LEX[SLF] THEN IF .LEX[IMMF] THEN RO(IF .NODE[SYMOFFF] THEN NAMET ELSE NORMALT,IMMEDIATE,PC,GETOFFSET(.NODE)) ELSE RO(NORMALT,ABSOLUTE,PC,.NODE[OFFSETF]); NMODE_.NODE[MODE]; IF .NMODE EQL GENREG THEN RETURN GMA(.NODE[REGF]); IF .NMODE EQL (GENREG+DEFERRED) THEN RETURN DEFER(GMA(.NODE[REGF])); O_GETOFFSET(.NODE); TY_IF NOT(.NODE[SYMOFFF]) THEN NORMALT ELSE BEGIN S_.NODE[OFFSETF]; IF ONEOF(.S[TYPEF],BIT2(LOCALT,FORMALT)) THEN NORMALT ELSE NAMET END; IF .NMODE EQL IMMEDIATE OR .NMODE EQL ABSOLUTE THEN RO(.TY, IF .NODE[NIMMF] THEN IMMEDIATE ELSE .NMODE, REGNUM(.NODE[REGF]), .O); IF .NMODE EQL INDEXED OR .NMODE EQL (INDEXED+DEFERRED) THEN BEGIN LOCAL GTVEC TN; TN_.NODE[REGF]; IF .LEX[IMMF] THEN RETURN GMA(.TN); IF .TN[BNDTYP] EQL BNDNCSE THEN BEGIN T_GMA(LEXOUT(BNDVAR,.TN[REGF])); IF .NMODE EQL INDEXED THEN RETURN .T ELSE RETURN DEFER(.T); END; IF ISREG(.TN) THEN RO(.TY,.NMODE,REGNUM(.TN),.O) ELSE BEGIN IF .SAMETOG NEQ 0 THEN RETURN -(.TN^18+(3 AND .NMODE)^16+.O); T_VERYTEMP(0); EMIT(PMOV,GMA(.TN),GMA(.T)); IF ISREG(.T) THEN RO(.TY,.NMODE,REGNUM(.T),.O); EMIT(PADD,GMOFF(.NODE),GMA(.T)); IF .NMODE EQL (INDEXED+DEFERRED) THEN EMIT(PMOV,DEFER(GMA(.T)),GMA(.T)); RETURN DEFER(GMA(.T)); END; END; PUNT(580); ! ALL THE ALLOWED CASES SHOULD HAVE BEEN HANDLED END; ! SYMBOL TABLE CASES SELECT .NODE[TYPEF] OF NSET REGT: RETURN GMA(.NODE[REGF]); LOCALT: IF .NODE[REGF] GEQ 8 THEN RETURN GMA(.NODE[REGF]) ELSE RO(NORMALT,INDEXED,SP,LOCALOFFSET(NODE)); FORMALT: IF .NODE[REGF] GEQ 8 THEN RETURN GMA(.NODE[REGF]) ELSE RO(NORMALT,INDEXED,SP,FORMALK+LOCALOFFSET(NODE)); GLOBALT: (L_ IF .LEX[IMMF] THEN IMMEDIATE ELSE IF .PICSW THEN ABSOLUTE ELSE RELATIVE; RO(NAMET,.L,PC,NAMEDESC(.NODE))); EXTERNALT: (L_ IF .LEX[IMMF] THEN IMMEDIATE ELSE IF .PICSW THEN ABSOLUTE ELSE RELATIVE; RO(NAMET,.L,PC,NAMEDESC(.NODE))); ALWAYS: IF ONEOF(.NODE[TYPEF],BIT4(OWNT,ROUTINET,GROUTINET,FORWT)) THEN RO(NAMET, IF .LEX[IMMF] THEN IMMEDIATE ELSE RELATIVE, PC, NAMEDESC(.NODE)) TESN; PUNT(580) END; ! OF GMA ROUTINE GMA8(OPND)= BEGIN MAP GTVEC OPND; LOCAL X; X_GMA(.OPND); IF NOT ISLIT(.OPND) THEN IF .OPND[POSF] EQL 8 THEN X_NXTBYTEADR(.X); .X END; ! ROUTINES TO HANDLE GENERAL DATA MOVES ! ------------------------------------- FORWARD CLEARFIELD,MAKEDESTROYABLE,DIAL,ISMOVSELF, SHIFT,ISOLATE,MASK,GENBITTEST,POSITIONIT; MACRO PICK8(INSTR,POS,SIZ)= (IF (POS)+(SIZ) LEQ 8 THEN ID(INSTR)B ELSE INSTR) $; ROUTINE CK08(NODE)= BEGIN MAP GTVEC NODE; BIND LEXEME LEX=NODE; IF .LEX[LTYPF] EQL BNDVAR THEN BEGIN IF .NODE[POSF] EQL 0 THEN IF .NODE[SIZEF] EQL 8 THEN RETURN 1; RETURN 0; END; IF .LEX[LTYPF] NEQ GTTYP THEN RETURN 0; IF .NODE[POSF] LSS 8 THEN IF .NODE[POSF]+.NODE[SIZEF] LEQ 8 THEN RETURN 1; RETURN 0; END; MACRO CHECK08(NX)=CK08(NX)$; ROUTINE SIMPLEMOVE(O1,O2)= BEGIN MAP GTVEC O1:O2; LOCAL A1,A2; IF .O1 NEQ .O2 THEN IF (A1_GMA(.O1)) NEQ (A2_GMA(.O2)) THEN IF NOT ISMOVSELF(.A1,.A2) THEN IF CHECK08(.O1) THEN EMIT(PMOVB,.A1,.A2) ELSE IF CHECK08(.O2) THEN EMIT(PMOVB,.A1,.A2) ELSE EMIT(PMOV,.A1,.A2) END; ROUTINE ISMOVSELF(S,D)= BEGIN MACRO PCRETURN=RETURN .S[OPDREGF] EQL PC$, COMBINE(MODE1,MODE2)=(MODE1*8 + MODE2)$; MAP LEXEME S:D; IF .S EQL .D THEN RETURN 1; IF .S[OPDF] NEQ .D[OPDF] THEN RETURN 0; IF .S[OPDREGF] NEQ .D[OPDREGF] THEN RETURN 0; SELECT COMBINE(.S[OPDMODEF],.D[OPDMODEF]) OF NSET COMBINE(0,0): RETURN 1; COMBINE(1,1): RETURN 1; COMBINE(6,6): RETURN 1; COMBINE(7,7): RETURN 1; COMBINE(3,3): PCRETURN; COMBINE(6,3): PCRETURN; COMBINE(3,6): PCRETURN; OTHERWISE: RETURN 0 TESN; END; ROUTINE SAMEADDR(O1,O2)= BEGIN LOCAL SDTD; SDTD_.DYTEMPS; SAMETOG_.SAMETOG+1; O1_GMA(.O1); O2_GMA(.O2); DYTEMPS_.SDTD; SAMETOG_.SAMETOG-1; ISMOVSELF(.O1,.O2) END; ROUTINE SAMEWORD(O1,O2)= BEGIN LOCAL SDTD; SDTD_.DYTEMPS; SAMETOG_.SAMETOG+1; O1_GMA(.O1) AND (-2); O2_GMA(.O2) AND (-2); DYTEMPS_.SDTD; SAMETOG_.SAMETOG-1; ISMOVSELF(.O1,.O2) END; ROUTINE OVERLAP(P1,S1,P2,S2)= BEGIN S1_.S1+.P1; S2_.S2+.P2; .S2 GEQ .P1 AND .P2 LEQ .S1 END; ROUTINE REG8(R)= BEGIN MAP GTVEC R; IF .R[POSF] NEQ 8 THEN RETURN GMA(.R); R_MAKEDESTROYABLE(.R); IF ISREG(.R) THEN (EMIT(PSWAB,GMA(.R),0);GMA(.R)) ELSE NXTBYTEADR(GMA(.R)) END; ROUTINE NOMOVREQD(O1,O2)= BEGIN MAP LEXEME O1:O2; BIND GTVEC N1=O1:N2=O2; IF .O1[LTYPF] EQL LITTYP OR .O2[LTYPF] EQL LITTYP THEN RETURN .O1 EQL .O2; IF .O1[SSPF] NEQ .O2[SSPF] THEN IF .O1[SSPF]+.O2[SSPF] GTR PFNONE+PF016 THEN RETURN 0; RETURN SAMEADDR(.O1,.O2) END; ROUTINE DEPENDON(S,D)= BEGIN MAP GTVEC S:D; LOCAL RESULT,T,E; IF ISREG(.D) THEN REGNUM(.S) EQL REGNUM(.D) ELSE BEGIN LOCAL SDTD; SDTD_.DYTEMPS; SAMETOG_.SAMETOG+1; IF (T_GMA(.S)) LSS 0 THEN T_GMA(.S[REGF]); IF (E_GMA(.D)) LSS 0 THEN E_GMA(.D[REGF]); RESULT_(NODEFER(.T) AND (-2)) EQL (.E AND (-2)); DYTEMPS_.SDTD; SAMETOG_.SAMETOG-1; .RESULT END END; ROUTINE GENMOVE(O1,O2)= BEGIN MAP LEXEME O1:O2; LOCAL P1,P2; BIND GTVEC N1=O1:N2=O2; BIND GMOVPLIT=PLIT( 0,0,1,8,5,1, 0,0,1,8,5,1, 2,2,1,8,5,1, 7,7,6,8,8,6, 3,3,4,8,5,4, 2,2,1,8,5,1); IF .O1 EQL .O2 THEN RETURN; P1_.O1[SSPF]; P2_.O2[SSPF]; IF SLOW THEN IF NOMOVREQD(.O1,.O2) THEN RETURN; CASE .GMOVPLIT[.P1*6+.P2] OF SET ! 0 - FULL WORD TO FULL WORD IF ISZERO(.O1) THEN EMIT(PCLR,GMA(.O2),0) ELSE EMIT(PMOV,GMA(.O1),GMA(.O2)); ! 1 - MOVE TO <0,8> OR <8,8> FROM <0,16>, <0,8> OR <8,8> IF ISREG(.O2) THEN BEGIN REGISTER T,POS2; POS2_.N2[POSF]; IF ISLIT(.O1) THEN BEGIN IF (T_CLITVALUE(.O1) AND #377) NEQ #377 THEN CLEARFIELD(.O2,.POS2,8); IF .T NEQ 0 THEN EMIT(PICK8(PBIS,.POS2,8), GMA(MAKLIT(.T^.POS2)), GMA(.O2)); RETURN END; T_.O1; IF DEPENDON(.O1,.O2) THEN (T_VERYTEMP(0); SIMPLEMOVE(.O1,.T)); IF .POS2 EQL 8 OR (ISREG(.T) AND .P1 EQL PF88) THEN T_DIAL(.T,.N1[POSF],.N1[SIZEF],.POS2,8); CLEARFIELD(.O2,.POS2,8); IF .POS2 EQL 0 THEN IF NOT ISREG(.T) THEN RETURN EMIT(PBISB,GMA8(.T),GMA(.O2)); EMIT(PICK8(PBIS,.POS2,8),GMA(.T),GMA(.O2)) END ELSE IF ISLIT(.O1) THEN IF CLITVALUE(.O1) EQL 0 THEN EMIT(PCLRB,GMA8(.O2),0) ELSE EMIT(PMOVB,GMA(.O1),GMA8(.O2)) ELSE IF ISREG(.O1) AND .N1[POSF] NEQ 0 THEN BEGIN LOCAL T; IF NOT DEPENDON(.O2,.O1) THEN (T_GMA(.O1); EMIT(PSWAB,.T,0); EMIT(PMOVB,.T,GMA8(.O2)); EMIT(PSWAB,.T,0) ) ELSE (T_VERYTEMP(0); SIMPLEMOVE(.O1,.T); T_REG8(.T); EMIT(PMOVB,.T,GMA8(.O2))) END ELSE EMIT(PMOVB,GMA8(.O1),GMA8(.O2)); ! 2 - MOVE TO 0,16 FROM 0,8 OR 8,8 BEGIN REGISTER T; IF SAMEWORD(.O1,.O2) THEN BEGIN SHIFT(.O1,.N1[POSF],0,8); ISOLATE(.O2,0,.N1[SIZEF]); RETURN END; IF DEPENDON(.O1,.O2) THEN BEGIN EMIT(PMOVB,GMA8(.O1),GMA(.O2)); CLEARFIELD(.O2,8,8); RETURN END; IF ISREG(.O1) AND .N1[POSF] EQL 8 THEN (SIMPLEMOVE(.O1,.O2); EMIT(PCLRB,GMA(.O2),0); EMIT(PSWAB,GMA(.O2),0)) ELSE (EMIT(PCLR,GMA(.O2),0); EMIT(PBISB,GMA8(.O1),GMA(.O2))) END; ! 3 - MOVE TO 0,16 FROM ARBITRARY FIELD BEGIN LOCAL T; T_.O2; IF NOT SAMEWORD(.O1,.O2) THEN IF NOT ISCHEAP(.O2) THEN IF .N1[POSF] NEQ 0 THEN (IF (O2_VERYTMPREG()) EQL 0 THEN O2_.T); SIMPLEMOVE(.O1,.O2); SHIFT(.O2,.N1[POSF],0,.N1[SIZEF]); ISOLATE(.O2,0,.N1[SIZEF]); SIMPLEMOVE(.O2,.T) END; ! 4 - MOVE TO 0,8 OR 8,8 FROM ARBITRARY FIELD BEGIN LOCAL T,SPC; T_.O1;IF DEPENDON(.O1,.O2) THEN (T_VERYTEMP(0);SIMPLEMOVE(.O1,.T)); SPC _ ISREG(.O2) AND .N2[POSF] EQL 8; IF .SPC OR .N1[SIZEF] LSS 8 THEN T_DIAL(.T,.N1[POSF],.N1[SIZEF],8*.SPC,8) ELSE T_POSITIONIT(.T,.N1[POSF],0,8); IF .SPC THEN (CLEARFIELD(.O2,8,8);EMIT(PBIS,GMA(.T),GMA(.O2))) ELSE EMIT(PMOVB,GMA(.T),GMA8(.O2)) END; ! 5 - ARBITRARY FIELD TO ARBITRARY FIELD BEGIN LOCAL T,POS2,SIZE2; LOCAL C,X,BS; BS_C_-1; POS2_.N2[POSF]; SIZE2_.N2[SIZEF]; IF ISLIT(.O1) THEN BEGIN REGISTER L; L_CLITVALUE(.O1); X_MASK(0,.SIZE2,0); IF (L_.L AND .X) EQL .X THEN C_0; IF .L EQL 0 THEN BS_0; T_MAKLIT(.L^.POS2); END ELSE BEGIN LOCAL POS1,SIZE1; IF .N1[TYPEF] EQL TEMPNAMET THEN (POS1_0; SIZE1_16) ELSE (POS1_.N1[POSF]; SIZE1_.N1[SIZEF]); T_DIAL(.O1,.POS1,.SIZE1,.POS2,.SIZE2) END; IF .C NEQ 0 THEN CLEARFIELD(.O2,.POS2,.SIZE2); IF .BS NEQ 0 THEN EMIT(PICK8(PBIS,.POS2,.SIZE2),GMA(.T),GMA(.O2)) END; ! 6 - MOVE TO 0,8 OR 8,8 FROM E,1 BEGIN LOCAL T,P1,S,CHP,SPC; CHP_0; P1_.N1[POSF]; SPC_(ISREG(.O2) AND .N2[POSF] EQL 8); IF DEPENDON(.O1,.O2) OR (IF SAMEWORD(.O1,.O2) THEN OVERLAP(.P1,.N1[SIZEF],.N2[POSF],.N2[SIZEF])) THEN BEGIN T_VERYTEMP(0); IF ISCHEAP(.T) AND NOT .SPC THEN (CHP_-1;S_.O2;O2_.T) ELSE (SIMPLEMOVE(.O1,.T);O1_.T) END; CLEARFIELD(.O2,.N2[POSF],.N2[SIZEF]); T_GENLABEL(); GENBITTEST(.O1,.P1,.T); IF NOT .SPC THEN EMIT(PINCB,GMA8(.O2),0) ELSE EMIT(PBIS,GMA(MAKLIT(1^8)),GMA(.O2)); PLACELABEL(.T); IF .CHP THEN EMIT(PMOVB,GMA(.O2),GMA8(.S)) END; ! 7 - MOVE TO 0,16 FROM E,1 BEGIN LOCAL S,T,P1,CHP; CHP_0; P1_.N1[POSF]; IF SAMEWORD(.O1,.O2) THEN BEGIN IF (.P1 MOD 8) LEQ 2 THEN BEGIN SHIFT(.O1,.P1,0,1); ISOLATE(.O2,0,1); RETURN END; CHP_1 END ELSE IF DEPENDON(.O1,.O2) THEN CHP_1; IF .CHP EQL 1 THEN BEGIN T_VERYTEMP(0); IF ISCHEAP(.T) THEN (S_.O2;O2_.T) ELSE (CHP_0;SIMPLEMOVE(.O1,.T);O1_.T) END; EMIT(PCLR,GMA(.O2),0); T_GENLABEL(); GENBITTEST(.O1,.P1,.T); EMIT(PINC,GMA(.O2),0); PLACELABEL(.T); IF .CHP THEN EMIT(PMOV,GMA(.O2),GMA(.S)) END; ! 8 - MOVE TO/FROM ARBITRARY ONE BIT FIELD BEGIN REGISTER T,POS2,XBIT,P1; IF ISLIT(.O1) THEN BEGIN REGISTER OP; T_CLITVALUE(.O1); XBIT_GMA(MAKLIT(MASK(.N2[POSF],1,0))); IF .N2[POSF]+.N2[SIZEF] LEQ 8 THEN IF .T THEN OP_PBISB ELSE OP_PBICB ELSE IF .T THEN OP_PBIS ELSE OP_PBIC ; EMIT(.OP,.XBIT,GMA(.O2)); RETURN END; P1_IF .N1[TYPEF] EQL TEMPNAMET THEN 0 ELSE .N1[POSF]; IF DEPENDON(.O1,.O2) OR (IF SAMEWORD(.O1,.O2) THEN OVERLAP(.P1,.N1[SIZEF],.N2[POSF],.N2[SIZEF])) THEN (T_VERYTEMP(0);SIMPLEMOVE(.O1,.T);O1_.T); CLEARFIELD(.O2,.N2[POSF],.N2[SIZEF]); T_GENLABEL(); GENBITTEST(.O1,.P1,.T); IF (POS2_.N2[POSF]) EQL 0 THEN EMIT(PINCB,GMA(.O2),0) ELSF .POS2 EQL 8 AND NOT(ISREG(.O2)) THEN EMIT(PINCB,GMA8(.O2),0) ELSE EMIT(PICK8(PBIS,.POS2,1),GMA(MAKLIT(1^.POS2)),GMA(.O2)); PLACELABEL(.T); END; TES; END; ! OF GENMOVE MACRO TTN(Z)=(1^(Z))$, TTM(Z)=(TTN(Z)-1)$; ROUTINE MAKEDESTROYABLE(XOPND)= BEGIN MAP GTVEC XOPND; LOCAL T; IF NOT ISDESTROYABLE(.XOPND) THEN SIMPLEMOVE(.XOPND,T_VERYTEMP(.XOPND[REGF])) ELSF .XOPND[TYPEF] EQL TEMPNAMET THEN RETURN .XOPND ELSE BEGIN T_.XOPND[REGF]; IF .XOPND[MODE] NEQ GENREG THEN SIMPLEMOVE(.XOPND,.T) END; .T END; BIND MASKS = PLIT( 0, TTM(1), TTM(2), TTM(3), TTM(4), TTM(5), TTM(6), TTM(7), TTM(8), TTM(9), TTM(10), TTM(11), TTM(12), TTM(13), TTM(14), TTM(15), TTM(16) ); ROUTINE MASK(POS,SIZ,COMP)= BEGIN BIND X=SIZ; X_(.MASKS[.SIZ])^.POS; IF .COMP THEN X_NOT(.X); .X AND #177777 END; ROUTINE CLEARMASK(XOPND,MSK)= BEGIN LOCAL LOCN; MSK_.MSK AND #177777; IF .MSK EQL 0 THEN RETURN NOVALUE; IF CHECK08(.XOPND) THEN MSK_.MSK AND #377; LOCN_GMA(.XOPND); SELECT .MSK OF NSET #177777: RETURN EMIT(PCLR,.LOCN,0); #000377: RETURN EMIT(PCLRB,.LOCN,0); #177400: IF NOT ISREG(.XOPND) THEN RETURN EMIT(PCLRB,NXTBYTEADR(.LOCN),0); ALWAYS: RETURN EMIT(IF .MSK LEQ #377 THEN PBICB ELSE PBIC, GMA(MAKLIT(.MSK)),.LOCN) TESN; NOVALUE END; ROUTINE CLEARFIELD(XOPND,P,S)=CLEARMASK(.XOPND,MASK(.P,.S,0)); ROUTINE ISOLATE(XOPND,P,S)=CLEARMASK(.XOPND,MASK(.P,.S,1)); ROUTINE SHIFT(XOPND,XFP,XTP,SZ)= BEGIN LOCAL DIST,RL,SB,RB,SA,SHIFTROT,OP,ADRWD ADR:ADR1; IF (DIST_.XTP-.XFP) EQL 0 THEN RETURN; ADR_GMA(.XOPND); IF .SZ EQL 1 THEN IF .XFP EQL 15 THEN IF .ADR[OPDF] NEQ 0 THEN IF ONEOF(.XTP,BIT5(2,3,4,10,11)) THEN BEGIN LOCAL LAB; LAB_GENLABEL(); EMIT(PBIC,GMA(MAKLIT(1^.XTP)),.ADR); EMIT(PBPL,.LAB,0); EMIT(PCOM,.ADR,0); PLACELABEL(.LAB); RETURN 0 END; RL_SB_RB_SA_SHIFTROT_0; IF .DIST LSS 0 THEN (RL_NOT .RL;DIST_-.DIST); IF .DIST GTR 12 THEN (RL_NOT .RL;DIST_17-.DIST;SHIFTROT_1); IF .DIST GTR 7 THEN (SB_1;DIST_.DIST-8); IF .DIST GTR 4 THEN BEGIN LOCAL A; IF .SZ GTR 8 THEN IF .RL AND (.DIST EQL 5) THEN EXITBLOCK ELSE (RB_SHIFTROT_1; IF .RL THEN SA_8-.DIST ELSE SB_1) ELSE (A_ IF .RL THEN 16-(.XFP+.SZ) ELSE .XFP; SA_MIN(.A,8-.DIST); IF .SA EQL 0 THEN SB_1); DIST_8-.DIST; RL_NOT .RL END; ADR1_.ADR; IF .SB+(.SA NEQ 0)+.DIST+.RB GTR 1 THEN IF .ADR[OPDF] NEQ 0 THEN BEGIN ADR_VERYTMPREG(); IF .ADR EQL 0 THEN EXITCOMPOUND ADR_.ADR1; GENMOVE(.XOPND,.ADR); ADR_GMA(.ADR) END; IF .SB THEN EMIT(PSWAB,.ADR,0); IF .RB AND .RL THEN EMIT(PRORB,.ADR,0); OP_IF .RL THEN PASR ELSE PASL; IF .SHIFTROT THEN OP_.OP-4; ! ASR TO ROR, ASL TO ROL WHILE (DIST_.DIST-1) GEQ 0 DO (EMIT(.OP,.ADR,0); IF .DIST EQL 0 THEN IF .RB AND NOT .RL THEN EMIT(PROLB,.ADR,0); IF (SA_.SA-1) EQL 0 THEN EMIT(PSWAB,.ADR,0)); IF .ADR NEQ .ADR1 THEN EMIT(PMOV,.ADR,.ADR1); .SHIFTROT AND NOT .SB !TRUE IFF OLD CARRY BIT !HAS BEEN ROTATED INTO WORD. END; ROUTINE POSITIONIT(X,XFP,XTP,SZ)= BEGIN MAP GTVEC X; LOCAL T; IF .SZ LEQ 8 THEN IF .XFP EQL 8 THEN IF .XTP EQL 0 THEN IF NOT(ISIDT(.X)) THEN IF NOT(ISREG(.X)) THEN BEGIN EMIT(PMOVB,GMA8(.X),GMA(T_VERYTEMP(.X[REGF]))); RETURN .T END; T_MAKEDESTROYABLE(.X); SHIFT(.T,.XFP,.XTP,.SZ); .T END; ROUTINE DIAL(XOPND,XFP,XFS,XTP,XTS)= BEGIN MAP GTVEC XOPND; LOCAL S,T; S_MIN(.XFS,.XTS); T_POSITIONIT(.XOPND,.XFP,.XTP,.S); ISOLATE(.T,.XTP,.S); .T END; ROUTINE ALIGN(O1,O2)= BEGIN LOCAL GTVEC N1:N2:X1:X2:T1:T2,T; MACRO F=<0,36>$; N1_@.O1; N2_@.O2; IF .N1[POSF] GTR .N2[POSF] THEN (X1_.N2; X2_.N1; T_0) ELSE (X1_.N1; X2_.N2; T_1); T1_MAKEDESTROYABLE(.X1); ISOLATE(.T1,.X1[POSF],.X1[SIZEF]); T2_DIAL(.X2,.X2[POSF],.X2[SIZEF],.X1[POSF],16); IF .T THEN ((.O1)F_.T1; (.O2)F_.T2) ELSE ((.O1)F_.T2; (.O2)F_.T1); END; ! TEST-BRANCH SPECIAL CASE ROUTINES ! --------------------------------------- ROUTINE GENBITTEST(OPND,BIT,FLAB)= BEGIN REGISTER OPC1,OPC2; LOCAL ADR,SPC; IF ISLIT(.OPND) THEN BEGIN IF (CLITVALUE(.OPND) AND (1^.BIT)) EQL 0 THEN EMIT(PBR,.FLAB,0); RETURN NOVALUE END; SPC_-1; ADR_GMA(.OPND); SELECT .BIT OF NSET 15: (OPC1_PTST; OPC2_PBPL; EXITSELECT); 7: (OPC1_PTSTB; OPC2_PBPL; EXITSELECT); ALWAYS: IF NOT ISDESTROYABLE(.OPND) THEN (SPC_0; EXITSELECT); 0: (OPC1_PROR; OPC2_PBHIS; EXITSELECT); 14: (OPC1_PASL; OPC2_PBPL; EXITSELECT); 6: (OPC1_PASLB; OPC2_PBPL; EXITSELECT); ALWAYS: SPC_0 TESN; IF .SPC EQL 0 THEN BEGIN OPC1_PICK8(PBIT,.BIT,1); EMIT(.OPC1,GMA(MAKLIT(MASK(.BIT,1,0))),.ADR); OPC2_PBEQ END ELSE EMIT(.OPC1,.ADR,0); EMIT(.OPC2,.FLAB,0); RETURN NOVALUE END; STRUCTURE RELX[I]= (.RELX+(.I-SGTROP))<0,36>; BIND RELX RELOPTAB= PLIT( PBGT, PBLE, PBLT, PBGE, PBEQ, PBNE, 0,0,0,0,0,0,0,0,0,0,0,0, PBHI, PBLOS, PBLO, PBHIS, PBEQ, PBNE); STRUCTURE RELC[I]=(.RELC+(.I-PBNE))<0,36>; BIND RELC CRELOP=PLIT( PBNE,PBEQ,PBLE,PBGT,PBGE,PBLT,0,0,PBLO,PBHIS,0,0,PBLOS,PBHI); ROUTINE MAPTOUNSIGNED(OP)= BEGIN SELECT .OP OF NSET PBGT:PBHI; PBGE:PBHIS; PBLT:PBLO; PBLE:PBLOS; OTHERWISE:.OP; TESN END; MACRO CONVERSERELATIONAL(OP)=(.CRELOP[OP])$; MACRO REVERSERELATIONAL(OP)=((OP) XOR 1)$; ROUTINE COMPARE(OP1,OP2,RELOP,LAB)= BEGIN EMIT(PCMP,GMA(.OP1),GMA(.OP2)); EMIT(.RELOP,.LAB,0) END; ROUTINE COMPAREBYTE(OP1,OP2,RELOP,LAB)= BEGIN EMIT(PCMPB,GMA8(.OP1),GMA8(.OP2)); EMIT(MAPTOUNSIGNED(.RELOP),.LAB,0) END; ROUTINE REALCOMPARE(OP1,OP2,RELOP,LAB)= BEGIN MAP GTVEC OP1:OP2; BIND LEXEME LX1=OP1:LX2=OP2; LOCAL T; BIND SSPLIT= PLIT( 0,0,2,2,2,2, 0,0,2,2,2,2, 3,3,1,4,4,1, 3,3,4,4,4,4, 3,3,4,4,4,4, 3,3,1,4,4,1); CASE .SSPLIT[.LX1[SSPF]*6+.LX2[SSPF]] OF SET !0 -- FULL WORD COMPARISON COMPARE(.OP1,.OP2,.RELOP,.LAB); !1 -- BYTE-BYTE COMPARISON IF (ISREG(.OP1) AND .LX1[SSPF] NEQ PF08) OR (ISREG(.OP2) AND .LX2[SSPF] NEQ PF08) THEN BEGIN ALIGN(OP1,OP2); COMPARE(.OP1,.OP2,MAPTOUNSIGNED(.RELOP),.LAB); END ELSE COMPAREBYTE(.OP1,.OP2,.RELOP,.LAB); !2 -- FULL WORD WITH SOMETHING SMALLER BEGIN T_DIAL(.OP2,.OP2[POSF],.OP2[SIZEF],0,16); COMPARE(.OP1,.T,.RELOP,.LAB); END; !3 -- SOMETHING SMALLER WITH FULL WORD BEGIN T_DIAL(.OP1,.OP1[POSF],.OP1[SIZEF],0,16); COMPARE(.T,.OP2,.RELOP,.LAB); END; !4 -- BOTH ARE FUNNY FIELDS BEGIN ALIGN(OP1,OP2); COMPARE(.OP1,.OP2,MAPTOUNSIGNED(.RELOP),.LAB); END; TES; END; ROUTINE LITCOMPARE(OP1,L,RELOP,LAB %,MGT% )= BEGIN MAP GTVEC OP1, LEXEME L; BIND LEXEME OP1LEX=OP1; LOCAL T,C,T1,CASINDEX; BIND O1SS=PLIT(0,0,1,2,3,1); CASINDEX_.O1SS[.OP1LEX[SSPF]]; IF .OP1LEX[SSPF] EQL PF88 THEN IF ISREG(.OP1) THEN CASINDEX_3; CASE .CASINDEX OF SET !0 -- FULL WORD CASES BEGIN IF .L[SSLF] EQL LFZERO THEN BEGIN % IF .MGT OR ISSIMPLEOPND(.OP1) THEN % EMIT(PTST,GMA(.OP1),0); EMIT(.RELOP,.LAB,0); RETURN; END; IF .L[SSLF] EQL LFPM1 THEN IF ISDESTROYABLE(.OP1) THEN BEGIN T_CLITVALUE(.L); IF .T EQL 1 THEN EMIT(PDEC,GMA(.OP1),0) ELSE EMIT(PINC,GMA(.OP1),0); EMIT(.RELOP,.LAB,0); RETURN; END; COMPARE(.OP1,.L,.RELOP,.LAB); END; !1 -- BYTE CASES BEGIN RELOP_MAPTOUNSIGNED(.RELOP); IF .L[SSLF] EQL LFZERO THEN BEGIN EMIT(PTSTB,GMA8(.OP1),0); EMIT(.RELOP,.LAB,0); RETURN; END; IF .L[SSLF] EQL LFPM1 THEN IF ISDESTROYABLE(.OP1) THEN BEGIN T_CLITVALUE(.L); IF .T EQL 1 THEN EMIT(PDECB,GMA8(.OP1),0) ELSE EMIT(PINCB,GMA8(.OP1),0); EMIT(.RELOP,.LAB,0); RETURN; END; COMPAREBYTE(.OP1,.L,.RELOP,.LAB); END; !2 -- ONE BIT CASES BEGIN T_CLITVALUE(.L); IF .T EQL 0 OR .T EQL 1 THEN IF .RELOP EQL PBEQ OR .RELOP EQL PBNE THEN BEGIN IF (.T EQL 0) EQV (.RELOP EQL PBEQ) THEN GENBITTEST(.OP1,.OP1[POSF],.LAB) ELSE BEGIN T_GENLABEL(); GENBITTEST(.OP1,.OP1[POSF],.T); EMIT(PBR,.LAB,0); PLACELABEL(.T); END; RETURN END; T_EXTENDBIT(.T,16); IF .T LSS 0 THEN IF .RELOP EQL PBGT OR .RELOP EQL PBGE THEN EMIT(PBR,.LAB,0); IF .T GTR 1 THEN IF .RELOP EQL PBLT OR .RELOP EQL PBLE THEN EMIT(PBR,.LAB,0); RETURN; END; !3 -- GENERAL SUBFIELD CASES BEGIN IF (T_CLITVALUE(.L)) EQL 0 THEN BEGIN RELOP_MAPTOUNSIGNED(.RELOP); RELOP_SELECT .RELOP OF NSET PBHI: EXITSELECT PBNE; PBHIS: EXITSELECT PBR; PBLOS: EXITSELECT PBEQ; PBLO: RETURN NOVALUE; ALWAYS: EXITSELECT .RELOP TESN; IF .RELOP NEQ PBR THEN EMIT(PICK8(PBIT,.OP1[POSF],.OP1[SIZEF]), GMA(.OP1), GMA(MAKLIT(MASK(.OP1[POSF],.OP1[SIZEF],0)))); EMIT(.RELOP,.LAB,0); RETURN NOVALUE; END; T_EXTENDBIT(.T,16); IF .T GTR 0 THEN BEGIN IF (.T^(.OP1[POSF]) EQL ((.T^(.OP1[POSF]))AND#177777)) THEN BEGIN T1_MAKEDESTROYABLE(.OP1); ISOLATE(.T1,.OP1[POSF],.OP1[SIZEF]); COMPARE(.T1,MAKLIT(.T^(.OP1[POSF])),MAPTOUNSIGNED(.RELOP),.LAB); RETURN END; END; T1_DIAL(.OP1,.OP1[POSF],.OP1[SIZEF],0,16); COMPARE(.T1,.L,.RELOP,.LAB); RETURN END; TES; END; ROUTINE GENCOMPARE(OP1,OP2,OPX,LABT,LABF,SENSE %,MGT% )= BEGIN BIND LEXEME LX1=OP1:LX2=OP2; LOCAL RELOP; RELOP_.RELOPTAB[.OPX]; IF .SENSE THEN RELOP_CONVERSERELATIONAL(.RELOP); IF .LABT EQL 0 THEN (RELOP_REVERSERELATIONAL(.RELOP);LABT_.LABF;LABF_0); IF .LX2[LTYPF] EQL LITTYP THEN LITCOMPARE(.OP1,.OP2,.RELOP,.LABT %,.MGT% ) ELSE IF .LX1[LTYPF] EQL LITTYP THEN BEGIN RELOP_CONVERSERELATIONAL(.RELOP); LITCOMPARE(.OP2,.OP1,.RELOP,.LABT) END ELSE REALCOMPARE(.OP1,.OP2,.RELOP,.LABT); IF .LABF NEQ 0 THEN EMIT(PBR,.LABF,0); END; MACRO COMPAREFALSE(X1,X2,NX,XL)= GENCOMPARE(X1,X2,NX,XL,0,0)$; ROUTINE BITLIT(O1,O2)= BEGIN MAP GTVEC O1:O2; LOCAL L,P,S; P_.O1[POSF]; S_.O1[SIZEF]; L_GMA(MAKLIT(CLITVALUE(.O2)^.P AND .MASKS[.P+.S])); EMIT(PICK8(PBIT,.P,.S),.L,GMA(.O1)) END; ROUTINE BIT(O1,O2,ENE,LAB)= BEGIN MAP GTVEC O1:O2; BIND LEXEME L1=O1:L2=O2; LOCAL P,S; BIND BITPLIT=PLIT( 0,0,1,2,2,1, 0,0,1,2,2,1, 1,1,1,2,2,1, 2,2,2,2,2,2, 2,2,2,2,2,2, 1,1,1,2,2,1); IF ISLIT(.O1) THEN BITLIT(.O2,.O1) ELSE IF ISLIT(.O2) THEN BITLIT(.O1,.O2) ELSE CASE .BITPLIT[.L1[SSPF]*6+.L2[SSPF]] OF SET ! 0 - BIT EMIT(PBIT,GMA(.O1),GMA(.O2)); ! 1 - BITB BEGIN IF .L1[SSPF] EQL PF88 THEN IF ISREG(.O1) THEN O1_POSITIONIT(.O1,8,0,8); IF .L2[SSPF] EQL PF88 THEN IF ISREG(.O2) THEN O2_POSITIONIT(.O2,8,0,8); EMIT(PBITB,GMA8(.O1),GMA8(.O2)); END; ! 2 - SUBFIELD CASES BEGIN S_MIN(.O1[SIZEF],.O2[SIZEF]); IF .O1[POSF] LEQ .O2[POSF] THEN (P_.O1[POSF]; O2_DIAL(.O2,.O2[POSF],.O2[SIZEF],.P,.S)) ELSE (P_.O2[POSF]; O1_DIAL(.O1,.O1[POSF],.O1[SIZEF],.P,.S)); EMIT(PICK8(PBIT,.P,.S),GMA(.O1),GMA(.O2)); END TES; EMIT(IF .ENE THEN PBNE ELSE PBEQ,.LAB,0) END; !!! THE FOLLOWING ROUTINES ARE THE NODE-SPECIFIC CODE GENERATORS !!! -------------------------------------------------------------- FORWARD CODE; MACRO ADJUSTSTACK=IF .NODE[DTDELETE] NEQ DTDONTCARE THEN IF .NODE[DTDELETE] NEQ .DYTEMPS THEN BEGIN EMIT(PADD,GMA(MAKLIT(.DYTEMPS-.NODE[DTDELETE])),STACKPTR); DYTEMPS_.NODE[DTDELETE] END$, CHECKFORFLOW=(IF .NODE[NSRFFF] THEN GFLOW(.NODE))$, CODELST(LST)=PULSELIST(PULSECODE,LST,0)$, CODER(RNAME)=ROUTINE RNAME(NODE,GOAL)= BEGIN MAP GTVEC NODE, GOALWD GOAL;$, LASTOPERAND=OPERAND(.NODE[NODESIZEF]-1)$, MYTEMP=.NODE[REGF]$, PICKTARGET(T,N)=IF .NODE[TPATH] THEN (T_.NODE[OPR2]; N_.NODE[OPR1]) ELSE (T_.NODE[OPR1]; N_.NODE[OPR2])$, STARTFREE(LST1,LST2)= BEGIN IF EMPTY(LST1) THEN IF EMPTY(LST2) THEN EXITCOMPOUND; PLSTCNT_.PLSTCNT-1; END $, STOPFREE(LST1,LST2)= BEGIN IF EMPTY(LST1) THEN IF EMPTY(LST2) THEN EXITCOMPOUND; PLSTCNT_.PLSTCNT+1; END $; STRUCTURE GOALWD[I]=.GOALWD<.I*18,18>; BIND GSIZEF=0, GPOSF=1; MACRO GOALS(P,S)=((P)^18 OR (S))$, FULLWD=GOALS(0,16)$; ROUTINE SETNEWPS(NODE,P,S)= BEGIN MAP GTVEC NODE; BIND LEXEME LEX=NODE; NODE[POSF]_.P; NODE[SIZEF]_.S; NODE[NSSPF]_(IF .S EQL 1 THEN PFE1 ELSF .P EQL 0 THEF .S EQL 8 THEN PF08 ELSF .S EQL 16 THEN PF016 ELSE PFOTHER ELSF .P EQL 8 AND .S EQL 8 THEN PF88 ELSE PFOTHER); LEX[SSPF]_.NODE[NSSPF]; .NODE END; ROUTINE GFLOW(NODE)= BEGIN MAP GTVEC NODE; ADJUSTSTACK; GENBITTEST(.NODE,.NODE[POSF],NODELABEL(.NODE[LABELFF])); EMIT(PBR,NODELABEL(.NODE[LABELTF]),0) END; ROUTINE PULSECODE(NODE,P)= BEGIN MAP GTVEC NODE; LOCAL L,LR,RFF,LDT; IF (RFF_.NODE[NSRFF])EQL RFFLOW THEN RETURN ELSE NODE[NSRFFF]_0; L_.NODE[LABELF]; NODE[LABELF]_0; LR_.NODE[LABELREQDF]; NODE[LABELREQDF]_0; LDT_.NODE[DTDELETE]; NODE[DTDELETE]_DTDONTCARE; NODE[MUSTGENCODE]_1; PLSTCNT_.PLSTCNT+1; CODE(NODE,FULLWD); PLSTCNT_.PLSTCNT-1; NODE[LABELREQDF]_.LR; NODE[LABELF]_.L; NODE[NSRFF]_.RFF; NODE[DTDELETE]_.LDT; END; ROUTINE GAS(NODE,GOAL,OP)= BEGIN MAP GTVEC NODE, GOALWD GOAL; LOCAL GTVEC TAR:NTAR:TMP, INCORDEC; INCORDEC_FALSE; TMP_.NODE[REGF]; CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); IF .NODE[NSRFF] EQL RFNONE THEN RETURN .NODE; PICKTARGET(TAR,NTAR); SELECT TRUE OF NSET .NODE[RCMOF]: EMIT(PMOV,GMOFF(.NODE),GMA(.TMP)); .NODE[RCMTF]: GENMOVE(.TAR,.TMP); .NODE[RCNTF]: EMIT(PNEG,GMA(.TMP),0); .NODE[RCOPTF]: BEGIN IF .NTAR[NSSPF] GTR PF016 THEN GENMOVE(.NTAR,NTAR_VERYTEMP(.NTAR[REGF])); EMIT(.OP,GMA(.NTAR),GMA(.TMP)); END; .NODE[RCAF] XOR .NODE[RCSF]: ! IF OFFSET IS LITERAL, GET ITS ABSOLUTE VALUE, TO ! TRY TO GET AS MANY INCB'S AND DECB'S AS POSSIBLE. IF NOT .NODE[SYMOFFF] THEN IF EXTEND(.NODE[OFFSETF]) LSS 0 THEN (NODE[OFFSETF]_(-.NODE[OFFSETF]) AND #177777; NODE[RCAF]_NOT .NODE[RCAF]; NODE[RCSF]_NOT .NODE[RCSF]); .NODE[RCAF]: IF .NODE[OFFSETF] EQL 1 ! NO NEED TO TEST [SYMOFFF] IF THE ABOVE IS TRUE! THEN (EMIT(PICK8(PINC,.GOAL[GPOSF],.GOAL[GSIZEF]),GMA(.TMP),0); INCORDEC_TRUE) ELSE EMIT(PADD,GMOFF(.NODE),GMA(.TMP)); .NODE[RCSF]: IF .NODE[OFFSETF] EQL 1 THEN (EMIT(PICK8(PDEC,.GOAL[GPOSF],.GOAL[GSIZEF]),GMA(.TMP),0); INCORDEC_TRUE) ELSE EMIT(PSUB,GMOFF(.NODE),GMA(.TMP)) TESN; CHECKFORFLOW; IF .INCORDEC THEN IF .GOAL EQL GOALS(0,8) THEN RETURN SETNEWPS(.NODE,0,8); .NODE END; CODER(GADD) GAS(.NODE,.GOAL,PADD) END; CODER(GSUB) GAS(.NODE,.GOAL,PSUB) END; CODER(GSTORE) LOCAL GTVEC TAR:NTAR,GOALWD TGOAL; BIND LEXEME LTAR=TAR; TAR_IF .NODE[TPATH] THEN .NODE[OPR2] ELSE .NODE[OPR1]; TGOAL_IF .LTAR[LTYPF] EQL LITTYP THEN FULLWD ELSE GOALS(.TAR[POSF],.TAR[SIZEF]); CODE(NODE[OPR1],IF .NODE[TPATH] THEN .TGOAL ELSE FULLWD); CODE(NODE[OPR2],IF .NODE[TPATH] THEN FULLWD ELSE .TGOAL); PICKTARGET(TAR,NTAR); IF .TGOAL NEQ GOALS(0,16) THEN IF .TGOAL EQL GOALS(.NTAR[POSF],.NTAR[SIZEF]) THEN NODE_SETNEWPS(.NODE,.TGOAL[GPOSF],.TGOAL[GSIZEF]); IF .NODE[NSRFRF] THEN (GENMOVE(.NTAR,MYTEMP); GENMOVE(MYTEMP,.TAR)) ELSE GENMOVE(.NTAR,.TAR); CHECKFORFLOW; .NODE END; CODER(GDOT) CODE(NODE[OPR1],FULLWD); CHECKFORFLOW; .NODE END; CODER(GXNULL) CHECKFORFLOW; .NODE END; CODER(GNULL) CODE(NODE[OPR1],FULLWD); IF .NODE[NSRFF] NEQ RFNONE THEN GENMOVE(.NODE[OPR1],MYTEMP); CHECKFORFLOW; .NODE END; CODER(GBNULL) CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); CHECKFORFLOW; .NODE END; CODER(GLOADNODE) MACRO OFFSETLIT=GMA(MAKLIT(LOCALOFFSET(OPR)))$; BIND LEXEME LEX=NODE[OPR1]; BIND GTVEC OPR =NODE[OPR1]; CODE(NODE[OPR1],FULLWD); IF .NODE[NSRFF] EQL RFNONE THEN RETURN .NODE; IF .NODE[RCMTF] THEN IF .LEX[LTYPF] EQL LITTYP THEN GENMOVE(.NODE[OPR1],.NODE[REGF]) ELSE IF .OPR[TYPEF] EQL GRAPHT THEN GENMOVE(.NODE[OPR1],.NODE[REGF]) ELSE IF NOT(.LEX[IMMF]) THEN GENMOVE(.NODE[OPR1],.NODE[REGF]) ELSE IF NOT FORGOTTEN(.NODE,.NODE[OPR1]) THEN BEGIN ! WE HAVE AN ST ENTRY WITH THE IMMF BIT ON LOCAL X; X_GMA(MYTEMP); SELECT .OPR[TYPEF] OF NSET LOCALT: BEGIN LOCAL GTVEC OPR; OPR_LOCDEF(.LEX); UNLOCFLG_TRUE; IF LOCALOFFSET(OPR) EQL 0 AND .X NEQ PUSHED THEN EMIT(PMOV,STACKPTR,.X) ELSE (EMIT(PMOV,OFFSETLIT,.X); EMIT(PADD,STACKPTR,GMA(MYTEMP))) END; FORMALT:BEGIN EMIT(PMOV,(OFFSETLIT)+FORMALK,.X); EMIT(PADD,STACKPTR,GMA(MYTEMP)); END; OTHERWISE: EMIT(PMOV,GMA(.LEX),.X); TESN; END; IF .NODE[RCAF] THEN EMIT(PADD,GMOFF(.NODE),GMA(MYTEMP)); IF .NODE[RCNTF] THEN EMIT(PICK8(PNEG,.GOAL[GPOSF],.GOAL[GSIZEF]),GMA(MYTEMP),0); IF .NODE[RCCF] THEN EMIT(PICK8(PCOM,.GOAL[GPOSF],.GOAL[GSIZEF]),GMA(MYTEMP),0); CHECKFORFLOW; IF .GOAL EQL GOALS(0,8) THEN IF .NODE[RCNTF] OR .NODE[RCCF] THEN RETURN SETNEWPS(.NODE,0,8); .NODE END; CODER(GREL) LOCAL L; CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); IF .NODE[NSRFFF] THEN (SETNOPUSHVT; ADJUSTSTACK); CASE .NODE[NSRFF] OF SET %RFNONE% 0; %RFREAL% BEGIN EMIT(PCLR,GMA(MYTEMP),0); L_GENLABEL(); GENCOMPARE(.NODE[OPR1],.NODE[OPR2],.NODE[NODEX],0,.L,.NODE[TPATH]); EMIT(PINC,GMA(MYTEMP),0); PLACELABEL(.L) END; %RFFLOW% GENCOMPARE(.NODE[OPR1], .NODE[OPR2], .NODE[NODEX], NODELABEL(.NODE[LABELTF]), NODELABEL(.NODE[LABELFF]), .NODE[TPATH]); %RFBOTH% BEGIN EMIT(PCLR,GMA(MYTEMP),0); GENCOMPARE(.NODE[OPR1],.NODE[OPR2],.NODE[NODEX],0,NODELABEL(.NODE[LABELFF]),.NODE[TPATH]); EMIT(PINC,GMA(MYTEMP),0); EMIT(PBR,NODELABEL(.NODE[LABELTF]),0) END TES; IF .NODE[NSRFFF] THEN RESETPUSHVT; .NODE END; CODER(GBIT) LOCAL L; CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); IF .NODE[NSRFFF] THEN (SETNOPUSHVT; ADJUSTSTACK); CASE .NODE[NSRFF] OF SET %RFNONE% 0; %RFREAL% BEGIN EMIT(PCLR,GMA(MYTEMP),0); BIT(.NODE[OPR1],.NODE[OPR2],NOT .NODE[NKNOTF],(L_GENLABEL())); EMIT(PINC,GMA(MYTEMP),0); PLACELABEL(.L); END; %RFFLOW% BEGIN BIT(.NODE[OPR1],.NODE[OPR2],.NODE[NKNOTF],NODELABEL(.NODE[LABELTF])); EMIT(PBR,NODELABEL(.NODE[LABELFF]),0); END; %RFBOTH% BEGIN EMIT(PCLR,GMA(MYTEMP),0); BIT(.NODE[OPR1],.NODE[OPR2],NOT .NODE[NKNOTF],NODELABEL(.NODE[LABELFF])); EMIT(PINC,GMA(MYTEMP),0); EMIT(PBR,NODELABEL(.NODE[LABELTF]),0); END TES; IF .NODE[NSRFFF] THEN RESETPUSHVT; .NODE END; STRUCTURE PVECTOR[I]=(@.PVECTOR+.I)<0,36>; BIND XNT=0, ! MOVE NON-TARGET TO DISTINCT TEMPORARY CN=1, ! COMPLEMENT NON-TARGET CT=2, ! COMPLEMENT TEMP CX=3, ! COMPLEMENT X (COPY OF NON-TARGET) BISNT=4, ! BIS NON-TARGET TO TARGET BISXT=5, ! BIS X TO TARGET BISTX=6, ! BIS TARGET TO X BICNT=7, ! BIC NON-TARGET TO TARGET BICXT=8, ! BIC X TO TARGET BICTX=9; ! BIC TARGET TO X ROUTINE GBOOL(NODE,GOAL,OPS,FILL)= BEGIN MAP GTVEC NODE, GOALWD GOAL, PVECTOR OPS; LOCAL GTVEC NT:XNT:T, X,RPOS,RSIZ,TPOS,TSIZ; CODE(NODE[OPR1],.GOAL); CODE(NODE[OPR2],.GOAL); IF NOT(.NODE[NSRFRF]) THEN RETURN .NODE; PICKTARGET(T,NT); XNT_.NT; IF .NODE[RCMTF] THEN SIMPLEMOVE(.T,MYTEMP); IF ISLIT(.T) ! YES, THIS CAN HAPPEN, E.G. " #340 AND NOT .X " ! IN WHICH THE TARGET SUBNODE WILL BE THE " #340 ". THEN (TPOS_0; TSIZ_16) ELSE (TPOS_.T[POSF]; TSIZ_.T[SIZEF]); IF ISLIT(.NT) THEN BEGIN RPOS_MIN(.GOAL[GPOSF],.TPOS); RSIZ_.GOAL[GSIZEF]; IF .RPOS LSS .TPOS THEN SHIFT(MYTEMP,.TPOS,.RPOS,MIN(.TSIZ,.RSIZ)); IF .TSIZ LSS .RSIZ THEN ISOLATE(MYTEMP,.RPOS,.TSIZ); XNT_MAKLIT(CLITVALUE(.NT)^.RPOS); END ELSE BEGIN RPOS_(IF (.TPOS-.GOAL[GPOSF])*(.NT[POSF]-.GOAL[GPOSF]) LSS 0 THEN .GOAL[GPOSF] ELSF ABS(.TPOS-.GOAL[GPOSF]) LSS ABS(.NT[POSF]-.GOAL[GPOSF]) THEN .TPOS ELSE .NT[POSF]); RSIZ_MIN(.GOAL[GSIZEF],MAX(.TSIZ,.NT[SIZEF])); IF .TPOS NEQ .RPOS THEN SHIFT(MYTEMP,.TPOS,.RPOS,MIN(.TSIZ,.RSIZ)); IF .TSIZ LSS .RSIZ THEN ISOLATE(MYTEMP,.RPOS,.TSIZ); IF .NT[POSF] NEQ .RPOS THEN BEGIN XNT_MAKEDESTROYABLE(.XNT); SHIFT(.XNT,.NT[POSF],.RPOS,MIN(.NT[SIZEF],.RSIZ)); END; IF NOT .NODE[RCMTF] THEN IF ((.RPOS) OR (.RSIZ MOD 8)) NEQ 0 THEN BEGIN XNT_MAKEDESTROYABLE(.XNT); ISOLATE(.XNT,.RPOS,.RSIZ); END; IF .NT[SIZEF] LSS .RSIZ THEN BEGIN XNT_MAKEDESTROYABLE(.XNT); ISOLATE(.XNT,.RPOS,.NT[SIZEF]); END; END; INCR I FROM 0 TO .OPS[-1]-1 DO CASE .OPS[.I] OF SET %XNT% (X_VERYTEMP(0); GENMOVE(.XNT,.X)); %CN% IF ISLIT(.XNT) THEN XNT_MAKLIT(NOT CLITVALUE(.XNT)) ELSE EMIT(PCOM,GMA(XNT_MAKEDESTROYABLE(.XNT)),0); %CT% EMIT(PICK8(PCOM,.RPOS,.RSIZ),GMA(MYTEMP),0); %CX% EMIT(PCOM,GMA(.X),0); %BISNT% EMIT(PICK8(PBIS,.RPOS,.RSIZ),GMA(.XNT),GMA(MYTEMP)); %BISXT% EMIT(PBIS,GMA(.X),GMA(MYTEMP)); %BISTX% EMIT(PBIS,GMA(MYTEMP),GMA(.X)); %BICNT% EMIT(PICK8(PBIC,.RPOS,.RSIZ),GMA(.XNT),GMA(MYTEMP)); %BICXT% EMIT(PBIC,GMA(.X),GMA(MYTEMP)); %BICTX% EMIT(PBIC,GMA(MYTEMP),GMA(.X)) TES; SHIFT(MYTEMP,.RPOS,.GOAL[GPOSF],.RSIZ); IF .GOAL[GSIZEF] GTR .RSIZ THEN BEGIN RPOS_.GOAL[GPOSF]+.RSIZ; RSIZ_.GOAL[GSIZEF]-.RSIZ; IF .FILL THEN EMIT(PICK8(PBIS,.RPOS,.RSIZ), GMA(MAKLIT(MASK(.RPOS,.RSIZ,0))), GMA(MYTEMP)) ELSE CLEARFIELD(MYTEMP,.RPOS,.RSIZ); END; CHECKFORFLOW; SETNEWPS(.NODE,.GOAL[GPOSF],.GOAL[GSIZEF]) END; MACRO PICKCASE= (IF .NODE[TPATH] THEN .O1[KNOTF]*2+.O2[KNOTF] ELSE .O2[KNOTF]*2+.O1[KNOTF])$; CODER(GAND) BIND LEXEME O1=NODE[OPR1]:O2=NODE[OPR2]; BIND OPS = PLIT( PLIT(CN,BICNT), PLIT(CN,BISNT,CT), PLIT(BICNT), PLIT(BISNT,CT) ); GBOOL(.NODE,.GOAL,.OPS[PICKCASE],0) END; CODER(GOR) BIND LEXEME O1=NODE[OPR1]:O2=NODE[OPR2]; BIND OPS=PLIT( PLIT(BISNT), PLIT(CT,BISNT), PLIT(CN,BISNT), PLIT(CN,BICNT,CT) ); GBOOL(.NODE,.GOAL,.OPS[PICKCASE],0) END; ROUTINE XEFLOW(LOP,ROP,TLAB,FLAB)= BEGIN MAP GTVEC LOP:ROP; LOCAL GTVEC VT,RPOS; SETNOPUSHVT; RPOS_.ROP[POSF]; IF (.RPOS+.ROP[SIZEF] LEQ 8) AND (NOT ISREG(.ROP)) THEN (VT_VERYTEMP(.ROP[REGF]); SIMPLEMOVE(.ROP,.VT); ROP_.VT); VT_POSITIONIT(.LOP,.LOP[POSF],.RPOS,1); CLEARFIELD(.VT,0,.RPOS); EMIT(PADD,GMA(.ROP),GMA(.VT)); GENBITTEST(.VT,.RPOS,NODELABEL(.FLAB)); EMIT(PBR,NODELABEL(.TLAB),0); RESETPUSHVT; END; CODER(GXOR) BIND LEXEME O1=NODE[OPR1]:O2=NODE[OPR2]; BIND OPS=PLIT( PLIT(XNT,BICTX,BICNT,BISXT), PLIT(XNT,BICTX,BICNT,BISXT,CT), PLIT(XNT,BICTX,BICNT,BISXT,CT), PLIT(XNT,BICTX,BICNT,BISXT) ); IF .NODE[NSRFF] NEQ RFFLOW THEN GBOOL(.NODE,.GOAL,.OPS[PICKCASE],0) ELSE (CODE(O1,FULLWD);CODE(O2,FULLWD);ADJUSTSTACK; XEFLOW(.O1,.O2,.NODE[LABELTF],.NODE[LABELFF]); .NODE) END; CODER(GEQV) BIND LEXEME O1=NODE[OPR1]:O2=NODE[OPR2]; BIND OPS=PLIT( PLIT(XNT,BICTX,BICNT,BISXT,CT), PLIT(XNT,BICTX,BICNT,BISXT), PLIT(XNT,BICTX,BICNT,BISXT), PLIT(XNT,BICTX,BICNT,BISXT,CT) ); IF .NODE[NSRFF] NEQ RFFLOW THEN GBOOL(.NODE,.GOAL,.OPS[PICKCASE],1) ELSE (CODE(O1,FULLWD);CODE(O2,FULLWD);ADJUSTSTACK; XEFLOW(.O1,.O2,.NODE[LABELFF],.NODE[LABELTF]); .NODE) END; CODER(GSHIFT) LOCAL STVEC T,NT,S,AS,OP,T1,GT1,CHP,GMD,MSK; BIND LEXEME TLEX=T; CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); IF .NODE[NSRFF] EQL RFNONE THEN RETURN .NODE; PICKTARGET(T,NT); IF NOT ISLIT(.NT) THEN PUNT(777); GMD_0; S_EXTEND(CLITVALUE(.NT)); IF .TLEX[SSPF] LEQ PF016 THEN MSK_0 ELSE BEGIN MACHOP ASH=#240; REGISTER R; S_MIN(16,.S-.T[POSF]); R_NOT MASK(.T[POSF],.T[SIZEF],0); MSK_ASH(R,.S); END; OP_IF .S LSS 0 THEN PASR ELSE PASL; AS_ABS(.S); CHP_0; IF .AS LEQ 2 OR ISCHEAP(MYTEMP) THEN (T1_MYTEMP; CHP_1) ELSE (IF (T1_VERYTMPREG()) EQL 0 THEN T1_MYTEMP ELSE CHP_1); IF .S GEQ 13 THEN BEGIN AS_17-.S; SIMPLEMOVE(.T,.T1); GT1_GMA(.T1); WHILE (AS_.AS-1) GEQ 0 DO EMIT(PROR,.GT1,0); CLEARMASK(.T1,.MASKS[.S] OR .MSK); GENMOVE(.T1,MYTEMP); CHECKFORFLOW; RETURN .NODE END; IF .S EQL 7 THEN BEGIN SIMPLEMOVE(.T,.T1); GT1_GMA(.T1); EMIT(PSWAB,.GT1,0); EMIT(PRORB,.GT1,0); EMIT(PROR,.GT1,0); CLEARMASK(.T1,#177 OR .MSK); GENMOVE(.T1,MYTEMP); CHECKFORFLOW; RETURN .NODE END; IF .S GEQ 8 THEN BEGIN SIMPLEMOVE(.T,.T1); GT1_GMA(.T1); GMD_1; EMIT(PSWAB,.GT1,0); AS_.AS-8; IF (.MSK AND NOT (#377^.AS)) EQL 0 THEN EMIT(PCLRB,.GT1,0) ELSE MSK_.MSK OR #377^.AS; END; IF (.S LEQ -7) OR (NOT .CHP) THEN IF ISREG(.T1) AND .S LEQ -8 THEN BEGIN SIMPLEMOVE(.T,.T1); GT1_GMA(.T1); GMD_1; EMIT(PSWAB,.GT1,0); IF .MSK EQL 0 THEN EMIT(PMOVB,.GT1,.GT1); AS_.AS-8 END ELSE IF .AS GEQ 4 THEN BEGIN LOCAL L1; IF .T1 EQL MYTEMP THEN T1_VERYTEMP(0); SIMPLEMOVE(.T,MYTEMP); EMIT(PMOV,GMA(MAKLIT(.AS)),GMA(.T1)); L1_GENLABEL(); PLACELABEL(.L1); EMIT(.OP,GMA(MYTEMP),0); EMIT(PDEC,GMA(.T1),0); EMIT(PBNE,.L1,0); CLEARMASK(MYTEMP,.MSK); CHECKFORFLOW; RETURN .NODE END; IF NOT .GMD THEN (SIMPLEMOVE(.T,.T1); GT1_GMA(.T1)); WHILE (AS_.AS-1) GEQ 0 DO EMIT(.OP,.GT1,0); CLEARMASK(.T1,.MSK); IF .NODE[RCAF] THEN EMIT(PADD,GMOFF(.NODE),GMA(.T1)); ! FOR DISTRIBUTED MULTIPLICATION THAT DIDN'T MAKE IT. GENMOVE(.T1,MYTEMP); CHECKFORFLOW; .NODE END; CODER(GROT) BIND LEXEME LEX=NODE; LOCAL S,NT,T,OP,L; CODE(NODE[OPR1],FULLWD); PICKTARGET(T,NT); GENMOVE(.T,MYTEMP); IF ISLIT(.NT) THEN BEGIN S_CLITVALUE(.NT); IF .S<15,1> THEN S_(.S+17) AND #177777; IF .S LEQ 8 THEN OP_PROL ELSE (OP_PROR; S_17-.S); WHILE (S_.S-1) GEQ 0 DO EMIT(.OP,GMA(MYTEMP),0); CHECKFORFLOW; RETURN .NODE END; PUNT(777); .NODE END; CODER(GMAXMIN) LOCAL LEXEME T:N,L,RELOP; CODE(NODE[OPR1],FULLWD); CODE(NODE[OPR2],FULLWD); IF .NODE[NSRFF] EQL RFNONE THEN RETURN .NODE; PICKTARGET(T,N); RELOP_(IF .NODE[NODEX] EQL SMINNOP THEN SGTROP ELSE SLSSOP); GENMOVE(.T,MYTEMP); L_GENLABEL(); GENCOMPARE(MYTEMP,.N,.RELOP,0,.L,0); GENMOVE(.N,MYTEMP); PLACELABEL(.L); CHECKFORFLOW; .NODE END; CODER(GSWAB) CODE(NODE[OPR1],FULLWD); GENMOVE(.NODE[OPR1],MYTEMP); EMIT(PSWAB,GMA(MYTEMP),0); CHECKFORFLOW; .NODE END; CODER(GCASE) LOCAL SDTD,T, PVECTOR L, LX,LE,LSG,CC; STOPFREE(.NODE[OPR1],.NODE[LASTOPERAND]); CODELST(.NODE[OPR1]); CODE(NODE[OPR2],FULLWD); SDTD_.DYTEMPS; T_.NODE[OPR2]; LE_GENLABEL(); LX_GENLABEL(); IF .SEGSW THEN LSG_GENLABEL(); CC_NEWCODECELL(); IF ISREG(.T) THEN PUTCODE(.CC,UNUSED,PADD,INDEXEDBY(.T,REFLABEL(.LE,.CC,UNUSED),LABELTYPE),PROGCTR) ELSE BEGIN PUTCODE(.CC,UNUSED,PADD,IMMLAB(.LE,.CC,UNUSED),GMA(.T)); EMIT(PADD,DEFER(GMA(.T)),PROGCTR) END; IF .SEGSW THEN (PLACELABEL(.LSG); EMIT(PWORD,GMA(MAKLIT(0)),0)); PLACELABEL(.LE); IF .SEGSW THEN LE_.LSG; L_GETSPACE(GT,.NODE[NODESIZEF]); INCR I FROM 2 TO .NODE[NODESIZEF]-2 DO BEGIN L[.I]_GENLABEL(); EMIT(PCASE,.L[.I],.LE) END; INCR I FROM 2 TO .NODE[NODESIZEF]-2 DO BEGIN PLACELABEL(.L[.I]); DYTEMPS_.SDTD; CODE(NODE[OPERAND(.I)],FULLWD); IF .NODE[NSRFRF] THEN (SETNOPUSHVT; GENMOVE(.NODE[OPERAND(.I)],MYTEMP); RESETPUSHVT); EMIT(PBR,.LX,0) END; PLACELABEL(.LX); CODELST(.NODE[LASTOPERAND]); RELEASESPACE(GT,.L,.NODE[NODESIZEF]); STARTFREE(.NODE[OPR1],.NODE[LASTOPERAND]); CHECKFORFLOW; .NODE END; MACRO POPENABLE=(IF NOT .HYDRASW THEN EMIT(PMOV,ALOCAL(.K),GMA(.LXSIGR)) ELSE EMIT(PMOV,ALOCAL(.K+2),GMA(.LXSIGR)))$; % GET RID OF ELSE PART AFTER HYDRA PEOPLE RECOMPILE % CODER(GCOMPOUND) INCR I FROM 0 TO .NODE[NODESIZEF]-1 DO CODE(NODE[OPERAND(.I)],FULLWD); IF .NODE[ENABIT] THEN IF NOT .HYDRASW THEN EMIT(PMOV,DEFER(GMA(.LXSIGR)),GMA(.LXSIGR)) ELSE BEGIN %TEMPORARY UNTIL HYDRA PEOPLE RECOMPILE% LOCAL V; V_VERYTEMP(0); GENMOVE(.LXSIGR,.V); IF ISREG(.V) THEN EMIT(PMOV,INDEXEDBY(.V,2,NORMALT),GMA(.LXSIGR)) ELSE BEGIN EMIT(PADD,GMA(MAKLIT(2)),GMA(.V)); EMIT(PMOV,DEFER(GMA(.V)),GMA(.LXSIGR)); END; END; CHECKFORFLOW; .NODE END; CODER(GCALL) MAP STVEC LXHLNK:LXHLTB:LXIHLNK; LOCAL GTVEC LNK; SETNODYNVT; SETNOPUSHVT; INCR I FROM 1 TO .NODE[NODESIZEF]-1 DO CODE(NODE[OPERAND(.I)],FULLWD); LNK_.NODE[OPR1]; LNKTYPE_.LNK[LNKGTF]; ! used by CKREGSCHNGD CASE .LNKTYPE OF SET !0: SPECIAL FUNCTIONS SELECT .NODE[XOPR2] OF NSET .LXHALT: EMIT(PHALT,0,0); .LXRESET: EMIT(PRESET,0,0); .LXWAIT: EMIT(PWAIT,0,0); .LXNOP: EMIT(PNOP,0,0); .LEXEXCHJ: (LEXEXCHJ[PRNEXF]_TRUE; EMIT(PJSR,PROGCTR,GMA(.LEXEXCHJ))) TESN; !1: BLISS LINKAGE BEGIN EMIT(PJSR,PROGCTR,GMA(.NODE[OPR2])); IF .NODE[OFFSETF] NEQ 0 THEN % FOR DISTRIBUTIVE MULTIPLICATION. % EMIT(PADD,GMOFF(.NODE),GMA(.NODE)) END; !2: EMT LINKAGE EMIT(PEMT,BUILDOPD(TRAPIDT,UNUSED,UNUSED,CLITVALUE(.NODE[OPR2])),0); !3: FORTRAN LINKAGE 0; ! NOT CODED YET !4: INTERRUPT LINKAGE 0; !5: TRAP LINKAGE EMIT(PTRAP,BUILDOPD(TRAPIDT,UNUSED,UNUSED,CLITVALUE(.NODE[OPR2])),0); !6: IOT LINKAGE EMIT(PIOT,0,0); !7: HYDRA BEGIN LXHLNK[PRNEXF]_LXHLTB[PRNEXF]_1; EMIT(PJSR,REG5,GMA(.LXHLNK)); EMIT(PWORD,GMA(.NODE[OPR2]),1); EMIT(PWORD,GMA(.LXHLTB),1) END; !8: IHYDRA BEGIN LXIHLNK[PRNEXF]_1; GENMOVE(.NODE[OPR2],.RR0); EMIT(PJSR,PROGCTR,GMA(.LXIHLNK)) END TES; CHECKFORFLOW; RESETPUSHVT; RESETDYNVT; .NODE END; CODER(GIF) MACRO GENTHEN=.T<0,1>$, GENELSE=.T<1,1>$; LOCAL SDTD,L,T; BIND GTVEC THENPART=NODE[OPR3]:ELSEPART=NODE[OPR4]; STOPFREE(.NODE[OPR1],.NODE[OPR5]); CODELST(.NODE[OPR1]); CODE(NODE[OPR2],FULLWD); T_IF ISLIT(.NODE[OPR2]) THEN IF CLITVALUE(.NODE[OPR2]) THEN 1 ELSE 2 ELSE 3; IF GENTHEN THEN BEGIN SDTD_.DYTEMPS; CODE(THENPART,FULLWD); IF .NODE[NSRFRF] THEN (SETNOPUSHVT; GENMOVE(.THENPART,MYTEMP); RESETPUSHVT); L_GENLABEL(); EMIT(PBR,.L,0); DYTEMPS_.SDTD; END ELSE PLACELABEL(NODELABEL(.THENPART)); IF GENELSE THEN BEGIN CODE(ELSEPART,FULLWD); IF .NODE[NSRFRF] THEN (SETNOPUSHVT; GENMOVE(.ELSEPART,MYTEMP); RESETPUSHVT); END ELSE PLACELABEL(NODELABEL(.ELSEPART)); IF GENTHEN THEN PLACELABEL(.L); CODELST(.NODE[OPR5]); STARTFREE(.NODE[OPR1],.NODE[OPR5]); CHECKFORFLOW; .NODE END; CODER(GSELECT) LOCAL TN,FO,L; TN_.NODE[OPERAND(.NODE[NODESIZEF]-2)] AND #777777; FO_CLITVALUE(.NODE[LASTOPERAND]); CODE(NODE[OPR1],FULLWD); IF .NODE[NSRFF] NEQ RFNONE THEN IF NOT .NODE[ROTHER] THEN EMIT(PMOV,GMA(MAKLIT(-1)),GMA(MYTEMP)); IF .FO NEQ 0 THEN EMIT(PCLR,GMA(.TN),0); INCR I FROM 1 TO .NODE[NODESIZEF]-4 BY 2 DO BEGIN MACRO PROCEED=EXITBLOCK$, THISOP=NODE[OPERAND(.I)]$; L_GENLABEL(); IF .THISOP EQL LEXOTHERWISE THEN BEGIN IF .I GTR .FO THEN PROCEED; EMIT(PTST,GMA(.TN),0); EMIT(PBGT,.L,0); END ELSE IF .THISOP NEQ LEXALWAYS THEN BEGIN LOCAL SVLON,SVFON; CODE(THISOP,FULLWD); SVLON_.LON; SVFON_.FON; IF .(THISOP) EQL GTTYP THEN (LON_.GT[.THISOP,LONF]; FON_.GT[.THISOP,FONF]); GENCOMPARE(.NODE[OPR1],.THISOP,SEQLOP,0,.L,0); LON_.SVLON; FON_.SVFON END; CODE(NODE[OPERAND(.I+1)],FULLWD); IF .NODE[NSRFF] NEQ RFNONE THEN (SETNOPUSHVT; GENMOVE(.NODE[OPERAND(.I+1)],MYTEMP); RESETPUSHVT); IF .I LSS .FO THEN EMIT(PADD,GMA(MAKLIT(1)),GMA(.TN)); PLACELABEL(.L); END; CHECKFORFLOW; .NODE END; CODER(GMOVP) CODE(NODE[OPR1],FULLWD); EMIT(PMFPI+LITVALUE(.NODE[OPR2]),GMA(.NODE[OPR1]),0); CHECKFORFLOW; .NODE END; CODER(GSIGNAL) CODE(NODE[OPR1],FULLWD); GENMOVE(.NODE[OPR1],MYTEMP); IF .SIGLAB EQL 0 THEN BEGIN SIGLAB_GENLABEL(); PLACELABEL(.SIGLAB); EMIT(PJMP,GMA(.LXSIGL),0) END ELSE EMIT(PBR,.SIGLAB,0); .NODE END; CODER(GENABLE) LOCAL GTVEC N,L,LEXIT; N_.NODE[OPR1]; EMIT(PMOV,GMA(MAKLIT(XLO(LITVALUE(.NODE[OPR2]))+6)),MYTEMP); EMIT(PJSR,PROGCTR,GMA(.LXENAB)); L_GENLABEL(); LEXIT_GENLABEL(); IF NOT .SEGSW THEN EMIT(PCASE,.LEXIT,.L) ELSE (REGISTER CC; CC_NEWCODECELL(); PUTCODE(.CC,UNUSED,PJMP,REFLABEL(.LEXIT,.CC,UNUSED),0); REFLABEL(.L,.BRAK1,UNUSED)); PLACELABEL(.L); IF .DEBFLG THEN BEGIN LXY612[PRNEXF]_TRUE; EMIT(PJSR,PROGCTR,GMA(.LXY612)); END; BEGIN MACRO DONE=EXITBLOCK$; INCR I FROM 1 TO .N[NODESIZEF]-4 BY 2 DO BEGIN IF .N[OPERAND(.I)] EQL LEXALWAYS THEN (CODE(N[OPERAND(.I+1)],FULLWD); DONE); CODE(N[OPERAND(.I)],FULLWD); L_GENLABEL(); GENCOMPARE(.N[OPERAND(.I)],.LXSIGV,SEQLOP,0,.L,0); CODE(N[OPERAND(.I+1)],FULLWD); PLACELABEL(.L); END; EMIT(PJMP,GMA(.LXSIG1),0); END; PLACELABEL(.LEXIT); .NODE END; CODER(GLABEL) LOCAL STVEC LAB; LAB_.NODE[OPR2]; LAB[LABCELLF]_0; CODE(NODE[OPR1],FULLWD); IF .NODE[NSRFF] NEQ RFNONE THEN GENMOVE(.NODE[OPR1],MYTEMP); ADJUSTSTACK; PLACELABEL(USERLABEL(.LAB)); CHECKFORFLOW; .NODE END; ROUTINE GLOOP(NODE,XBR)= BEGIN MAP GTVEC NODE; LOCAL L; STOPFREE(.NODE[OPR1],.NODE[OPR2]); XBR_#477747676766^(.XBR*3); CODELST(.NODE[OPR1]); CODELST(.NODE[OPR2]); IF .XBR<33,1> THEN PLACELABEL(L_GENLABEL()); IF .XBR<35,1> THEN CODE(NODE[OPR3],FULLWD); IF .XBR<34,1> THEN CODE(NODE[OPR4],FULLWD); IF .XBR<33,1> THEN EMIT(PBR,.L,0); CODE(NODE[OPR5],FULLWD); IF .NODE[NSRFF] NEQ RFNONE THEN EMIT(PMOV,GMA(MAKLIT(-1)),GMA(MYTEMP)); STARTFREE(.NODE[OPR1],.NODE[OPR2]); CHECKFORFLOW; .NODE END; MACRO DLC(X)= (IF ISLIT(X) THEN (CLITVALUE(X) AND 1) ELSE 2)$; CODER(GWD) GLOOP(.NODE,0+DLC(.NODE[OPR3])) END; CODER(GUD) GLOOP(.NODE,3+DLC(.NODE[OPR3])) END; CODER(GDW) GLOOP(.NODE,6+DLC(.NODE[OPR4])) END; CODER(GDU) GLOOP(.NODE,9+DLC(.NODE[OPR4])) END; ROUTINE GID(NODE,WHICH)= BEGIN MACRO STDTST= BEGIN EMIT(PCMP,GMA(.NODE[OPR1]),GMA(.NODE[OPR3])); EMIT(IF .WHICH THEN PBGE ELSE PBLE,.L1,0); END$; MAP GTVEC NODE; LOCAL L1,L2,STVEC T,T2,T3; STOPFREE(.NODE[OPR5],.NODE[OPR6]); L1_GENLABEL(); L2_GENLABEL(); T_1; CODE(NODE[OPR2],FULLWD); !!! T2_NOTECODE(); CODE(NODE[OPR3],FULLWD); CODE(NODE[OPR4],FULLWD); CODELST(.NODE[OPR5]); CODELST(.NODE[OPR6]); !!! T3_NOTECODE(); GENMOVE(.NODE[OPR2],.NODE[OPR1]); %< IF ISLIT(.NODE[OPR3]) THEN IF NOT ISLIT(.NODE[OPR2]) THEN >% IF CLITVALUE(.NODE[OPR3]) EQL 0 THEN %< IF NOT ANYCODESINCE(.T3) THEN IF ANYCODESINCE(.T2) THEN >% EMIT(PTST,GMA(.NODE[OPR1]),0); IF ISLIT(.NODE[OPR2]) THEN IF ISLIT(.NODE[OPR3]) THEN BEGIN T2_CLITVALUE(.NODE[OPR2]); T2_EXTENDBIT(.T2,16); T3_CLITVALUE(.NODE[OPR3]); T3_EXTENDBIT(.T3,16); IF .WHICH THEN (IF .T2 GEQ .T3 THEN T_0) ELSE (IF .T2 LEQ .T3 THEN T_0) END; IF .T THEN EMIT(PBR,.L2,0); PLACELABEL(.L1); CODE(NODE[OPR7],FULLWD); EMIT(IF .WHICH THEN PSUB ELSE PADD,GMA(.NODE[OPR4]),GMA(.NODE[OPR1])); PLACELABEL(.L2); IF ISLIT(.NODE[OPR3]) THEN BEGIN LOCAL L; L_EXTENDBIT(CLITVALUE(.NODE[OPR3]),16); IF ABS(.L)-.WHICH EQL #77777 THEN EMIT(PBR,.L1,0) ELSF .L EQL 0 THEN EMIT(IF .WHICH THEN PBPL ELSE PBLE,.L1,0) ELSF .WHICH AND .L EQL 1 THEN EMIT(PBGT,.L1,0) ELSF NOT .WHICH AND .L EQL -1 THEN EMIT(PBMI,.L1,0) ELSE STDTST; END ELSE STDTST; IF .NODE[NSRFF] NEQ RFNONE THEN EMIT(PMOV,GMA(MAKLIT(-1)),GMA(MYTEMP)); STARTFREE(.NODE[OPR5],.NODE[OPR6]); CHECKFORFLOW; .NODE END; CODER(GINCR) GID(.NODE,0) END; CODER(GDECR) GID(.NODE,1) END; ROUTINE NOTEREGS(RNAME)= BEGIN MAP GTVEC RNAME; RNAME[REGSTOSAVE]_(.REGSCHNGD AND NOT .RESERVED) AND ((1^6)-1) END; ROUTINE FIXFORMALS(N,CURS,E) = BEGIN MAP STVEC CURS; LCCROUT(NXTLCC,NEXTF,CODEP); ROUTINE FF(A,N)= BEGIN MAP STVEC A; IF .A[ANAMET] EQL FORMALNAME THEN BEGIN A[ANAMET]_NORMNAME; A[AOFFSET]_AOFFSETV(A)+.N END END; WHILE (CURS_NXTLCC(.CURS)) NEQ .E DO CASE .OPERTYPE[.CURS[OPF]] OF SET 0; FF(SRCP(.CURS),.N); (FF(SRCP(.CURS),.N); FF(DSTP(.CURS),.N)); FF(SRCP(.CURS),.N); FF(DSTP(.CURS),.N); 0; 0; 0; 0 TES END; MACRO ! COPIED FROM FLOW.BEG LDATITEM(I) = 1,I,18,18$, RDATITEM(I) = 1,I, 0,18$; CODER(GBODY) LOCAL GTVEC RNAME:LNKAGE,BNCELL,ENCELL,BLOC,ELOC,LB,NR,LX; REGISTER LNKTYPE; BIND INLINSAVPLIT=PLIT(0,0,1,1,1,1,1,0,0); BIND T=CODENAME[3]; MACRO GETRESULT=GENMOVE(.NODE[OPR1],MYTEMP)$, POF2(X) =(((X) AND -(X)) EQL (X))$, INLINSAV =(.DEBFLG OR .ZIPSW OR POF2(.RNAME[REGSTOSAVE]))$, CNDPOPR =(IF INLINSAV THEN POPREGS)$, POPREGS =(DECR I FROM 5 TO 0 DO IF (.RNAME[REGSTOSAVE] AND 1^(.I)) NEQ 0 THEN EMIT(PMOV,POPPED,XREG(.I)))$, SAVREGS =(INCR I FROM 0 TO 5 DO IF (.RNAME[REGSTOSAVE] AND 1^(.I))NEQ 0 THEN (NR_.NR+1; EMIT(PMOV,XREG(.I),PUSHED)))$, CALLSAV =(IF INLINSAV THEN SAVREGS ELSE BEGIN BIND VECTOR SAVN=PLIT(LXSAV2,LXSAV3,LXSAV4,LXSAV5); LOCAL HR,STVEC LEX; HR_35-FIRSTONE(.RNAME[REGSTOSAVE]); NR_.HR+1; LEX_@(.SAVN[.HR-2]); LEX[PRNEXF]_TRUE; EMIT(PJSR,REG1,GMA(.LEX)); END;)$, MOVREGFORMALS=BEGIN LOCAL LSTHDR L,ITEM I,A,B; I_L_.RNAME[REGFORMLST]; UNTIL (I_.I[RLINK]) EQL .L DO BEGIN A_XREG(.I[LDATITEM(1)]); B_GMA(.I[RDATITEM(1)]); IF .A NEQ .B THEN EMIT(PMOV,.A,.B); END; END$, RTSPC =IF NOT .DEBFLG THEN EMIT(PRTS,PROGCTR,0) ELSE (LXX612[PRNEXF]_TRUE; EMIT(PJMP,GMA(.LXX612),0))$, RTSR5 =EMIT(PRTS,REG5,0)$, RTI =(IF .DEBFLG THEN EMIT(PJSR,PROGCTR,GMA(.LXX612)); EMIT(PRTI,0,0))$, PL =BEGIN IF .DYTEMPS NEQ 0 THEN EMIT(PADD,GMA(MAKLIT(.DYTEMPS)),STACKPTR); PLACELABEL(.LX); END$, ALLOCATELOCALS=IF .LB NEQ 0 THEN EMIT(PSUB,GMA(MAKLIT(.LB)),STACKPTR)$, RELLOCALS=( IF .LB NEQ 0 THEN EMIT(PADD,GMA(MAKLIT(.LB)),STACKPTR); NODE[DTDELETE]_.DYTEMPS)$; LOC_100; BNCELL_.NCELL; NR_0; RNAME_.NODE[OPR2]; LNKAGE_.RNAME[LNKGNMF]; LNKTYPE_.LNKAGE[LNKGTF]; NODE[LABELF]_LX_GENLABEL(); IF .RNAME[UNIQBIT] THEN (T_.RNAME[UNIQENAMEF]; CODENAME[2]_ (IF .RNAME[TYPEF] EQL ROUTINET THEN .T ELSE -.T)); CODENAME[0]_.NT[.RNAME[NAMEPTR],ACCUM1]; CODENAME[1]_.NT[.RNAME[NAMEPTR],ACCUM2]; CODENAME[4]_.RNAME; MOVREGFORMALS; CODE(NODE[OPR1],FULLWD); LB_.MAXLOCALS+.STATICSIZE+(.VTEMPS[MAXD]+1)*2; NOTEREGS(.RNAME); IF .LNKTYPE NEQ INTRRPTLNKGT THEN BEGIN RNAME[REGSTOSAVE]_.RNAME[REGSTOSAVE] AND (NOT(1)); GETRESULT END; PL; RELLOCALS; IF .INLINSAVPLIT[.LNKTYPE] THEN POPREGS ELSE CNDPOPR; CASE .LNKTYPE OF SET %0% 0; %1% RTSPC; %2% RTI; %3% RTSR5; %4% RTI; %5% RTI; %6% RTI; %7% RTSPC; %8% RTSPC TES; ENCELL_.NCELL;ELOC_.LOC;NCELL_.BNCELL;LOC_0; IF .DEBFLG THEN (LXE612[PRNEXF]_TRUE; EMIT(PJSR,PROGCTR,GMA(.LXE612))); IF .INLINSAVPLIT[.LNKTYPE] THEN SAVREGS ELSE CALLSAV; ALLOCATELOCALS; NODE[LABELF]_0; NCELL_.ENCELL; LOC_.ELOC; NR_(.NR+.VTEMPS[MAXD]+1)*2; FIXFORMALS(.NR,.BRAK1,.NCELL); .NODE END; CODER(GLEAVE) LOCAL GTVEC LAB:LABNODE, K; LAB_.NODE[OPR2]; LABNODE_.LAB[LINKFLD]; CODE(NODE[OPR1],FULLWD); IF .LABNODE[NSRFF] NEQ RFNONE THEN GENMOVE(.NODE[OPR1],.LABNODE[REGF]); IF .DYTEMPS NEQ .LABNODE[DTDELETE] THEN EMIT(PADD,GMA(MAKLIT(.DYTEMPS-.LABNODE[DTDELETE])),STACKPTR); IF (K_LITVALUE(.NODE[OPR3])) NEQ 0 THEN POPENABLE; EMIT(PBR,USERLABEL(.LAB),0); .NODE END; CODER(GRETURN) LOCAL GTVEC R, K; R_.NODE[OPR2]; R_.R[RETLAB]; CODE(NODE[OPR1],FULLWD); IF .R[REGF] NEQ 0 THEN GENMOVE(.NODE[OPR1],.R[REGF]); IF .DYTEMPS NEQ 0 THEN EMIT(PADD,GMA(MAKLIT(.DYTEMPS)),STACKPTR); IF (K_LITVALUE(.NODE[OPR3])) NEQ 0 THEN POPENABLE; EMIT(PBR,.R[LABELF],0); .NODE END; CODER(GINLINE) BIND ILO=BUILDOPD(INLNOPDT,0,0,0); PUTCODE(NEWCODECELL(),INLINET,0,.NODE[OPR1],ILO); NCELL[INLCOM]_.NODE[ISCOMBIT]; .NODE END; !!! THE FOLLOWING ARE THE DRIVERS FOR THE NODE-SPECIFIC GENERATORS !!! ---------------------------------------------------------------- BIND GENPLIT= PLIT( ! PLIT OF GENERATOR ROUTINE NAMES GADD, ! + GSWAB, ! SWAB GBNULL, ! / GDOT, ! . GSUB, ! - (BINARY) GBNULL, ! MOD GBNULL, ! * GDOT, ! - (UNARY) GLOADNODE, ! + (UNARY) GSHIFT, ! ^ GBIT, ! BIT GREL, ! GTR GREL, ! LEQ GREL, ! LSS GREL, ! GEQ GREL, ! EQL GREL, ! NEQ GDOT, ! NOT, GEQV, ! EQV GAND, ! AND GOR, ! OR GXOR, ! XOR 0, ! FADR 0, ! FDVR 0, ! FIX 0, ! FLOAT 0, ! FMPR 0, ! FNEG 0, ! FSBR GREL, ! GTRU GREL, ! LEQU GREL, ! LSSU GREL, ! GEQU GREL, ! EQLU GREL, ! NEQU GROT, ! ROT GMAXMIN, ! MAX GMAXMIN, ! MIN PUNT, ! CARRY PUNT, ! OVERFLOW GSTORE, ! _ 0, ! ERROR OPERATOR GCASE, ! CASE GNULL, ! CALL-STORE GNULL, ! CALL-PARM GWD, ! WHILE-DO GUD, ! UNTIL-DO GBODY, ! ROUTINE DEFN GCOMPOUND, ! COMPOUND GINCR, ! INCR GDECR, ! DECR GIF, ! IF GDW, ! DO-WHILE GDU, ! DO-UNTIL 0, ! CREATE 0, ! EXCHJ GSELECT, ! SELECT 0, ! EXITLOOP GLABEL, ! LABEL PLACEMENT 0, ! MODULE 0, ! PLIT GCALL, ! CALL GDOT, ! POINTER 0, ! [ GLEAVE, ! LEAVE GRETURN, ! RETURN GXNULL, ! NULL GINLINE, ! INLINE GENABLE, ! ENABLE GSIGNAL, ! SIGNAL GMOVP, ! MFPI, ETC. 0,0,0,0,0,0); ROUTINE FREEUNDER(NODE,XLON)= BEGIN MAP GTVEC NODE; BIND LEXEME LEX=NODE; LOCAL LEXEME L; BIND GTVEC LN=L; IF .PLSTCNT GTR 0 THEN RETURN; IF .LEX[LTYPF] NEQ GTTYP THEN RETURN; DECR I FROM .NODE[NODESIZEF]-1 TO 0 DO BEGIN IF (L_.NODE[OPERAND(.I)]) NEQ 0 THEN IF .L[LTYPF] EQL GTTYP THEN BEGIN LOCAL B,GTVEC A; A_B_0; IF .LN[NODEX] EQL SSTOROP THEN (A_.LN[REGF]; B_(.A NEQ 0)); IF .LN[NODEX] EQL SPLUSOP THEN (A_.LN[REGF]; IF .A GEQ 8 THEN IF .A[REQD] EQL MEMREQDB THEN IF NOT .A[TNLITBIT] THEN IF .A[REGF] GEQ 8 THEN B_(.GT[.A[REGF],TYPEF] EQL GRAPHT) ); IF .B THEN IF .A[LONLU] GEQ .XLON THEN RETURN 0; IF FREEUNDER(.L,.XLON) EQL 0 THEN EXITCOMPOUND ELSE RELEASESPACE(GT,.L,.LN[NODESIZEF]+BASEGTNODESIZE); END ELSE IF .L[LTYPF] GEQ LOWFLOLSTTYPE THEN RELLST(.L[ADDRF]); NODE[OPERAND(.I)]_0; END END; ROUTINE CODEWALK(NODE)= BEGIN MAP GTVEC NODE; LOCAL GTVEC N; BIND LEXEME L=N; IF NOT .NODE[CODED] THEN BEGIN N_FASTLEXOUT(GTTYP,.NODE[CSPARENT]); IF .L[ADDRF] EQL .NODE THEN RETURN; IF .N[CODED] THEN RETURN; IF NOT .N[DELAYED] ! N IS A BOGUS NODE THEN NONBOGUS(N); PULSECODE(.N,0); END; RETURN 0; % INCR I FROM 0 TO .NODE[NODESIZEF]-1 DO BEGIN N_.NODE[OPERAND(.I)]; IF .L[LTYPF] EQL GTTYP THEN IF .N[MUSTGENCODE] THEN CODE(.N) ELSE CODEWALK(.N) END; % NOVALUE END; ROUTINE CODE(PNODE,GOAL)= BEGIN BIND GTVEC NODE=.PNODE, LEXEME LEX=NODE; IF .LEX[LTYPF] NEQ GTTYP THEN RETURN; IF .NODE[LABELF] NEQ 0 THEN PLACELABEL(.NODE[LABELF]) ELSE IF .NODE[LABELREQDF] THEN PLACELABEL(NODELABEL(.NODE)); IF .NODE[MUSTGENCODE] THEN IF NOT(.NODE[CODED]) THEN BEGIN LOCAL SLON,SFON,SVTN,GTVEC NODE1; SLON_.LON; SFON_.FON; SVTN_.VTN; LON_.NODE[LONF]; FON_.NODE[FONF]; VTN_.NODE; NODE_(.GENPLIT[.NODE[NODEX]])(.NODE,.GOAL); ADJUSTSTACK; LON_.SLON; FON_.SFON; VTN_.SVTN; BEGIN LOCAL GTVEC NODE1; NODE1_.NODE[CSPARENT]; IF .NODE1 NEQ .LEX[ADDRF] THEN IF .NODE1[CODED] THEN EXITBLOCK; IF NOT ISCSECREATION(NODE1) THEN EXITBLOCK; DO (IF NOT .NODE1[CODED] THEN IF NOT (.NODE1[DELAYED] AND .NODE1[MUSTGENCODE]) THEN NODE1[CODED]_1) UNTIL (NODE1_.NODE1[CSTHREAD]) EQL 0; END; NODE[CODED]_1 END ELSE CHECKFORFLOW ELSE (CODEWALK(.NODE); CHECKFORFLOW); SELECT .NODE[NODEX] OF NSET SSTOROP: RETURN (IF .NODE[REGF] EQL 0 THEN FREEUNDER(.NODE,.NODE[LONF])); SPLUSOP: RETURN; SDOTOP: RETURN; SYNCOMP: RETURN; OTHERWISE: RETURN FREEUNDER(.NODE,.NODE[LONF]) TESN END; GLOBAL ROUTINE CODEDRIVER(LEX)= BEGIN MAP GTVEC LEX; EXTERNAL STVEC BRAK1:BRAK2, RELALLTNS; LOCAL ENCELL,T; CODENAME[0]_.MODNAME[0]; CODENAME[1]_.MODNAME[1]; CODENAME[2]_CODENAME[3]_CODENAME[4]_0; DYTEMPS_LOC_SAMETOG_0; SIGLAB_0; UNLOCFLG_FALSE; VTEMPS_GETSPACE(GT,10); VTEMPS[CURD]_VTEMPS[MAXD]_-1; BRAK1_NEWCODECELL(); BRAK1[OPTYPEF]_INLINET; NCELL_.BRAK1; NLHEAD_NEWLABCELL(MINLABNAM); PLSTCNT_NODVT_NOVTCNT_0; REGSCHNGD_(IF .ANYENAB THEN #77 ELSE 0); CODE(LEX,FULLWD); PLSTCNT_0; FREEUNDER(.LEX,.LEX[LONF]); VTN_.VTEMPS[MAXD]+1; IF .LEX EQL GTTYP THEN RELEASESPACE(GT,.LEX,.LEX[NODESIZEF]+BASEGTNODESIZE); IF .DEBFLG THEN LXHLTB[PRNEXF]_1; IF .MODDONE THEN BEGIN ENCELL_.NCELL; NCELL_.BRAK1; IF (T_.MAXLOCALS+.STATICSIZE+.VTN*2) NEQ 0 THEN EMIT(PSUB,GMA(MAKLIT(.T)),STACKPTR); IF .MAINDECL AND .DEBFLG THEN BEGIN MAP STVEC LXINT612; LXINT612[PRNEXF]_TRUE; EMIT(PJSR,PROGCTR,GMA(.LXINT612)); END; NCELL_.ENCELL; END; RELEASESPACE(GT,.VTEMPS,10); IF .MODDONE AND (ANYCODESINCE(.BRAK1) OR .MAINDECL) THEN EMIT(PHALT,0,0); BRAK2_PUTCODE(NEWCODECELL(),INLINET,0,0,0); RELALLTNS() ! RELEASE ALL TNS END; END END END ELUDOM