!!{GT:}%include "hostcodes.inc" CONSTINTEGER YES=1,NO=0 ! ! THESE CODE ARE ARBITARY BUT THE TOP DECIMAL DIGIT GIVES THE NO OF BYTES ! IN THE UNIT OF ADDRESSABILITY. BYTE ADDRESSED HOSTS BEING 1N ( also 0N) AND ! 16 BIT WORD ADDRESSED HOSTS BEING 2N ETC CONSTINTEGER PENTIUM=4; ! PENTIUM chip Unix stack and completely swopped constinteger MIPS=05; ! Imp on MIPS (all variants) CONSTINTEGER RS6=06; ! imp on IBM rs6000 CONSTINTEGER M88K=07; ! Imp on all forms of 88k ! also serves for Sparc sinc there is a common b-e CONSTINTEGER VAX=08; ! Imp on Vax using F & G formats CONSTINTEGER UNISYS=09; ! Imp on UnisSys. Unix stack unswopped Vax reals CONSTINTEGER EMAS=10; ! emas on 2900 (unsigned shorts) CONSTINTEGER IBM=11; ! emas on 24 bit ibm hardware CONSTINTEGER IBMXA=12; ! emas of XA 31 bit hardware CONSTINTEGER WWC=13; ! WWc (Natsemi chip) completely swopped CONSTINTEGER AMDAHL=14; ! Emas on Amdahls guess at Xa Minor differences fron IBM) CONSTINTEGER PERQ3=15; ! ICL packaged 68k chip Unix stack but not swopped CONSTINTEGER GOULD=16; ! Gould unswopped forward stack. Needs 4&8 byte alined CONSTINTEGER VNS=17; ! Unix on 2900 unsigned shorts params as ! 2900. Long int available but not in Ecode CONSTINTEGER EAMD=18; ! Amdahl via the Emachine CONSTINTEGER DRS=19; ! Intel chip Unix stack and mostly swopped CONSTINTEGER PERQ=20; ! Pos perq now obselete. Fully swopped forward stack CONSTINTEGER PNX=21; ! ICL's perq2 Unix stack byte swopped (unsigned shorts) CONSTINTEGER ACCENT=22; ! Perq 1 under accent. obsolete now ! ACCENT DIFFERS FROM PERQ ONLY IN ! ASSEMBLES SEQUENCES&SYNTAX ! AND GENERATOR constinteger ORN=23 CONSTINTEGER UNSIGNEDSHORTS=1<<emas!1<<pnx!1<<vns CONSTINTEGER LINTAVAIL=1<<IBM!1<<IBMXA!1<<amdahl!1<<EMAS!1<<GOULD!1<<MIPS CONSTINTEGER LLREALAVAIL=1<<IBM!1<<IBMXA!1<<amdahl!1<<EMAS!1<<MIPS CONSTINTEGER EMACHINE=1<<DRS!1<<PENTIUM!1<<WWC!1<<Vax!1<<GOULD!1<<PERQ3!1<<VNS!1<<EAMD!1<<ORN!1<<UniSys!1<<m88k!1<<rs6!1<<MIPS CONSTINTEGER IBMFPFORMAT=1<<ibm!1<<ibmxa!1<<amdahl!1<<emas!1<<gould!1<<vns!1<<EAMD constinteger VAXFPFORMAT=1<<Vax!1<<UniSys constinteger IEEEFPFORMAT=1<<WWC!1<<PERQ3!1<<DRS!1<<PENTIUM!1<<PERQ!1<<accent!1<<m88k!1<<rs6!1<<MIPS CONSTINTEGER BYTESWOPPED=1<<PERQ!1<<ACCENT!1<<WWC!1<<Vax!1<<PNX!1<<ORN CONSTINTEGER HALFSWOPPED=1<<PERQ!1<<ACCENT!1<<WWC!1<<Vax!1<<DRS!1<<PENTIUM!1<<ORN CONSTINTEGER WORDSWOPPED=1<<PERQ!1<<ACCENT!1<<WWC!1<<Vax!1<<DRS!1<<PENTIUM!1<<ORN CONSTINTEGER RISKMC=1<<M88K!1<<rs6!1<<MIPS ! ! end of file hostcodes ! 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<<host&unsignedshorts=0 START RECORDFORMAT RD((INTEGER S1 OR SHORT PTYPE,BYTE XB,FLAG), ((INTEGER D OR REAL R), INTEGER XTRA OR SHORT H0,H1,H2,H3 OR BYTE B0,B1,B2,B3,B4,B5,B6,B7)) RECORDFORMAT TAGF((SHORTINTEGER PTYPE,UIOJ,SNDISP,ACC,SLINK,KFORM OR C INTEGER S1,S2,S3),INTEGER LINK) RECORDFORMAT TRIPF(BYTE OPERN,OPTYPE,CNT,DPTH, SHORTINTEGER FLAGS,PUSE,FLINK,BLINK,INTEGER X1, RECORD(RD) OPND1,OPND2) RECORDFORMAT LISTF((SHORTINTEGER PTYPE,(SHORT UIOJ OR BYTE XB,FLAG), SHORT SNDISP,ACC,SLINK,KFORM OR INTEGER S1,S2,S3),INTEGER LINK) FINISH ELSE START RECORDFORMAT RD((INTEGER S1 OR HALF PTYPE,BYTE XB,FLAG), ((INTEGER D OR REAL R), INTEGER XTRA OR HALF H0,H1,H2,H3 OR BYTE B0,B1,B2,B3,B4,B5,B6,B7)) RECORDFORMAT TAGF((HALFINTEGER PTYPE,UIOJ,SNDISP,ACC,SLINK,KFORM OR C INTEGER S1,S2,S3),INTEGER LINK) RECORDFORMAT TRIPF(BYTE OPERN,OPTYPE,CNT,DPTH, HALFINTEGER FLAGS,PUSE,FLINK,BLINK,INTEGER X1, RECORD(RD) OPND1,OPND2) RECORDFORMAT LISTF((HALFINTEGER PTYPE,(HALF UIOJ OR BYTE XB,FLAG), HALF SNDISP,ACC,SLINK,KFORM OR INTEGER S1,S2,S3),INTEGER LINK) FINISH RECORDFORMAT WORKAF(INTEGER NNAMES,CCSIZE,DSIZE,ASL MAX,ASL CUR BTM,CONST PTR, CONST BTM,LASTTRIP,WKFILEAD,WKFILEK,FILE ADDR,RELEASE,AASL0,CONST LIMIT, RTCOUNT,ARTOP,AMAINEP,DICTBASE,OPTCNT,INCLHEAD,S2,S3,S4, INTEGERNAME LINE,N,S5,STRING(9)LADATE, BYTEINTEGERARRAYNAME CC,A,LETT, INTEGERARRAYNAME WORD,TAGS,CTABLE, RECORD(LEVELF)ARRAYNAME LEVELINF, INTEGERARRAY PLABS,PLINK(0:31), RECORD(LISTF)ARRAYNAME ASLIST) ! ! TRIPF_FLAGS SIGNIFY AS FOLLOWS CONSTINTEGER LEAVE STACKED=2****0; ! SET LEAVE RESULT IN ESTACK CONSTINTEGER LOADOP1=2****1; ! OPERAND 1 NEEDS LOADING CONSTINTEGER LOADOP2=2****2; ! OPERAND 2 NEEDS LOADING CONSTINTEGER NOTINREG=2****3; ! PREVENT REG OPTIMISNG ! OF TEMPS OVER LOOPS&JUMPS CONSTINTEGER USE ESTACK=2****4; ! KEEP DUPLICATE IN ESTACK CONSTINTEGER USE MSTACK=2****5; ! PUT DUPLICAT ON MSTACK CONSTINTEGER CONSTANTOP=2****6; ! ONE OPERAND IS CONSTANT(FOR FOLDING) CONSTINTEGER COMMUTABLE=2****7; ! OPERATION IS COMMUTABLE CONSTINTEGER BSTRUCT=2****12; ! Proc contains inner blks or RTs CONSTINTEGER USED LATE=2****13; ! I-RESULT USED AFTER LAB OR A LONG WAY AHEAD CONSTINTEGER ASS LEVEL=2****14; ! ASSEMBLER LEVEL OPERATION CONSTINTEGER DONT OPT=2****15; ! DONT DUPLICATE THIS RESULT ! USED FOR BYTE PTR & OTHER SODS! ! RECORDFORMAT EMASFHDRF(INTEGER ENDRA,STARTRA,FBYTESIZE,W3,W4,W5,W6,W7) ! FORMAT FOR ARRAY HEADS ! %END %OF %FILE "ERCC07.TRIMP_TFORM1S" ! ! FIRST THE OPERAND FLAG CONSTANTS ! CONSTINTEGER SCONST=0; ! CONST UPTO 64 BITS value is carried ! in opnd_d and opnd_xtra CONSTINTEGER LCONST=1; ! CONST LONGER THAN SCONST const can be ! found elsewhere(at top of ar) by ! meanse of base&offset inf in_d and _xtra CONSTINTEGER DNAME=2; ! NAME BY DICTIONARY NO the base and disp in ! the dictionary after adjusting by ! possible offset for item in ! in records lead to the variable CONSTINTEGER ARNAME=3; ! NAME BY AR POINTER opnd_d the ar pointer ! this form local to pass2 ! and used to identify functions ! with params before the call ! is planted CONSTINTEGER VIAPTR=4; ! VIA TRIPLE WITHOFFSET TO POINTER ! At an offset(_xtra) from address in ! referenced triple can be found a ! pointer to the required operand CONSTINTEGER INDNAME=5; ! INDIRECT VIA DICTIONARY base&disp ! in dictionary identify a pointer ! variable at possible offset from ! this pointer CONSTINTEGER INDIRECT=6; ! INDIRECT VIA TRIPLE WITH OFFSET ! the refenced triple has computed ! the (32bit) address of an item ! an offset may have to be applied ! before the fetch or store CONSTINTEGER LOCALIR=7; ! BASE DISP REF IN CURRENT STACK FRAME ! opnd_b=base<<16!offset used only for ! compiler generated temporaries CONSTINTEGER REFTRIP=8; ! REFERENCE TO A TRIPLE the operand is the result of ! triple opnd_d CONSTINTEGER INAREG=9; ! REGISTER OPERAND this form is local to the ! code generating pass(es) CONSTINTEGER developped=10; ! also local to generator CONSTINTEGER DEVADDR=11; ! ALSO LOCAL TO GENERATOR CONSTINTEGER BTREFMASK=1<<REFTRIP!1<<INDIRECT!1<<VIAPTR CONSTINTEGER REFER NEEDED=1<<INDIRECT!1<<VIAPTR ! ! NOW THE DEFINITIONS OF ONE OPERAND TRIPLES <128 ! CONSTINTEGER RTHD=1; ! ROUTINE-BLOCK HEADING CONSTINTEGER RDSPY=2; ! ROUTINE ENTRY SET DISPLAY CONSTINTEGER RDAREA=3; ! ROUTINE LEAVE DIAGNOSTIC SPACE CONSTINTEGER RDPTR=4; ! SET DIAGNOSTIC POINTER CONSTINTEGER RTBAD=5; ! ROUTINE-FN BAD EXIT CONSTINTEGER RTXIT=6; ! "%RETURN" CONSTINTEGER XSTOP=7; ! EXECUTE "%STO" CONSTINTEGER NOTL=10; ! LOGICAL NOT CONSTINTEGER LNEG=11; ! LOGICAL NEGATE CONSTINTEGER IFLOAT=12; ! CONVERT INTEGER TO REAL CONSTINTEGER MODULUS=13; ! AS USED BY IMOD&RMOD CONSTINTEGER SHRTN=14; ! SHORTEN TO LOWER PRECISION CONSTINTEGER LNGTHN=15; ! LENGTHEN TO HIGHER PRECISION CONSTINTEGER JAMSHRTN=16; ! SHORTEN FOR JAM TRANSFER CONSTINTEGER NULLT=18; ! FOR REDUNDANT TRIPLES CONSTINTEGER PRELOAD=19; ! PREFETCH FOR OPTIMISATION REASONS CONSTINTEGER SSPTR=21; ! STORE STACK POINTER CONSTINTEGER RSPTR=22; ! RESTORE STACK POINTER CONSTINTEGER ASPTR=23; ! ADVANCE STACK PTR CONSTINTEGER DARRAY=24; ! DECLARE ARRAY(IE STORE HD) CONSTINTEGER SLINE=25; ! UPDATE LINE NO CONSTINTEGER STPCK=26; ! CHECK FOR ZERO STEPS CONSTINTEGER FORPRE=27; ! PREAMBLE FOR "FOR" CONSTINTEGER FORPOST=28; ! POSTAMBLE FOR "FOR" CONSTINTEGER FORPR2=29; ! FOR SECOND PREAMBLE CONSTINTEGER PRECL=30; ! PREPARATION FOR CALL CONSTINTEGER RCALL=31; ! THE CALL CONSTINTEGER RCRFR=32; ! RECOVER FN RESULT CONSTINTEGER RCRMR=33; ! RECOVER MAP RESULT CONSTINTEGER GETAD=35; ! GET ADDRESS OF NAME CONSTINTEGER RTOI1=36; ! REAL TO INTEGER AS INT CONSTINTEGER RTOI2=37; ! REAL TO INTEGER INTPT CONSTINTEGER ITOS1=38; ! INTEGER TO STRING AS TOSTRING CONSTINTEGER MNITR=39; ! %MONITOR CONSTINTEGER PPROF=40; ! PRINT PROFILE CONSTINTEGER RTFP=41; ! TURN RT INTO FORMAL PARAMETER CONSTINTEGER ONEV1=42; ! ON EVENT 1 PRIOR TO TRAP CONSTINTEGER ONEV2=43; ! ON EVENT 2 AFTER TRAP CONSTINTEGER DVSTT=44; ! START OF DOPE VECTOR CONSTINTEGER DVEND=45; ! END OF DV EVALUATE TOTSIZE ETC CONSTINTEGER FOREND=46; ! END OF FOR LOOP CONSTINTEGER DMASS=47; ! assign via bim warning to opt only CONSTINTEGER RTOI3=48; ! real to integer as TRUNC ! ! CODES FOR USER WRITTEN ASSEMBLER. NATURALLY THESE ARE NOT ! MACHINE INDEPENDENT ! CONSTINTEGER UCNOP=50; ! FOR CNOPS CONSTINTEGER UCB1=51; ! ONE BYTE OPERATIONS CONSTINTEGER UCB2=52; ! FOR 2 BYTE OPERATIONE CONSTINTEGER UCB3=53; ! FOR 3 BYTE OPERATIONS CONSTINTEGER UCW=54; ! FOR WORD OPERATIONS CONSTINTEGER UCBW=55; ! FOR OPC,BYTEWORD OPERATIONE CONSTINTEGER UCWW=56; ! FOR OPC,WORD,WORD OPERAIONS CONSTINTEGER UCLW=57; ! FOR LONGWORD OPERATIONS CONSTINTEGER UCB2W=58; ! FOR OPC,B1,B2,WORD OPERATIONS CONSTINTEGER UCNAM=59; ! FOR ACESS TO NAMES FROM ASSEMBLER ! ! NOW THE BINARY OPERATIONS ! CONSTINTEGER ADD=128; ! ADDITION CONSTINTEGER SUB=129; ! SUBTRACTION CONSTINTEGER NONEQ=130; ! INTEGER NONEQUIVALENCE CONSTINTEGER ORL=131; ! LOGICAL OR CONSTINTEGER MULT=132; ! MULTIPLICATION CONSTINTEGER INTDIV=133; ! INTEGER DIVISION CONSTINTEGER REALDIV=134; ! REAL DIVISION CONSTINTEGER ANDL=135; ! LOGICAL AND CONSTINTEGER RSHIFT=136; ! LOGICAL RIGHT SHIFT CONSTINTEGER LSHIFT=137; ! LOGICAL LEFT SHIFT CONSTINTEGER REXP=138; ! REAL EXPONENTIATION CONSTINTEGER COMP=139; ! COMPARISONS CONSTINTEGER DCOMP=140; ! FIRST PART OF DSIDED(NEEDED?) CONSTINTEGER VMY=141; ! VECTOR MULTIPLY CONSTINTEGER COMB=142; ! COMBINE (IE ADD OF LA) ON VMY RESULTS CONSTINTEGER VASS=143; ! VARAIABLE ASSIGN WITH CHECKING CONSTINTEGER VJASS=144; ! VARIABLE JAMMED ASSIGN CONSTINTEGER IEXP=145; ! INTEGER EXPONENTIAITION CONSTINTEGER BADJ=146; ! BASE ADJUST ARRAY INDEX CONSTINTEGER AINDX=147; ! INDEX ARRAY(COMBINE BS&IX) CONSTINTEGER IFETCH=148; ! NO LONGER USED CONSTINTEGER LASS=149; ! ASSIGN LOCAL TEMPORARY CONSTINTEGER FORCK=150; ! VALIDATE FOR CONSTINTEGER PRECC=151; ! PRELIMINARY CONNCATENATION CONSTINTEGER CONCAT=152; ! CONCATENATION CONSTINTEGER IOCPC=153; ! CALL IOCP CONSTINTEGER PASS1=154; ! PRIMARY PARAMETER ASSIGNMENT CONSTINTEGER PASS2=155; ! PARAMETER PASSING POINTER PARAMS CONSTINTEGER PASS3=156; ! PARAMETERPASSING ARRAY PARAMETERS CONSTINTEGER PASS4=157; ! PASS A FORMAL PROCEDURE CONSTINTEGER PASS5=158; ! PASS AN UNTYPE(%NAME) PARAMETER CONSTINTEGER PASS6=159; ! PASS STRFN OR RECFN RESULT AREA CONSTINTEGER BJUMP=160; ! BACKWARDS JUMPS CONSTINTEGER FJUMP=161; ! FORWARD JUMPS CONSTINTEGER REMLB=162; ! REMOVE LAB FROM LABELIST ! NEEDS TO BE TRIPLE IF COMBINED ! LABEL LIST IS USED CONSTINTEGER TLAB=163; ! TO ENTER A LABEL CONSTINTEGER DCLSW=164; ! DECLARE A SWITCH ARRAY CONSTINTEGER SETSW=165; ! SET A SWITCH TO "CA" CONSTINTEGER GOTOSW=166; ! GO TO A SWITCH LABEL CONSTINTEGER STRASS1=167; ! STRING GENERAL ASSIGNMET CONSTINTEGER STRASS2=168; ! STRING FIXED LENGTH ASSNMENT CONSTINTEGER STRJT=169; ! STRING JAM TRANSFER CONSTINTEGER AHASS=170; ! ASSIGNMENT OF ARRAYHEADS CONSTINTEGER PTRAS=171; ! ASSIGNMENT OF POINTERS CONSTINTEGER MAPRES=172; ! ASSIGN MAPPING FN RESULT CONSTINTEGER FNRES=173; ! ASSIGN FN RESULT CONSTINTEGER SCOMP=174; ! STRING COMPARISON CONSTINTEGER SDCMP=175; ! FIRST PART OF STRING D-SIDED CONSTINTEGER PRES1=176; ! PRE RESOLUTION 1 CONSTINTEGER PRES2=177; ! PRE RESOLUTION 2 CONSTINTEGER RESLN=178; ! STRING RESOLUTION CONSTINTEGER RESFN=179; ! RESOLUTION FINALE CONSTINTEGER SIGEV=180; ! SIGNAL EVENT CONSTINTEGER RECASS=181; ! WHOLE RECORD ASSIGNMENT CONSTINTEGER AAINC=182; ! ARRAY ADDRESS ADJUST FOR ! RECORD RELATIVE TO ABSOLUTE CONSTINTEGER AHADJ=183; ! MODIFY HEAD FOR MAPPING CONSTINTEGER CTGEN=184; ! CREATE TYPE GENERAL PARAMETER CONSTINTEGER GETPTR=185; ! POINTER FOR PASSING BY NAME CONSTINTEGER SINDX=186; ! INDEX STRING IE CHARNO ! SAME AS AINDX FOR ALL TARGETS ! BUT PNX ! CONSTINTEGER ZCOMP=187; ! COMPARISONS WITH ZERO ! GENERATED BY OPTIMISER CONSTINTEGER CLSHIFT=188; ! CONSTANT LOGICAL SHIFT ! GENERATED BY OPTIMISER CONSTINTEGER CASHIFT=189; ! CONSTANT ARITHMETIC SHIFT ! GENERATED BYOPTIMISER CONSTINTEGER DVBPR=190; ! GENERATE DV ENTRY FOR BOUND PAIR CONSTINTEGER RSTORE=191; ! REGISTER TO STORE OPERATION CONSTINTEGER MULTX=192; ! MULTIPLY AND EXTEND PRECISION EXTRINSIC RECORD (WORKAF) WORKA EXTRINSIC RECORD (PARMF) PARM EXTERNAL ROUTINE SPEC IMPABORT IF HOST#TARGET START EXTERNAL ROUTINE SPEC REFORMATC(RECORD (RD) NAME OPND) FINISH EXTERNAL ROUTINE SPEC MOVE BYTES(INTEGER L,FB,FO,TB,TO) EXTERNAL ROUTINE SPEC FAULT(INTEGER N,DATA,IDENT) EXTERNAL ROUTINE SPEC PRINT TRIPS(RECORD (TRIPF) ARRAY NAME TRIPLES) CONST BYTE INTEGER ARRAY BYTES(0:7)=0(3),1,2,4,8,16; CONST BYTE INTEGER ARRAY WORDS(0:7)=0(3),1,1,1,2,4; EXTERNAL ROUTINE CTOP(INTEGER NAME FLAG,MASK, INTEGER XTRA, RECORD (RD) NAME OPND1,OPND2) !*********************************************************************** !* AN OPERATION HAS BEEN FOUND WHERE BOTH OPERANDS ARE * !* CONSTANTS OR KNOWN AT COMPILE TIME. THIS ROUTINE INTERPRETS * !* THE OPERATION * !* ON EXIT FLAG=0 IF INTERPRETED. REFRAINS FROM INTERPRETING * !* X=1/0 FOR EXAMPLE. CODE IS PLANTED FOR THESE FUNNIES * !*********************************************************************** ROUTINE SPEC EXTRACT(RECORD (RD) NAME OPND) INTEGER FN SPEC DEBYTESWOP(INTEGER VAL) CONST INTEGER UTRUNCMASK=X'00000800',BTRUNCMASK=X'00000013' INTEGER K,TYPEP,PRECP,OP,MAXD,SVAL,SVAL1,SVAL2,C,D,JJ,KK,TRUNCMASK,LB,UB,MP STRING (255) STRVAL,STRVAL1,STRVAL2 LONG REAL LR IF 1<<HOST&LINTAVAIL#0 THEN START LONG INTEGER VAL,VAL1,VAL2 FINISH ELSE START INTEGER VAL,VAL1,VAL2 FINISH IF 1<<HOST&LLREALAVAIL#0 THEN START LONG LONG REAL RVAL,RVAL1,RVAL2 FINISH ELSE START LONG REAL RVAL,RVAL1,RVAL2 FINISH SWITCH UISW,URSW(10:48),BISW,BRSW(0:47) ON EVENT 1,2 START RETURN FINISH TYPEP=OPND1_PTYPE&7; PRECP=OPND1_PTYPE>>4&15; OP=FLAG RETURN IF 1<<HOST&LINTAVAIL=0 AND OPND1_PTYPE=X'61' RETURN IF 1<<HOST&LLREALAVAIL=0 AND OPND1_PTYPE=X'72' if opnd1_ptype&x'8'#0 then return; ! Foreign constants can not be folded EXTRACT(OPND1) VAL1=VAL; RVAL1=RVAL; STRVAL1=STRVAL SVAL1<-VAL1 IF OP<128 START; ! UNARY RETURN UNLESS 10<=OP<=48 TRUNCMASK=UTRUNCMASK IF TYPEP=2 THEN ->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<<HOST&LINTAVAIL#0 AND PRECP=6 THEN START OPND1_D<-VAL1>>32 OPND1_XTRA<-VAL1 FLAG=0 FINISH ELSE START SVAL<-VAL1 IF SVAL=VAL1 OR 1<<OP&TRUNCMASK=0 THEN FLAG=0 AND OPND1_D=SVAL ! NO ARITH OFLOW CONDITION FINISH IF FLAG=0 START OPND1_PTYPE=PRECP<<4!1 OPND1_FLAG=0 FINISH RETURN UISW(11): ! INTEGER NEGATE VAL1=-VAL1; ->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<<HOST&LINTAVAIL#0 AND PRECP=5 THEN PRECP=6 AND ->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)<X'7FFFFFFE' VAL1=INT(RVAL1) PRECP=5 ->INTEND URSW(37): ! INTPT RETURN UNLESS MOD(RVAL1)<X'7FFFFFFE' VAL1=INTPT(RVAL1) PRECP=5 ->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)<x'7ffffffe' IF RVAL>=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<<SVAL2 ELSE VAL1=SVAL1<<SVAL2 ->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<<TARGET&EMACHINE#0 START LB=DEBYTESWOP(WORKA_CTABLE(D+3*C+1)) UB=DEBYTESWOP(WORKA_CTABLE(D+3*C)) MP=DEBYTESWOP(WORKA_CTABLE(D+3*C-1)) IF VAL1<LB OR VAL1>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 VAL1<WORKA_CTABLE(D+3*C) OR VAL1>WORKA_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<<TARGET&EMACHINE#0 OR TARGET=ACCENT OR TARGET=PNX START D=XTRA>>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 VAL1<VAL2) OR (MASK&2#0 AND VAL1>VAL2) 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 RVAL1<RVAL2) OR (MASK&2#0 AND RVAL1>RVAL2) 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 STRVAL1<STRVAL2) OR (MASK&2#0 AND C STRVAL1>STRVAL2) 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<<HOST&LINTAVAIL#0 AND PREC=6 THEN VAL=LENGTHENI(OPND_D)<<32!(OPND_XTRA&(LENGTHENI(-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<<I IF J=VAL THEN RESULT=I IF J>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<<CURRT_OPND2_FLAG&TRIPREFS=0 START ! BACK VIA OPND1 IF 1<<CURRT_OPND1_FLAG&TRIPREFS=0 THEN RESULT=TRIP RESULT=PRELOAD PLACE(OPND1_D) FINISH IF 1<<CURRT_OPND1_FLAG&TRIPREFS=0 OR OPND1_D=CURRT_BLINK THEN RESULT=PRELOAD PLACE(OPND2_D) ! ! BOTH OPERANDS ARE LOADED TRIPLES ! IF CURRT_BLINK=OPND2_D THEN RESULT=PRELOADPLACE(OPND1_D) RESULT=-1; ! TOO COMPLICATED END ROUTINE INDOPT(RECORD (RD) NAME OPND) !*********************************************************************** !* OPND IS AN INDIRECT OFFSET. TRY TO SUBSUME PART OF THE EXPRESSION* !* INTO THE OFFSET, REALLY GUNNING FOR IMP REFERENCES TO PAG0 ON IBM* !*********************************************************************** INTEGER COP,X,VAL,OP,LIMIT RECORD (TRIPF) NAME RTRIP RECORD (RD) NAME COPND IF TARGET=IBM OR TARGET=AMDAHL OR TARGET=IBMXA THEN LIMIT=4096 ELSE IF TARGET=EMAS THEN C LIMIT=X'7FFFFFFF' ELSE LIMIT=1<<16 RTRIP==TRIPLES(OPND_D) RETURN UNLESS RTRIP_CNT=1 AND RTRIP_FLAGS&CONSTANTOP#0 OP=RTRIP_OPERN RETURN UNLESS OP=ADD OR OP=SUB RETURN UNLESS RTRIP_OPTYPE&7=1 AND RTRIP_OPTYPE>>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<<DELT_OPND1_FLAG&BTREFMASK#0 THEN DEC USE(DELT_OPND1_D) IF DELT_OPERN>=128 AND 1<<DELT_OPND2_FLAG&BTREFMASK#0 THEN DEC USE(DELT_OPND2_D) DELT_X1=DELT_OPERN; ! FOR DEBUGGING DELT_OPERN=NULLT; ! NO OP CHANGES=CHANGES+1 DELT_FLAGS<-DELT_FLAGS!DONT OPT END ROUTINE DUPLICATE TRIP(INTEGER TRIPNO,DTRIPNO,FLAGBITS) !*********************************************************************** !* DTRIPNO IS A DUPLICATE OF TRIPNO. CHANGE ALL REFERENCES * !* AND DELETE IT * !*********************************************************************** RECORD (RD) NAME OPND1,OPND2 RECORD (TRIPF) NAME MASTER,CURRT,DUPT INTEGER CNT,PTR DUPS=DUPS+1 DUPTNO=TRIPNO MASTER==TRIPLES(TRIPNO) DUPT==TRIPLES(DTRIPNO) MASTER_FLAGS=MASTER_FLAGS!FLAGBITS CNT=DUPT_CNT PTR=DUPT_FLINK ! WHILE CNT>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<<OPND1_FLAG&BTREFMASK#0 START MASTER_CNT=MASTER_CNT+1 OPND1_D=TRIPNO CURRT_FLAGS=CURRT_FLAGS!LOAD OP1 CNT=CNT-1 FINISH IF CURRT_OPERN>=128 AND OPND2_D=DTRIPNO AND 1<<OPND2_FLAG&BTREFMASK#0 START MASTER_CNT=MASTER_CNT+1 OPND2_D=TRIPNO CURRT_FLAGS=CURRT_FLAGS!LOAD OP2 CNT=CNT-1 FINISH REPEAT DELETE TRIPLE(DTRIPNO) END ROUTINE INVERT DIV(RECORD (TRIPF) NAME CURRT) !*********************************************************************** !* DIVISION BY A REAL CONSTANT HAS BEEN FOUND * !* SO INVERT IT AND CHANGE TO MULTIPLY. USE CTOP FOR OPERATIONS * !* THIS WILL FAIL IF NOT ENOUGH PRECISION ON HOST FOR TARGET * !*********************************************************************** INTEGER OP,PREC,FLAG,J RECORD (RD) WOPND,COPND LONG REAL LR COPND=CURRT_OPND2; ! THE CONST TO BE INVERTED PREC=CURRT_OPTYPE>>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