Trailing-Edge
-
PDP-10 Archives
-
decuslib10-04
-
43,50325/code.bli
There are no other files named code.bli in the archive.
! 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<R>],3);OUTPUT(":");
OUTDEC(.A<M>,1);OUTPUT(":");OUTDEC(.A<OFS>,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>$;
[email protected]; [email protected];
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)<LTYPF> 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<ADDRF> 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<LTYPF> 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