%include "hostcodes.inc" %CONSTINTEGER HOST=M88K %CONSTINTEGER TARGET=RS6 ! ! Warning this module has the revised triples spec. ! ! In first attempt at Triple Imp considerable use was made of constant operands ! to pass information from Pass2 to GEN. Although for specialised operations like ! passing Labels this still applies, this adhocery has caused problems with arrays ! and pointers particularly in mapped records. The operands for four triples ! have thus been redefined in a more standard way. ! ! GETPTR X1 is now (ptype of passed)<<16! DIMENSION ! Opnd2 is either a 32 bit const with the size (ACC) as value or ! the ptr or arrayhead as normal operand. ! ! VMY X1 is now dim<<28!maxdim<<24!array name(where known) ! Opnd2 is either a 32 bit const with DV offset into const area or ! the arrayhead as a standard operand ! ! AINDX X1 is ELSIZE<<20 !spare ! Opnd2 is arrayhead as standard operand ! NOTE:- The Operands have been swopped for consistency with norm. ! ! BADJ X1 is arrayptype<<16!no of Dimensions (latter in case of backward dvs) ! Opnd2 exactly as for VMY ! ! ! RECORDFORMAT FOR ALL THE OPTION AND FLAG VARAIBLES ! ! amended to remove non-alined longreal prior to bootstrapping to gould ! %RECORDFORMAT PARMF(%INTEGER BITS1,BITS2,TTOPUT, %BYTEINTEGER LET,DYNAMIC,LINE,TRACE,ARR,DBUG,CHK,DIAG,OPT,FREE, LIST,CPRMODE,COMPILER,Z,Y,PROF,INHCODE,DCOMP,FAULTY,X,STACK,MAP,QUOTES,S2, %INTEGER LPOPUT,SP0) %RECORDFORMAT LEVELF(%INTEGER RBASE, DIAGINF, RAL, FLAG, L, M, NMDECS, ONWORD, ONINF, LABEL, JROUND, UNATT FORMATS, PSIZE, ENTRYAD, DISPLAY, AUXSBASE, NAMES, SNMAX,SN,RESSIZE,CLEVEL,SET, MAXPP, EXITLAB, CONTLAB, S3, %INTEGERARRAY AVL WSP(0:4)) %IF 1<>4&15; OP=FLAG %RETURN %IF 1<URSW(OP) %ELSE ->UISW(OP) %FINISH OP=OP-128 %RETURN %IF OP>47 %if opnd2_ptype&8#0 %then %return EXTRACT(OPND2) VAL2=VAL; RVAL2=RVAL; STRVAL2=STRVAL SVAL2<-VAL2 TRUNCMASK=BTRUNCMASK %IF TYPEP=2 %THEN ->BRSW(OP) %ELSE ->BISW(OP) UISW(10): ! \ VAL1=\VAL1 INTEND: %IF 1<>32 OPND1_XTRA<-VAL1 FLAG=0 %FINISH %ELSE %START SVAL<-VAL1 %IF SVAL=VAL1 %OR 1<INT END UISW(13): ! INTEGER ABS VAL1=IMOD(VAL1); ->INT END UISW(12): ! INTEGER FLOAT RVAL1=VAL1; PRECP=PRECP+1 ->REAL END URSW(15): ! STRETCH REAL PRECP=PRECP+1 REAL END:OPND1_FLAG=SCONST %IF PRECP=5 %THEN OPND1_R=RVAL1 %ELSE %IF PRECP=6 %THEN %START LR=RVAL1; ! may be rounding MOVE BYTES(8,ADDR(LR),0,ADDR(OPND1_D),0) %FINISH %ELSE %START OPND1_FLAG=LCONST OPND1_D=WORKA_ARTOP OPND1_XTRA=INTEGER(ADDR(RVAL1)) WORKA_ARTOP=WORKA_ARTOP+16 MOVE BYTES(16,ADDR(RVAL1),0,ADDR(WORKA_A(0)),OPND1_D) %FINISH FLAG=0; OPND1_PTYPE=16*PRECP+2 %RETURN UISW(15): ! STRETCH INTEGER %IF 1<INT END %IF PRECP=4 %THEN PRECP=5 %AND ->INT END %RETURN UISW(14): ! SHORTEN INTEGER %if precp=4 %and 0<=val1<=255 %then precp=3 %and ->int end %IF PRECP=5 %and IMOD(VAL1)<=X'7FFF' %THEN PRECP=4 %AND ->INT END %IF PRECP=6 %AND VAL1=SVAL1 %THEN PRECP=5 %AND ->INT END %RETURN URSW(14): ! SHORTEN REAL PRECP=PRECP-1 ->REAL END URSW(12): ! FLOAT REAL IMPABORT UISW(16): ! SHORTEN FOR <- %IF PRECP=5 %THEN VAL1=VAL1&X'FFFF' %AND PRECP=4 %AND ->INTEND %RETURN URSW(36): ! INT %RETURN %UNLESS MOD(RVAL1)INTEND URSW(37): ! INTPT %RETURN %UNLESS MOD(RVAL1)INTEND UISW(38): ! TOSTRING STRVAL1=TOSTRING(VAL1) ->STREND URSW(48): ! TRUNC coded without using itself as it ! it is not provided in the older compilers %RETURN %UNLESS MOD(RVAL1)=0 %THEN VAL1=INTPT(RVAL1) %ELSE VAL1=-INTPT(MOD(RVAL1)) PRECP=5 ->INTEND BISW(0): ! ADD BISW(14): ! COMBINE VMY RESULTS VAL1=VAL1+VAL2; ->INT END BISW(1): ! MINUS VAL1=VAL1-VAL2; ->INT END BISW(2): ! EXCLUSIVE OR VAL1=VAL1!!VAL2; ->INT END BISW(3): ! OR VAL1=VAL1!VAL2; ->INT END BISW(4): ! MULT VAL1=VAL1*VAL2; ->INT END BISW(6):%RETURN; ! / DIVISION BISW(5):%RETURN %IF VAL2=0; ! // DIVISION VAL1=VAL1//VAL2; ->INT END BISW(7): ! AND VAL1=VAL1&VAL2; ->INT END BISW(9): ! SLL %IF PRECP=6 %THEN VAL1=VAL1<INT END BISW(8): ! SRL %IF PRECP=6 %THEN VAL1=VAL1>>SVAL2 %ELSE VAL1=SVAL1>>SVAL2 ->INT END BISW(13): ! VMY & CHK BOUNDS MAXD=XTRA>>24&15; ! MAX DIMENSION C=XTRA>>28; ! DIMENSION D=OPND2_D&X'FFFF'; ! DV POINTER %IF TARGET=PNX %OR TARGET=PERQ %OR TARGET=ACCENT %OR 1<UB %THEN FAULT(50,VAL1,XTRA&X'FFFF') VAL1=VAL1*MP %UNLESS C=1 ->INT END %FINISH %IF TARGET=EMAS %START C=3*(MAXD+1-C) JJ=(VAL1-WORKA_CTABLE(D+C))*WORKA_CTABLE(D+C+1) %IF JJ<0 %OR JJ>WORKA_CTABLE(D+C+2) %THEN FAULT(50,VAL1,XTRA&X'FFFF') VAL1=JJ ->INT END %FINISH %IF TARGET=IBM %OR TARGET=AMDAHL %OR TARGET=IBMXA %START %IF VAL1WORKA_CTABLE(D+3*C+1) %THEN FAULT(50,VAL1,XTRA&X'FFFF') VAL1=VAL1*WORKA_CTABLE(D+3*C+2) ->INTEND %FINISH %RETURN BISW(18): ! BADJ ADUST ARRAY BASE %IF TARGET=PERQ %OR 1<>24&15; ! TOTAL NO OF DIMENSIONS KK=VAL2; ! DV DISP %RETURN %UNLESS KK>0 JJ=DEBYTESWOP(WORKA_CTABLE(KK));! adjustment VAL1=VAL1+JJ %FINISH ->INT END BISW(46): BISW(47): ! scomp & sdcomp BRSW(46): BRSW(47): ! scomp & sdcomp BISW(11): BISW(12): ! COMPARISONS BRSW(11): BRSW(12): ! REAL COMPARISONS MASK=XTRA; ! XTRA HAS IBM TYPE MASK ! RETURN MASK AS 15(=JUMP) OR 0 (IGNORE) FLAG=0 %IF TYPEP=2 %THEN ->RCOMP %IF TYPEP=5 %THEN ->SCOMP %IF (MASK&8#0 %AND VAL1=VAL2) %OR (MASK&4#0 %AND VAL1VAL2) %THEN MASK=15 %ELSE %C MASK=0 %if op=12{dsided} %then opnd1=opnd2 %RETURN RCOMP: %IF (MASK&8#0 %AND RVAL1=RVAL2) %OR (MASK&4#0 %AND RVAL1RVAL2) %THEN %C MASK=15 %ELSE MASK=0 %if op=12{dsided} %then opnd1=opnd2 %RETURN SCOMP: %IF (MASK&8#0 %AND STRVAL1=STRVAL2) %OR (MASK&4#0 %AND STRVAL1STRVAL2) %THEN MASK=15 %ELSE MASK=0 %if op=47{dsided} %then opnd1=opnd2 %RETURN URSW(11): ! NEGATE RVAL1=-RVAL1; ->REAL END BRSW(13): ! ABS RVAL1=MOD(RVAL1); ->REAL END BRSW(0): ! ADD RVAL1=RVAL1+RVAL2; ->REAL END BRSW(1): ! SUBTRACT RVAL1=RVAL1-RVAL2; ->REAL END BRSW(4): ! MULT RVAL1=RVAL1*RVAL2; ->REAL END BRSW(6): ! DIVISION %RETURN %IF RVAL2=0; ! AVOID DIV BY ZERO RVAL1=RVAL1/RVAL2; ->REAL END BISW(10): ! '**' WITH 2 INTEGER OPERANDS BRSW(10): ! '**' WITH AT LEAST 1 REAL %RETURN %UNLESS OPND2_PTYPE&7=1 %AND-77<=VAL2<=75 ! RVAL1=RVAL1**VAL2 ! ! avoid exponentiation in case a support routine reqd ! RVAL2=1 rval2=rval2*rval1 %for jj=1,1,imod(val2) %if val2<0 %then rval1=1.0/rval2 %else rval1=rval2 ->REALEND BISW(17): ! '****' WITH 2 INTEGER OPERAND %RETURN %UNLESS 0<=VAL2<=63 VAL2=1 %WHILE SVAL2>0 %CYCLE VAL2=VAL2*VAL1 SVAL2=SVAL2-1 %REPEAT VAL1=VAL2; ->INT END BISW(24): ! CONCAT %RETURN %IF LENGTH(STRVAL1)+LENGTH(STRVAL2)>255 STRVAL1=STRVAL1.STRVAL2 STREND: ! RETURN VALUE OPND1_PTYPE=X'35' OPND1_FLAG=LCONST OPND1_XTRA=LENGTH(STRVAL1) JJ=WORKA_ARTOP WORKA_A(JJ)=OPND1_XTRA %FOR K=1,1,OPND1_XTRA %CYCLE WORKA_A(JJ+K)=CHARNO(STRVAL1,K) %REPEAT OPND1_D=JJ WORKA_ARTOP=(JJ+OPND1_XTRA+2)&(-2); ! PERQ KEEP 16 BIT ALIGNED FLAG=0 %RETURN URSW(*): UISW(*): BRSW(*): BISW(*): %RETURN %ROUTINE EXTRACT(%RECORD (RD) %NAME OPND) !*********************************************************************** !* EXTRACTS A CONTANT OPERAND RETURNING REAL &INT VALUES * !*********************************************************************** %INTEGER TYPE,PREC,I,AD TYPE=OPND_PTYPE; PREC=TYPE>>4 TYPE=TYPE&15 VAL=0; RVAL=0; STRVAL="" %IF TYPE=5 %START LENGTH(STRVAL)=WORKA_A(OPND_D) %FOR I=1,1,OPND_XTRA %CYCLE CHARNO(STRVAL,I)=WORKA_A(OPND_D+I) %REPEAT %FINISH %ELSE %IF TYPE=1 %THEN %START %IF 1<>32)) %ELSE %C VAL=OPND_D RVAL=VAL %FINISH %ELSE %START %IF PREC=5 %THEN RVAL=OPND_R %ELSE %IF PREC=6 %THEN %START MOVE BYTES(8,ADDR(OPND_D),0,ADDR(LR),0) RVAL=LR %FINISH %ELSE MOVE BYTES(16,ADDR(WORKA_A(0)),OPND_D,ADDR(RVAL),0) %FINISH %END %INTEGER %FN DEBYTESWOP(%INTEGER VAL) !*********************************************************************** !* ITEMS IN THE THE CONST TABLE MAY BE BYTE SWOPPED. DEBYTESWOP BY * !* BYTE SWOPPING AGAIN. PDS PRAYS THERE WILL NEVER BE ARCHITECTURE * !* WHERE THIS IS NOT TRUE! * !*********************************************************************** %RECORD (RD) OPND OPND=0 OPND_PTYPE=X'51' OPND_D=VAL %IF HOST#TARGET %THEN REFORMATC(OPND) %RESULT=OPND_D %END %END %EXTERNAL %ROUTINE TRIP OPT(%RECORD (TRIPF) %ARRAY %NAME TRIPLES, %INTEGER inptr) !*********************************************************************** !* SCANS A TRIPLES LIST FOR POSSIBLE OPTIMISATIONS * !*********************************************************************** %INTEGER CHANGES,DUPS,DUPTNO,PTR,I,J,K,VAL,XVAL,CURR,NEXT,OP1,OP2,CTOPOP,REVOP,APTYPE,FOLD AGAIN %BYTE %INTEGER %ARRAY %NAME A %RECORD (TRIPF) %NAME CURRT,NEWT,NEXTT %RECORD (RD) %NAME OPND1,OPND2,POPND,ROPND %ROUTINE %SPEC SWOP OPERANDS(%RECORD (TRIPF) %NAME CURRT) %INTEGER %FN %SPEC POWEROF2(%INTEGER VAL) %INTEGER %FN %SPEC PRELOAD PLACE(%INTEGER TRIP) %ROUTINE %SPEC INDOPT(%RECORD (RD) %NAME OPND) %ROUTINE %SPEC VMYOPT(%INTEGER CURR) %INTEGER %FN %SPEC SAME OPND(%RECORD (RD) %NAME OPND1,OPND2,%integer ASSN) %ROUTINE %SPEC INVERT DIV(%RECORD (TRIPF) %NAME CURRT) %ROUTINE %SPEC CHECK DUPS(%INTEGER STRIPNO,STRIPNO) %ROUTINE %SPEC PROPAGATE CASS(%INTEGER STRIPNO, %RECORD (RD) %NAME N,C) %ROUTINE %SPEC DUPLICATE TRIP(%INTEGER TRIPNO,DTRIPNO,FLAGBITS) %ROUTINE %SPEC DEC USE(%INTEGER TRIPLE NO) %ROUTINE %SPEC DELETE TRIPLE(%INTEGER TRIPLE NO) %IF TARGET=AMDAHL %OR TARGET=IBM %OR TARGET=IBMXA %START ! ON IBM VMY OF 0 ALWAYS ZERO %CONST %BYTE %INTEGER %ARRAY FOLD NOOP INFO(0:199)= 0(128), X'89',X'41',X'89',X'89',X'B6',{+,-,!!,!,*} %C 2,0,X'A4',1,1,{//,/,&,>>,<<} %C 2,0,0,32,X'89',{**,COMP,DCOMP,VMY,COMB} %C 0,0,2,0,0,{=,<-,****,BADJ,INDEX} %C 0{IFETCH},0(3), X'40'{CONCAT},0(*) %FINISH %ELSE %IF TARGET=EMAS %START ! INDEX IS NOT NECESSARILY A NOOP WHEN INDEX IS 0 ! %CONST %BYTE %INTEGER %ARRAY FOLD NOOP INFO(0:199)= 0(128), X'89',X'41',X'89',X'89',X'B6',{+,-,!!,!,*} %C 2,0,X'A4',1,1,{//,/,&,>>,<<} %C 2,0,0,3,X'89',{**,COMP,DCOMP,VMY,COMB} %C 0,0,2,0,0,{=,<-,****,BADJ,INDEX} %C 0{IFETCH},0(3), X'40'{CONCAT},0(*) %FINISH %ELSE %START %CONST %BYTE %INTEGER %ARRAY FOLD NOOP INFO(0:199)= 0(128), X'89',X'41',X'89',X'89',X'B6',{+,-,!!,!,*} %C 2,0,X'A4',1,1,{//,/,&,>>,<<} %C 2,0,0,3,X'89',{**,COMP,DCOMP,VMY,COMB} %C 0,0,2,0,1,{=,<-,****,BADJ,INDEX} %C 0{IFETCH},0(3), X'40'{CONCAT},0(*) %FINISH ! 2**0 SET IF SECOND OPERAND ZERO IS NOOP ! 2**1 SET IF SECOND OPERAND 1 IS A NOOP ! 2**2 SET IF SECOND OPERAND 0 MEANS RESULT=0 ! 2**3 SET IF FIRST OPERAND ZERO IS NOOP ! 2**4 SET IF FIRST OPERAND 1 IS A NOOP ! 2**5 SET IF FIRST OPERAND ZERO MEANS RESULT=0 ! 2**6 SET IF FOLDING WITH ITSELF POSSIBLE BUT NOT SIMPE ! 2**7 SET FOR NORMAL FOLDING ! A==WORKA_A CHANGES=0; ! NO CHANGES AS YET DUPS=0; ! NO DUPLICATES YET %if parm_dcomp#0 %then printstring("Optimising triples ") %and print trips(triples) ! ! LOOK FOR REGISTER TO STORE OPERATIONS ON EMACHINES (xcept VNS and risk) ! PTR=inptr %WHILE PTR>0 %CYCLE CURRT==TRIPLES(PTR) PTR=CURRT_FLINK NEXTT==TRIPLES(PTR) %EXIT %IF PTR=0; ! THE END %UNLESS NEXTT_OPERN=VASS %AND NEXTT_OPTYPE=X'51'=CURRT_OPTYPE %AND (NEXTT_OPND1_FLAG=DNAME %OR %C NEXTT_OPND1_FLAG=INDNAME %or NEXTT_OPND1_FLAG=arname) %AND NEXTT_OPND2_FLAG=REFTRIP %AND CURRT_PUSE=PTR %AND CURRT_CNT=1 %THEN %C %CONTINUE %CONTINUE %UNLESS ADD<=CURRT_OPERN<=ANDL; ! lshift & rshift also possible on pnx %IF CURRT_FLAGS&COMMUTABLE#0 %AND SAME OPND(CURRT_OPND2,NEXTT_OPND1,NO)=YES %THEN %C SWOP OPERANDS(CURRT) %ELSE %START %CONTINUE %UNLESS SAME OPND(CURRT_OPND1,NEXTT_OPND1,NO)=YES %FINISH NEXTT_X1=CURRT_OPERN NEXTT_OPERN=RSTORE NEXTT_PUSE=0 NEXTT_FLAGS<-DONT OPT!CURRT_FLAGS&(\LOAD OP1); ! THIS AVOIDS A USELESS PRELOAD NEXTT_opnd2=CURRT_opnd2 triples(NEXTT_BLINK)_opern=NULLT changes=changes+1 %REPEAT %IF CHANGES>0 %AND PARM_DCOMP#0 %THEN PRINT TRIPS(TRIPLES) WORKA_OPTCNT=WORKA_OPTCNT+CHANGES %RETURN %INTEGER %FN POWEROF2(%INTEGER VAL) !*********************************************************************** !* CHECKS IF VAL IS A POWER OF 2 * !*********************************************************************** %INTEGER I,J %FOR I=1,1,30 %CYCLE J=1<VAL %THEN %RESULT=0 %REPEAT %RESULT=0 %END %ROUTINE SWOP OPERANDS(%RECORD (TRIPF) %NAME CURRT) !*********************************************************************** !* EXCHANGE OPND1&OPND2 KEEPING THE FLAGS CORRECT * !*********************************************************************** %RECORD (RD) TOPND %INTEGER FLAGS,NEWFLAGS TOPND=CURRT_OPND1 CURRT_OPND1=CURRT_OPND2 CURRT_OPND2=TOPND FLAGS=CURRT_FLAGS NEWFLAGS=FLAGS&(\(LOADOP1+LOADOP2)) %IF FLAGS&LOADOP1#0 %THEN NEWFLAGS=NEWFLAGS!LOADOP2 %IF FLAGS&LOADOP2#0 %THEN NEWFLAGS=NEWFLAGS!LOADOP1 CURRT_FLAGS=NEWFLAGS CHANGES=CHANGES+1 %END %INTEGER %FN PRELOAD PLACE(%INTEGER TRIP) !*********************************************************************** !* LOOK FOR FIRST TRIPLE IN THE CHAIN THAT LEADS TO TRIP * !* CAN BE VERY COMPILCATED. RETURN -1 IF NOT SIMPLE * !*********************************************************************** %CONST %INTEGER TRIPREFS=X'140'; ! BITMASK OF OPERAND FORMATS %RECORD (RD) %NAME OPND1,OPND2 %RECORD (TRIPF) %NAME CURRT CURRT==TRIPLES(TRIP) OPND1==CURRT_OPND1 OPND2==CURRT_OPND2 %IF CURRT_OPERN<128 %OR 1<>4<6 %IF RTRIP_OPND1_FLAG<=1 %THEN %START COP=1; ! CONSTANT IS OP 1 COPND==RTRIP_OPND1; ! DEFINED BY COPND %ELSE COP=2; ! CONSTANT IS OPERAND 2 COPND==RTRIP_OPND2 %FINISH X=OPND_XTRA; ! CURRENT OFFSET %IF X<0 %THEN X=0 VAL=COPND_D %IF OP=ADD %AND LIMIT>X+VAL>=0 %THEN COPND_D=0 %AND OPND_XTRA=X+VAL %AND %RETURN ! THE ZERO ADD WILL BE ELAIMINATED %IF OP=SUB %AND LIMIT>X-VAL>=0 %AND COP=2 %THEN COPND_D=0 %AND OPND_XTRA=X-VAL %END %ROUTINE VMYOPT(%INTEGER CURR) !*********************************************************************** !* ANALYSES A VMY AND REPACES WITH A CONSTANT MULTIPLY IF POSSIBLE * !*********************************************************************** %RECORD (TRIPF) %NAME CURRT %RECORD (RD) %NAME OPND2 %INTEGER C,D,VALUE,APTYPE,DV,I,J,DVNAME CURRT==TRIPLES(CURR) OPND2==CURRT_OPND2 C=CURRT_X1>>28; ! CURRENT DIMENSION D=CURRT_X1>>24&15; ! MAX DIMENSION DV=0 %IF OPND2_FLAG=SCONST %THEN DV=OPND2_D; ! DOPE VECTOR IF CONST %IF (TARGET=PNX %OR TARGET=PERQ %OR TARGET=ACCENT) %AND C=1 %THEN VALUE=1 %AND ->TOMULT APTYPE=-1; ! ARRAY PTYPE DVNAME=CURRT_X1&X'FFFF' %IF DVNAME>0 %THEN APTYPE=WORKA_ASLIST(WORKA_TAGS(DVNAME))_PTYPE %IF TARGET=EMAS %START %IF DV>0 %START I=3*(D+1-C) %IF WORKA_CTABLE(DV+I)=0 %THEN VALUE=WORKA_CTABLE(DV+I+1) %AND ->TOMULT %FINISH %IF APTYPE>>8=2 {ARR=2,NAM=0} %AND C=1 %AND APTYPE&7<=2 %AND APTYPE&255#X'41' %THEN VALUE=1 %AND ->TOMULT %FINISH %IF TARGET=IBM %OR TARGET=AMDAHL %OR TARGET=IBMXA %START %IF C=1=D %AND CURRT_OPND1_FLAG=REFTRIP %THEN IBMVMY(CURR) %IF OPND1_FLAG=SCONST %AND OPND1_D=0 %THEN VALUE=1 %AND ->TOMULT ! ANY VMY OF 0 =0 ON IBMS %IF DV>0 %THEN VALUE=WORKA_CTABLE(DV+3*C+2) %AND ->TOMULT %IF C=1 %START %IF APTYPE&7<=2 %THEN VALUE=BYTES(APTYPE>>4&7) %AND ->TOMULT %IF APTYPE&X'0C00'=0 %START; ! NAM=0 %IF DVNAME>0 %THEN VALUE=WORKA_ASLIST(WORKA_TAGS(DVNAME))_ACC %AND ->TOMULT %FINISH %FINISH %FINISH %RETURN TOMULT: ! CHANGE VMY TO INTEGER MULT CURRT_OPERN=MULT CURRT_FLAGS=CURRT_FLAGS!CONSTANT OP OPND2_PTYPE=CURRT_OPTYPE; ! SOME M-CS HAVE 16 BIT OPERATIONS OPND2_FLAG=SCONST OPND2_D=VALUE CHANGES=CHANGES+1 %END %ROUTINE DEC USE(%INTEGER TRIPLE NO) !*********************************************************************** !* A TRIPLE HAS BEEN PASSED INTO 'DEAD' CODE. DECREMENT ITS USE * !* AND IF RELEVANT DELETE OPERATIONS LEADING TO IT * !*********************************************************************** %RECORD (TRIPF) %NAME CURRT CURRT==TRIPLES(TRIPLE NO) %IF CURRT_CNT=0 %START PRINTSTRING("dec use??? ") PRINT TRIPS(TRIPLES) %MONITOR %FINISH CURRT_CNT<-CURRT_CNT-1 %IF CURRT_CNT=1 %THEN DUPS=DUPS-1 %IF CURRT_CNT=0 %AND CURRT_OPERN#RSTORE %AND CURRT_OPERN#NULLT %THEN DELETE TRIPLE(TRIPLE NO) %END %ROUTINE DELETE TRIPLE(%INTEGER TRIPLE NO) %RECORD (TRIPF) %NAME DELT DELT==TRIPLES(TRIPLE NO) %IF 1<=128 %AND 1<0 %AND PTR>0 %CYCLE CURRT==TRIPLES(PTR) PTR=CURRT_FLINK %IF CURRT_OPERN=NULLT %THEN %CONTINUE OPND1==CURRT_OPND1 OPND2==CURRT_OPND2 %IF OPND1_D=DTRIPNO %AND 1<=128 %AND OPND2_D=DTRIPNO %AND 1<>4; ! PRECISION WOPND_S1=COPND_S1 ! ! SET UP WOPND AS REAL ONE IN GIGTH PRECISION ! %IF PREC=5 %THEN WOPND_R=1.0 %ELSE %IF PREC=6 %THEN %START LR=1.0 MOVE BYTES(8,ADDR(LR),0,ADDR(WOPND_D),0) %FINISH %ELSE %START WOPND_PTYPE=X'61' WOPND_D=0 WOPND_XTRA=1 OP=IFLOAT CTOP(OP,J,0,WOPND,COPND); ! FLOAT LONG 1 TO REAL %RETURN %IF OP#0; ! NO CAN DO %FINISH OP=REAL DIV CTOP(OP,J,0,WOPND,COPND) %RETURN %IF OP#0 CURRT_OPERN=MULT CURRT_OPND2=WOPND %END %ROUTINE CHECK DUPS(%INTEGER TRIPNO,STRIPNO) !*********************************************************************** !* CHECK STARTING FROM STRIPNO FOR DUPLICATES OF TRIPNO * !* MAY BE MORE THAN ONE * !*********************************************************************** %RECORD (TRIPF) %NAME CURRT,DUPT,WORKT %RECORD (RD) AOPND,DOPND1,DOPND2,WOPND1,WOPND2 %CONST %INTEGER LMAX=4 %INTEGER %ARRAY LABS(0:LMAX) %INTEGER OP,NEXT,LPTR,I,J,CTRIPNO,OPERN,F,C11,C12,C21,C22,W12,W22,LABP DUPT==TRIPLES(TRIPNO) DOPND1=DUPT_OPND1; DOPND2=DUPT_OPND2 OPERN=DUPT_OPERN ! COMPARISONS ARE IMPOSSIBLE TO OPTIMISE ! ON CONDITION CODE MACHINES ! POSSIBLE BUT DIFFICULT ON TRUE FLAG MCS %IF OPERN=COMP %OR OPERN=DCOMP %OR OPERN=SCOMP %OR OPERN=SDCMP %THEN %RETURN %IF OPERN=PRECC %OR OPERN=CONCAT %OR OPERN=PRES1 %OR OPERN=PRES2 %THEN %RETURN %IF OPERN=PRECL %OR PASS1<=OPERN<=PASS6 %THEN %RETURN %if opern=getptr %and dupt_optype=X'61' %then %return ! two word pointers are tricky things to store and pickup F=DUPT_FLAGS LPTR=0; LABP=0 %WHILE STRIPNO>0 %CYCLE CURRT==TRIPLES(STRIPNO) %EXIT %IF CURRT_FLAGS&ASS LEVEL#0 OP=CURRT_OPERN %IF OP=FJUMP %AND LPTR<=LMAX %START J=CURRT_OPND1_D I=J&X'FFFF'; ! THE LAB NO %IF J<0 %AND I>WORKA_NNAMES %THEN LABS(LPTR)=I %AND LPTR=LPTR+1 %FINISH %IF OP=TLAB %START LABP=USED LATE; ! FLAG OPERAND IF DUPLICATE FOUND J=CURRT_OPND1_D&X'FFFF'; ! THE LAB NO %FOR I=0,1,LPTR-1 %CYCLE ->JSEEN %IF J=LABS(I) %REPEAT %EXIT; ! CAN NOT NORMALLY PASS LABES JSEEN: ! THE FIRST JUMP TO THIS LAB HAS ! BEEN PASSED. THERE ARE NO BACK JUMPS ! TO INTERNAL LABELS FIRST REFERENCED ! VIA A FORWARD JUMP %FINISH %EXIT %IF OP=RTXIT %OR OP=RCALL %EXIT %IF OP=SETSW %OR OP=AHASS %OR OP=PTRAS %OR OP=LASS %IF OP=VASS %OR OP=VJASS %or strass1<=op<=strjt %OR OP=DMASS %OR OP=RSTORE %START; ! ASSIGNMENT AOPND=CURRT_OPND1; ! DEST OF ASSIGNMENT %IF AOPND_FLAG=INDIRECT %AND (DOPND1_FLAG=INDIRECT %OR DOPND2_FLAG=INDIRECT) %START ! MAPPED ARRAYS MAKE AY ARRAY OR MAP ASSIGNMENT ! DIFFICULT TO CHECK OUT. ONLY SAFE CASE ! IS TO DIFFERENT ARRAYS BUT NOT ! IF EITHER ARE ARRAYNAMES %EXIT %FINISH %ELSE %START %EXIT %IF SAME OPND(AOPND,DOPND1,yes)=YES %EXIT %IF OPERN>=128 %AND SAME OPND(AOPND,DOPND2,yes)=YES %FINISH %FINISH %if op=getad %or op=getptr %Start aopnd=currt_opnd1 %if same opnd(aopnd,dopnd1,yes)=yes %then %exit %if opern>=128 %and same opnd(aopnd,dopnd2,yes)=yes %then %exit %finish CTRIPNO=STRIPNO STRIPNO=CURRT_FLINK %IF OP=OPERN %AND (OP#VMY %OR DUPT_X1=CURRT_X1) %START C11=SAME OPND(DOPND1,CURRT_OPND1,NO) %IF OPERN<128 %START %IF C11=YES %THEN DUPLICATE TRIP(TRIPNO,CTRIPNO,LABP) %CONTINUE %FINISH ! NOW BINARY ONES C22=SAME OPND(DOPND2,CURRT_OPND2,NO) C12=NO; C21=NO %IF F&COMMUTABLE#0 %START C12=SAME OPND(DOPND1,CURRT_OPND2,NO) C21=SAME OPND(DOPND2,CURRT_OPND1,NO) %FINISH %IF C11=YES=C22 %OR C21=YES=C12 %START DUPLICATE TRIP(TRIPNO,CTRIPNO,LABP) %CONTINUE %FINISH ! ! now check for distributed common expressions ie (a+b) %AND (a+x+b). The latter ! is changes to (a+b+x) and the common element eliminated ! %IF C12!C11!C22!C21=YES %START WORKT==TRIPLES(CURRT_PUSE) WOPND1=WORKT_OPND1; WOPND2=WORKT_OPND2 %IF OP=WORKT_OPERN %AND WORKT_CNT=1 %AND F&COMMUTABLE#0 %START W22=SAME OPND(DOPND2,WOPND2,NO) W12=SAME OPND(DOPND1,WOPND2,NO) %IF C12=YES=W22 %OR C22=YES=W12 %OR C21=YES=W12 %OR C11=YES=W22 %START %IF C12=YES %OR C22=YES %START WORKT_OPND2=CURRT_OPND1 CURRT_OPND1=WOPND2 %FINISH %ELSE %START WORKT_OPND2=CURRT_OPND2 CURRT_OPND2=WOPND2 %FINISH DUPLICATE TRIP(TRIPNO,CTRIPNO,LABP) %CONTINUE %FINISH %FINISH %FINISH %FINISH %REPEAT %END %ROUTINE PROPAGATE CASS(%INTEGER STRIPNO, %RECORD (RD) %NAME NOPND,COPND) !*********************************************************************** !* CHECK STARTING FROM STRIPNO FOR DUPLICATES OF TRIPNO * !* MAY BE MORE THAN ONE * !*********************************************************************** %RECORD (TRIPF) %NAME CURRT %RECORD (RD) AOPND %CONST %INTEGER LMAX=4 %INTEGER %ARRAY LABS(0:LMAX) %INTEGER OP,NEXT,LPTR,I,J,CTRIPNO,LABP LPTR=0; %WHILE STRIPNO>0 %CYCLE CURRT==TRIPLES(STRIPNO) %EXIT %IF CURRT_FLAGS&ASS LEVEL#0 OP=CURRT_OPERN %IF OP=FJUMP %AND LPTR<=LMAX %START J=CURRT_OPND1_D I=J&X'FFFF'; ! THE LAB NO %IF J<0 %AND I>WORKA_NNAMES %THEN LABS(LPTR)=I %AND LPTR=LPTR+1 %FINISH %IF OP=TLAB %START J=CURRT_OPND1_D&X'FFFF'; ! THE LAB NO %FOR I=0,1,LPTR-1 %CYCLE ->JSEEN %IF J=LABS(I) %REPEAT %EXIT; ! CAN NOT NORMALLY PASS LABES JSEEN: ! THE FIRST JUMP TO THIS LAB HAS ! BEEN PASSED. THERE ARE NO BACK JUMPS ! TO INTERNAL LABELS FIRST REFERENCED ! VIA A FORWARD JUMP %FINISH %EXIT %IF OP=RTXIT %OR OP=RCALL %EXIT %IF OP=SETSW %OR OP=PTRAS %IF OP=VASS %OR OP=STRASS2 %OR OP=VJASS %OR OP=DMASS %OR OP=RSTORE %OR OP=GETAD %OR OP=GETPTR %START ! ASSIGNMENT AOPND=CURRT_OPND1; ! DEST OF ASSIGNMENT %EXIT %IF SAME OPND(AOPND,NOPND,yes)=YES %FINISH %IF SAME OPND(CURRT_OPND1,NOPND,NO)=YES %START CHANGES=CHANGES+1 %IF OP<128 %OR CURRT_FLAGS&CONSTANTOP#0 %THEN FOLD AGAIN=YES CURRT_FLAGS=CURRT_FLAGS!CONSTANTOP CURRT_OPND1=COPND %FINISH %IF OP>=128 %AND SAME OPND(CURRT_OPND2,NOPND,NO)=YES %START CHANGES=CHANGES+1 %IF CURRT_FLAGS&CONSTANTOP#0 %THEN FOLD AGAIN=YES CURRT_FLAGS=CURRT_FLAGS!CONSTANTOP CURRT_OPND2=COPND %FINISH STRIPNO=CURRT_FLINK %REPEAT %END %INTEGER %FN SAME OPND(%RECORD (RD) %NAME OPND1,OPND2,%integer ASSN) !*********************************************************************** !* ARE THESE OPERANDS THE SAME ? * !* If assn=yes then allow for possible overlapping assignments * !* in variant records * !*********************************************************************** %INTEGER F,I,B1,B2 ! printstring(" same opnd"); write(opnd1_flag,2); write(opnd2_flag,2); newline F=OPND1_FLAG %if f=3 %start { ar pointer } %result=no %unless f=opnd2_flag b1=opnd1_d; b2=opnd2_d %if a(b1)=a(b2) %and a(b1+1)=a(b2+1) %and a(b1+2)=2 %and a(b2+2)=2 %c %and a(b1+3)=2 %and a(b2+3)=2 %then %result=yes %result=no %finish %IF F=2 %OR F=5 %START %result=no %unless f=opnd2_flag %RESULT=NO %UNLESS OPND1_D=OPND2_D %AND OPND1_PTYPE&X'3000'=0 %IF ASSN=NO %AND OPND1_PTYPE#OPND2_PTYPE %THEN %RESULT=NO %IF OPND1_XTRA=OPND2_XTRA %THEN %RESULT=YES B1=BYTES(OPND1_PTYPE>>4&15) B2=BYTES(OPND2_PTYPE>>4&15) i=IMOD(OPND1_XTRA&X'FFFF'-OPND2_XTRA&X'FFFF') %IF ASSN=YES %AND (i<=B1 %or i<=B2) %THEN %RESULT=YES %RESULT=NO %FINISH %RESULT=NO %UNLESS OPND1_S1&X'FFFF00FF'=OPND2_S1&X'FFFF00FF' %IF F<=1 %START; ! CONSTANTS %IF OPND1_PTYPE=X'35' %START %RESULT=NO %UNLESS OPND1_XTRA=OPND2_XTRA %FOR I=1,1,OPND1_XTRA %CYCLE %RESULT=NO %UNLESS A(OPND1_D+I)=A(OPND2_D+I) %REPEAT %RESULT=YES %FINISH %RESULT=YES %IF OPND1_D=OPND2_D %AND (OPND1_XTRA=OPND2_XTRA %OR OPND1_PTYPE&X'F0'<=X'50') %RESULT=NO %FINISH %RESULT=YES %IF OPND1_D=OPND2_D %AND OPND1_XTRA=OPND2_XTRA %RESULT=NO %END %END %END %OF %FILE