!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ! !COPYRIGHT (C) 1972,1973,1974,1975,1977,1978 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754 !FILENAME: H3PEEP.BLI !DATE: 13 AUG 75 !AUTHOR: G.J. BUNZA/JAG %4.01% !FILE CREATED IN UPDATE 4.01 %4.11% !UUO SKIP TEST ADDED TO NONSKIP %5(125)% !CALLI -> CALL BUG FIXED ! REVISION HISTORY : ! 6-20-77 ROUTINES PEEP03,PEEP07 ARE MODIFIED SO THAT ! [MOVE R,X TLNE R,#400000 REPLACE BY SKIPGE R,X] ! [MOVE R,X TLNN R,#400000 REPLACE BY SKIPL R,X] ! ARE NOT DONE IF THERE IS A LABLE ON INSTRUCTION ! TLNN OR TLNE. ! ! 5-13-77 ROUTINE PEEP02 IS MODIFIED TO ALLOW NO OPTIMIZATION ! FOR INSTRS: MOVEM R,X PUSHJ $S,Y MOVE R,X.THE REGISTERS ! ARE INVALID AFTER A ROUTINE CALL. BUG# 29 ! ! 5-9-77 ROUTINE PEEP14 IS MODIFIED NOT TO SUBSTITUTE TDZA ! INSTRUCTION FOR SETZ,JRST .+2 IF PRCEEDED BY SKIPN. ! BUG# 22 ! GLOBAL BIND H3PEEV=16; !MODULE VERSION NUMBER FORWARD PEEPIT,PEEPER,PEEP00,PEEP01,PEEP02,PEEP03,PEEP07,PEEP10,PEEP11, PEEP04,PEEP12,PEEP36,POPT74,PEEP23,POPT75, PEEP14,PEEP05,PEEP20,PEEP21,PEEP30,PEEPA0, POPT01,POPT02,POPT03,POPT04,POPT06,POPT07,POPT09,POPT10, POPT11,POPT14,POPT15,POPT16,POPT17,POPT18,POPT19,POPT21, POPT22,POPT23,POPT24,POPT27,POPT29,POPT30,POPT70,POPT71,POPT72, POPT73,NONSKIP,OPTOMEM, AROPTOMEM,DELCODE; MACRO AEQNXTLAB=(.ADDRF EQL .LNKDN)$, AEQ2NDLAB=(.ADDRF EQL .LNKDN2)$, AEQ0=(.PADDR(.PX) EQL 0 AND .PRELOC(.PX) EQL NORELOC)$, AEQ1=(.PADDR(.PX) EQL 1 AND .PRELOC(.PX) EQL NORELOC)$, AEQR=(.PADDR(.PX) EQL .PREG(.PX) AND .PRELOC(.PX) EQL NORELOC)$, NXTJRST=(.POPCODE(.LNKDN) EQL JRST)$, PRVNONSKIP=(NONSKIP(.POPCODE(.LNKUP)))$, NXTNONSKIP=(NONSKIP(.POPCODE(.LNKDN)))$, REQNXTR=(.PREG(.PX) EQL .PREG(.LNKDN))$, REQPRVR=(.PREG(.PX) EQL .PREG(.LNKUP))$, REQ2NDR=(.PREG(.PX) EQL .PREG(.LNKDN2))$, WHOLEEQ2ND=((.PCODEWD(.PX) EQL .PCODEWD(.LNKDN2)) AND (.PRELOC(.PX) EQL .PRELOC(.LNKDN2)))$; MACRO NONOPEQNXT=(.PRGADDR(.PX) EQL .PRGADDR(.LNKDN) AND .PRELOC(.PX) EQL .PRELOC(.LNKDN))$; MACRO NONOPEQ2ND=(.PRGADDR(.PX) EQL .PRGADDR(.LNKDN2) AND .PRELOC(.PX) EQL .PRELOC(.LNKDN2))$; MACRO NONOPEQPRV=(.PRGADDR(.PX) EQL .PRGADDR(.LNKUP) AND .PRELOC(.PX) EQL .PRELOC(.LNKUP))$; MACRO PRVNONEQNXT=(.PRGADDR(.LNKUP) EQL .PRGADDR(.LNKDN) AND .PRELOC(.LNKUP) EQL .PRELOC(.LNKDN))$; MACRO MEMRFEQNXT=((.PADDR(.PX) EQL .PADDR(.LNKDN)) AND (.PRELOC(.PX) EQL .PRELOC(.LNKDN)))$; GLOBAL PX,PEEPHDR,LNKUP,LNKUP2,LNKDN,LNKDN2; GLOBAL PSTACK[10],PSTKPTR,PEEPOK,PSTOP; ! ROUTINE NEXT CODE (CODE TABLE INDEX/LNK) ! ! FOLLOWS THE LNKED LIST OF CODE WORDS TO FIND THE NEXT ! REAL, LIVE CODE WORD, SKIPPING LABEL ENTRIES ! IF IT REACHES THE END OF THE TABLE, IT WILL RETURN A ! LNK POINING TO THE HEADER. GLOBAL ROUTINE NXTINSTR(X)= BEGIN LOCAL I,T; IF .X EQL .PEEPHDR THEN RETURN .X; T_.CT[.X,0]; WHILE (.T NEQ .PEEPHDR) AND (.POPCODE(.T) EQL 0) DO T_.CT[.T,0]; .T END; ! ROUTINE PREVIOUS CODE (CODE TABLE INDEX/LNK) ! ! FOLLOWS THE CODE TABLE BACKWARDS, TO FIND THE LAST REAL ! WORD OF CODE. IF WE BACK UP TO THE HEADER, IT WILL ! RETURN A POINTER TO THE HEADER ITSELF. ROUTINE PRVINSTR(X)= BEGIN LOCAL I,T; IF .X EQL .PSTOP THEN RETURN .X; T_.CT[.X,0]; WHILE (.T NEQ .PSTOP) AND (.POPCODE(.T) EQL 0) DO T_.CT[.T,0]; .T END; OWN ADDRF; !ADDRESS FIELD OF THE INSTRUCTION BEING EXAMINED OWN T1,T2; !TEMPS USED BY THE MACROS THAT CHECK FOR !CHARACTERISTICS BIND REG0=0, !REGISTER 0 (IS FREQUENTLY AN EXCEPTION) TRUE=-1, FALSE=0; GLOBAL ROUTINE PEEPER= BEGIN IF ((LNKUP2_PRVINSTR(LNKUP_PRVINSTR(.PX))) NEQ .PSTOP) AND ((LNKDN2_NXTINSTR(LNKDN_NXTINSTR(.PX))) NEQ .PEEPHDR) THEN BEGIN IF .POPCODE(.LNKUP2) EQL PEEPHOLE THEN BEGIN T1_ .PX; PX_ .LNKUP2; PEEP36(); PX_ .T1 END; IF .POPCODE(.LNKUP) EQL PEEPHOLE THEN BEGIN T1_ .PX; PX_ .LNKUP; PEEP36(); PX_ .T1 END; IF PEEPIT() THEN BEGIN PX_ PRVINSTR(PRVINSTR(.PX)); PEEPER() END END ELSE IF .LNKDN2 EQL .PEEPHDR THEN PX_.PEEPHDR END; !PEEPER ROUTINE PEEPIT= %(*************************************************************************** ROUTINE TO PERFORM ANY PEEPHOLE OPTIMIZATION TRIGGERED BY THE KEY INSTRUCTION POINTED TO BY THE GLOBAL PEEPPTR. IF ANY OPTIMIZATION CAN BE PERFORMED, LEAVE THE GLOBAL FRSTNEW POINTING TO THE FIRST INSTR CHANGED BY THE PEEPHOLE, AND RETURN TRUE. ELSE RETURN FALSE. KEYS OFF THE LAST 5 BITS OF THE OPCODE OF THE KEY INSTR. ***************************************************************************)% BEGIN IF .PEEPOK THEN RETURN ( CASE .PCODEWD(.PX)<27,5> OF SET PEEP00(); !ASH (240 ENDS IN 00), AND MOVE (200 ENDS IN 00) PEEP01(); !MOVEI PEEP02(); !MOVEM PEEP03(); !SETZB PEEP04(); !CAIA #304 PEEP05(); ! MOVSI FALSE; ! 06 PEEP07(); !TLNN (#607) PEEP10(); ! AOS (#350 HAS LAST 5 BITS EQL TO 10),MOVN(#210) PEEP11(); !MOVNI PEEP12(); !ANDCAM #412 FALSE; ! 13 PEEP14(); !JRST FALSE; ! 15 FALSE; ! 16 FALSE; ! 17 PEEP20(); ! DMOVE, SETCM(#460),TRZ,TRO PEEP21(); !TLZ,TLO FALSE; ! 22 PEEP23(); !POPJ FALSE; ! 24 FALSE; !25 FALSE; ! 26 FALSE; ! 27 PEEP30(); !SOS FALSE; ! 31 FALSE; ! 32 FALSE; ! 33 FALSE; ! 34 FALSE; ! 35 PEEP36(); !IORM #436,PEEPHOLE #776 FALSE ! 37 TES ) ELSE RETURN FALSE END; GLOBAL ROUTINE PEEP00= %(*************************************************************************** CHECK FOR ANY PEEPHOLES FOR WHICH THE KEY INSTR HAS THE LAST 5 BITS OF THE OPCODE EQUAL TO 00 THIS INCLUDES THE INSTRUCTIONS: ASH MOVE AOJ ***************************************************************************)% BEGIN %(***CHECK FOR PEEPHOLES KEYED BY MOVE***)% IF (.POPCODE(.PX) EQL MOVE) THEN BEGIN %(***CHECK FOR THE PEEPHOLE R,X MOVE R,X *****)% IF NONOPEQPRV !IF ADDR,IX,IND,ANDREG FIELDS ARE ! SAME AS THOSE ON INSTR BEFORE THE MOVE THEN BEGIN IF AROPTOMEM(.POPCODE(.LNKUP)) !IF PREV INSTR IS TO MEMORY THEN RETURN POPT29() END; %(***CHECK FOR: MOVE R,X SKIP 0,X AND FOR: MOVE R,X SKIP 0,R ********)% IF (((.POPCODE(.LNKDN) AND #770) EQL SKIP) AND (.PREG(.LNKDN) EQL 0)) THEN BEGIN IF MEMRFEQNXT !IF INDIRECT,INDEX AND ADDR FIELDS OF THIS ! INSTR EQL THOSE OF NEXT THEN RETURN POPT22() %(***CHECK FOR THE ADDR FIELD OF THE SKIP EQL TO THE REG OF THE MOVE**)% ELSE IF .PREG(.PX) EQL .PADDR(.LNKDN) AND .PRELOC(.LNKDN) EQL NORELOC THEN RETURN POPT22() END; %(***CHECK FOR THE PEEPHOLE MOVE R,X JUMP R,L ******)% IF .PREG(.PX) EQL .PREG(.LNKDN) THEN BEGIN IF (.POPCODE(.LNKDN) AND #770) EQL JUMP THEN RETURN POPT30() END; %(***CHECK FOR THE PEEPHOLE: MOVE R,X R,Y MOVE R,X *******)% RETURN PEEPA0() END %(***CHECK FOR PEEPHOLES KEYED BY ASH***)% ELSE IF (.POPCODE(.PX) EQL ASH) THEN BEGIN %(***CHECK FOR: MOVE R,X ASH R,1 MOVEM R,X ******)% IF PRVNONEQNXT THEN %(***IF ADDR AND REG OF PREV INSTR EQL THOSE OF NEXT INSTR***)% BEGIN IF AEQ1 THEN BEGIN IF (.POPCODE(.LNKUP) EQL MOVE) AND (.POPCODE(.LNKDN) EQL MOVEM) THEN RETURN POPT09(); END; END; %(****CHECK FOR: ASH R,A ASH R,B ******)% IF .POPCODE(.LNKDN) EQL ASH THEN BEGIN IF REQNXTR THEN BEGIN %(***CAN ONLY DO THIS PEEPHOLE IF A AND B ARE BOTH POS OR BOTH NEGATIVE (FOR NUMERICAL REASONS)***)% IF ((.PADDR(.LNKDN) XOR .PADDR(.PX)) AND #400000) EQL 0 THEN RETURN POPT14(); END END; RETURN FALSE; END; %(********CHECK FOR THE PEEPHOLE AOJ R,0 JRST X *******************************)% IF .POPCODE(.PX) EQL AOJ THEN BEGIN IF PRVNONSKIP AND NXTJRST AND AEQ0 THEN RETURN POPT71(); END; RETURN FALSE; END; GLOBAL ROUTINE PEEP01= %(*************************************************************************** CHECKS FOR ANY PEEPHOLES WHICH HAVE THE LAST 5 BITS OF THE KEY OPCODE=01 THIS INCLUDES PEEPHOLES WHOSE KEY OPCODE IS: MOVEI ***************************************************************************)% BEGIN %(***CHECK FOR PEEPHOLES KEYING FROM MOVEI**)% IF (.POPCODE(.PX) EQL MOVEI) THEN BEGIN %(***CHECK FOR PEEPHOLES KEYING FROM MOVEI R,0 ***)% IF AEQ0 THEN BEGIN IF REQNXTR THEN %(****IF REG FIELD OF THE "MOVEI R,0" IS EQL TO REG FIELD OF NEXT INSTR***)% BEGIN %(***CHECK FOR: MOVEI R,0 MOVEM R,X ******)% IF .POPCODE(.LNKDN) EQL MOVEM THEN RETURN POPT03(); END ELSE IF REQ2NDR THEN %(***IF REG FIELD OF MOVEI R,0 IS EQL TO REG FIELD OF INSTR AFTER NEXT AND IS **NOT** EQL TO REG FIELD OF NEXT INSTR***)% BEGIN %(*****CHECK FOR: MOVEI R,0 MOVEM RB,Y ;WHERE RB NEQ RA, BUT Y CAN =X MOVEM R,X ********)% IF .POPCODE(.LNKDN2) EQL MOVEM AND .POPCODE(.LNKDN) EQL MOVEM THEN RETURN POPT10(); END ELSE %(***CHECK FOR: MOVEI R1,0 MOVEI R2,0 *******)% IF .PADDR(.LNKDN) EQL 0 AND .PRELOC(.LNKDN) EQL NORELOC THEN BEGIN IF .POPCODE(.LNKDN) EQL MOVEI THEN RETURN POPT27() END END %(***CHECK FOR PEEPHOLES KEYING FROM "MOVEI R,1" ***)% ELSE IF AEQ1 THEN BEGIN IF REQNXTR THEN BEGIN %(***CHECK FOR MOVEI R,1 ADDB R,X *****)% IF .POPCODE(.LNKDN) EQL ADDB THEN RETURN POPT06() END; IF .PREG(.PX) EQL .PREG(.LNKDN) AND .PCODEWD(.LNKDN2) EQL (SETZ^4+.PREG(.PX))^23 AND (.POPCODE(.LNKDN) AND #760) EQL CAI THEN BEGIN LOCAL MI; MI_.PCODEWD(.PX); PRELOC(.PX)_.PRELOC(.LNKDN); PCODEWD(.PX)_.PCODEWD(.LNKDN); PRELOC(.LNKDN)_0; PCODEWD(.LNKDN)_(TDZA^4+.MI<23,4>)^23+.MI<23,4>; PCODEWD(.LNKDN2)_.MI; RETURN TRUE END; END ELSE %(***CHECK FOR THE PEEPHOLE: MOVEI R,X R,Y MOVEI R,X *******)% RETURN PEEPA0() END; RETURN FALSE; END; GLOBAL ROUTINE PEEP02= %(*************************************************************************** CHECKS FOR ANY PEEPHOLES FOR WHICH THE KEY INSTR HAS THE LAST 5 BITS OF THE OPCODE EQUAL TO 02 THIS INCLUDES PEEPHOLES WHOSE KEY OPCODE IS MOVEM ***************************************************************************)% BEGIN %(***CHECK FOR PEEPHOLES FOR WHICH REG AND ADDR OF THE INSTR AFTER THE MOVEM ARE THE SAME AS THEY ARE FOR THE MOVEM *******)% IF NONOPEQNXT THEN BEGIN IF .POPCODE(.PX) EQL MOVEM THEN BEGIN %(***CHECK FOR: MOVEM R,X MOVE R,X ******)% IF .POPCODE(.LNKDN) EQL MOVE THEN RETURN POPT01() ELSE %(****CHECK FOR: MOVEM R,X SKIP R,X JRST L *********)% IF .POPCODE(.LNKDN2) EQL JRST THEN BEGIN IF (.POPCODE(.LNKDN) AND #770) EQL SKIP THEN RETURN POPT15(); END END; END ELSE %(***CHECK FOR PEEPHOLES IN WHICH THE REG AND ADDR OF THE INSTR AFTER THE INSTR AFTER THE "MOVEM" ARE THE SAME AS THEY ARE FOR THE "MOVEM"***)% IF NONOPEQ2ND THEN BEGIN IF .POPCODE(.PX) EQL MOVEM THEN BEGIN %(***CHECK FOR: MOVEM R,X NONSKIP-INSTR THAT DOES NOT CHANGE R OR X MOVE R,X *******)% IF .POPCODE(.LNKDN2) EQL MOVE THEN BEGIN %(***IF THE INSTR AFTER THE MOVEM CAN SKIP, DONT BOTHER***)% IF NOT NONSKIP(.POPCODE(.LNKDN)) THEN RETURN FALSE ELSE %(***IF THE INSTR AFTER THE MOVEM CAN JUMP, DONOT BOTHER***) 5-13-77% IF (LOCAL L;L_.POPCODE(.LNKDN); .L GEQ #250 AND .L LSS #270) THEN RETURN FALSE %(***CHECK FOR THE POSSIBILITY OF THE INSTR AFTER THE MOVEM CLOBBERING R OR X***)% ELSE %(***IF REG IN NEXT INSTR IS R AND NEXT INSTR IS NOT TO MEMORY***)% IF REQNXTR AND NOT OPTOMEM(.POPCODE(.LNKDN)) THEN RETURN FALSE ELSE ! IF THE ADDR REF IN THE NEXT INSTR IS X IF (.PADDR(.PX) EQL .PADDR(.LNKDN)) THEN RETURN FALSE ELSE ! IF THE ADDR OF THE NEXT INSTR IS R IF (.PRELOC(.LNKDN) EQL NORELOC) AND (.PADDR(.LNKDN) EQL .PREG(.PX)) THEN RETURN FALSE ELSE ! IF X IS A REG, THEN MUST CHECK FOR REG ON NEXT INSTR=X IF (.PRELOC(.PX) EQL NORELOC) AND (.PRELOC(.PX) EQL .PREG(.LNKDN)) THEN RETURN FALSE %(***IF THE INSTR AFTER THE MOVEM DOES NOT CLOBBER X OR R***)% ELSE RETURN POPT18() END END END; RETURN FALSE; END; GLOBAL ROUTINE PEEP03= %(*************************************************************************** CHECK FOR ANY PEEPHOLES FOR WHICH THE KEY INSTR HAS THE LAST 5 BITS EQUAL TO OCTAL 03. THIS INCLUDES: SETZB,TLNE ***************************************************************************)% BEGIN %(***CHECK FOR MOVE R,X TLNE R,400000 *************)% IF NONSKIP(.POPCODE(.LNKUP2)) THEN IF (.POPCODE(.PX) EQL TLNE) AND REQPRVR THEN BEGIN IF .POPCODE(.LNKUP) EQL MOVE AND NOT .PLABEL(.PX) ! NO LABEL ON TLNE INSTR THEN ONLY 6-15-77 THEN RETURN POPT70(); END; %(***CHECK FOR PEEPHOLES FOR WHICH REG AND THE ADDR OF THE INSTR AFTER THE SETZB ARE THE SAME AS THEY ARE FOR THE SETZB***)% IF NONOPEQNXT THEN BEGIN IF .POPCODE(.PX) EQL SETZB THEN BEGIN %(***CHECK FOR: SETZB R,X MOVE R,X *******)% IF .POPCODE(.LNKDN) EQL MOVE THEN RETURN POPT01(); !USE SAME ROUTINE AS FOR MOVEM-MOVE END END; RETURN FALSE END; GLOBAL ROUTINE PEEP04= BEGIN LOCAL TOP; IF NOT .PLABEL(.LNKDN2) AND (.PCODEWD(.PX) EQL CAIA^27) THEN BEGIN TOP_.POPCODE(.LNKDN2); IF .TOP EQL JRST OR .TOP EQL AOJA OR .TOP EQL SOJA THEN BEGIN PCODEWD(.PX)_.PCODEWD(.LNKDN2); PRELOC(.PX)_.PRELOC(.LNKDN2); RETURN DELCODE(.LNKDN2) END ELSE IF .TOP EQL MOVE AND .PREG(.LNKDN2) NEQ 0 AND .POPCODE(.LNKDN) EQL JRST THEN BEGIN POPCODE(.LNKDN2)_SKIPA; PCODEWD(.PX)_.PCODEWD(.LNKDN2); PRELOC(.PX)_.PRELOC(.LNKDN2); RETURN DELCODE(.LNKDN2) END; END; RETURN 0 END; GLOBAL ROUTINE PEEP07= %(******************************************************************** CHECK FOR ANY PEEPHOLE FOR WHICH THE LAST 5 KEY BITS ARE EQUAL TO OCTAL 07 THIS INCLUDES THE PEEPHOLES KEYED BY THE INSTRUCTIONS TLNN *********************************************************************)% BEGIN IF NONSKIP(.POPCODE(.LNKUP2)) THEN BEGIN IF (.POPCODE(.PX) EQL TLNN) AND REQPRVR THEN BEGIN %(****CHECK FOR MOVE R,X TLNN R,400000 ****************)% IF .POPCODE(.LNKUP) EQL MOVE AND NOT .PLABEL(.PX) ! NO LABEL ON INSTR TLNN R,400000 6-15-77 THEN RETURN POPT70(); END; END; END; GLOBAL ROUTINE PEEP10= %(*************************************************************************** CHECK FOR ANY PEEPHOLESFOR WHICH THE KEY INSTR HAS OPCODE WITH THE LAST 5 BITS EQL TO OCTAL 10 THIS INCLUDES PEEPHOLES KEYED BY THE INSTRS: AOS,MOVN ***************************************************************************)% BEGIN IF NONOPEQNXT !IF THE REG,IX,INDIRECT,AND ADDRESS FIELDS ! OF THIS INSTR EQUAL THOSE OF THE NEXT THEN BEGIN %(***CHECK FOR THE PEEPHOLE: AOS R,X MOVE R,X *******)% IF (.POPCODE(.PX) EQL AOS) AND (.POPCODE(.LNKDN) EQL MOVE) THEN RETURN POPT23() %(***CHECK FOR THE PEEPHOLE: MOVN R,X MOVEM R,X ****)% ELSE IF .POPCODE(.PX) EQL MOVN AND .POPCODE(.LNKDN) EQL MOVEM THEN RETURN POPT16() ELSE RETURN FALSE END ELSE RETURN FALSE END; GLOBAL ROUTINE PEEP11= %(*************************************************************************** CHECK FOR ANY PEEPHOLES FOR WHICH THE KEY INSTR HAS OPCODE WITH THE LAST FIVE BITS EQL OCTAL 11 THIS INCLUDES ALL PEEPHOLES FOR WHICH THE KEY INSTR IS: MOVNI ***************************************************************************)% BEGIN %(***CHECK FOR PEEPHOLES FOR WHICH KEY INSTR IS: MOVNI R,1 *********)% IF AEQ1 THEN BEGIN IF .POPCODE(.PX) EQL MOVNI THEN BEGIN %(***CHECK FOR THOSE PEEPHOLES IN WHICH THE REG FIELD OF THE INSTR AFTER THE MOVNI MUSTBE THE SAME AS THAT OF THE MOVNI****)% IF REQNXTR THEN BEGIN %(***CHECK FOR: MOVNI R,1 MOVEM R,X ********)% IF .POPCODE(.LNKDN) EQL MOVEM THEN RETURN POPT04() ELSE %(***CHECK FOR: MOVNI R,1 ADDB R,X *********)% IF .POPCODE(.LNKDN) EQL ADDB THEN RETURN POPT07(); END; END; END; %(***CHECK FOR: MOVNI R,X MOVEM(ADDM,...) R,Y MOVNI R,X *****)% RETURN PEEPA0(); END; GLOBAL ROUTINE PEEP12= BEGIN IF .POPCODE(.PX) EQL ANDCAM THEN RETURN POPT74(); RETURN FALSE END; GLOBAL ROUTINE PEEP23= %(******************************************************************************** CHECK FOR ANY PEEPHOLES WITH LAST 5 BIRTS OF INSTRUCTION EQUAL TO 13 OCTAL THIS INCLUDES PEEPHOLES WHOSE OPCODES ARE: POPJ ********************************************************************************)% BEGIN IF .POPCODE(.PX) EQL POPJ AND .POPCODE(.LNKUP) EQL PUSHJ AND NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN POPT75(); RETURN FALSE END; GLOBAL ROUTINE PEEP14= %(*************************************************************************** CHECK FOR ANY PEEPHOLES WHOSE KEY INSTRS HAVE THE LAST 5 BITS OF THE OPCODE =14 THIS INCLUDES PEEPHOLES WHOSE KEY OPCODE IS: JRST ***************************************************************************)% BEGIN %(******NO PEEPHOLE FOUND HEREIN KEYS OFF OF ANYTHING BUT A JRST******)% IF .POPCODE(.PX) NEQ JRST THEN RETURN FALSE; %(***BEFORE CAN LOOK AT LABEL-TABLE ENTRIES, MUST BE SURE THAT ADDR FIELD IS A LABEL (SINCE INSTR MIGHT NOT BE JRST) ***)% IF .PRELOC(.PX) EQL CTRELOC THEN BEGIN %(******REMOVE: AOJA/SOJA X JRST Y ******)% IF NONSKIP(.POPCODE(.LNKUP2)) AND (.POPCODE(.LNKUP) EQL AOJA OR .POPCODE(.LNKUP) EQL SOJA) THEN IF DELCODE(.PX) THEN RETURN TRUE; ADDRF_.PADDR(.PX); %(***CHECK FOR JRST .+1 *****)% IF AEQNXTLAB THEN IF POPT02() THEN RETURN TRUE; %(***CHECK FOR PEEPHOLES INVOLVING JRST .+2 ***)% IF AEQ2NDLAB THEN BEGIN %(***CHECK FOR: CAM/SKIP/CAI/AOS/SOS JRST Y XXXXXX ;ANY INSTR Y: XXXXXX ;ANY INSTR ********)% IF ((T1_.POPCODE(.LNKUP)) AND #700) EQL #300 THEN BEGIN IF (.POPCODE(.LNKDN) NEQ PEEPHOLE) AND ((.T1 AND #010) EQL #010 !FOR CAM,SKIP,AOS,SOS OR (.T1 AND #770) EQL #300) !FOR CAI THEN IF POPT11() THEN RETURN TRUE END; %(******SEARCH FOR: SETZ R,0 JRST .+2 ******)% IF (.PCODEWD(.LNKUP) AND #776037777777) EQL SETZ^27 AND .PLABEL(.PX) EQL 0 AND NONSKIP(.POPCODE(.LNKUP2)) % NO SKIP INSTRCTIONS ARE PRECEDED 4-19-77 % THEN BEGIN PCODEWD(.LNKUP)_(TDZA^4+.PREG(.LNKUP))^23+.PREG(.LNKUP); PRELOC(.LNKUP)_NORELOC; RETURN DELCODE(.PX) END; END; %(****CHECK FOR: JUMP<> R,L JRST 0,FOO L: ??? ********************************)% IF (.POPCODE(.LNKUP) AND #770) EQL #320 AND NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN POPT72(); %(***CHECK FOR: CAI R,0 JRST L *********)% IF .PADDR(.LNKUP) EQL 0 THEN BEGIN IF (.PRELOC(.LNKUP) EQL NORELOC) AND ((.POPCODE(.LNKUP) AND #770) EQL CAI) THEN IF POPT19() THEN RETURN TRUE END; %(****** CHECK FOR: JRST JRST ******)% IF .POPCODE(.LNKDN) EQL JRST AND PRVNONSKIP AND .PLABEL(.LNKDN) EQL 0 THEN IF DELCODE(.LNKDN) THEN RETURN TRUE; %(***** SEARCH FOR JRSTS TO JRSTS*****)% BEGIN LOCAL CURNTJ,LASTJ,P; LASTJ_CURNTJ_.PX; UNTIL .POPCODE(.CURNTJ) NEQ JRST OR .PRELOC(.CURNTJ) NEQ CTRELOC OR .PCODEWD(.CURNTJ)<18,9> NEQ 0 DO BEGIN LASTJ_.CURNTJ; CURNTJ_.PADDR(.CURNTJ) END; IF .CURNTJ NEQ .PX THEN IF (P_.POPCODE(.CURNTJ)) EQL JRST OR .P EQL AOJA OR .P EQL POPJ OR .P EQL SOJA THEN BEGIN PRELOC(.PX)_.PRELOC(.CURNTJ); PCODEWD(.PX)_.PCODEWD(.CURNTJ); RETURN TRUE END ELSE PCODEWD(.PX)_.PCODEWD(.LASTJ); END; END; %(****CHECK FOR: ADDI R,1 JRST L AND FOR: SUBI R,1 JRST L *********)% IF .PADDR(.LNKUP) EQL 1 AND .PRELOC(.LNKUP) EQL NORELOC THEN %(******IF ADDR FIELD OF INSTR BEFORE THE JRST IS IMMEDIATE 1******)% BEGIN IF .POPCODE(.LNKUP) EQL ADDI OR .POPCODE(.LNKUP) EQL SUBI THEN RETURN POPT24() END; RETURN FALSE; END; GLOBAL ROUTINE PEEP05= %(*************************************************************************** CHECKS FOR ANY PEEPHOLES FOR WHICH THE KEY INSTR HAS THE LAST 5 BITS OF THE OPCODE EQUAL TO OCTAL 05 THIS INCLUDES THE INSTRUCTIONS: MOVSI ***************************************************************************)% BEGIN %(***CHECK FOR PEEPHOLES KEYED BY MOVSI R,0 ****)% IF AEQ0 THEN BEGIN %(***TRANSFORM MOVSI R,0 TO MOVEI R,0 SO THAT CAN GET ALL THE OPTIMS USED FOR MOVEI R,0***)% IF .POPCODE(.PX) EQL MOVSI THEN BEGIN POPCODE(.PX)_MOVEI; RETURN TRUE END END; %(***CHECK FOR: MOVSI R,X MOVEM(ADDM,...) R,Y MOVSI R,X *****)% RETURN PEEPA0(); END; GLOBAL ROUTINE PEEP20= %(*************************************************************************** CHECKS FOR PEEPHOLES KEYED BY INSTRS WHOSE OPCODES END IN OCTAL 20 THIS INCLUDES: SOJ,SETCM,TRZ,TRO ***************************************************************************)% BEGIN %(***CHECK FOR: SOJ R,0 JRST X ********************)% IF .POPCODE(.PX) EQL SOJ THEN IF PRVNONSKIP AND AEQ0 AND NXTJRST THEN RETURN POPT71(); %(***CHECK FOR: TRZ R,X TRO R,X TRZ R,Y TRO R,Y ***********************************************)% IF (.POPCODE(.PX) EQL TRO OR .POPCODE(.PX) EQL TRZ) AND PRVNONSKIP THEN RETURN POPT73(); %(***CHECK FOR: SETCM R,X MOVEM R,X ***)% IF NONOPEQNXT !IF REG,IX,INDIRECT,AND ADDRESS FIELDS OF THIS INSTR ARE ! IDENTICAL TO THOSE OF THE NEXT THEN BEGIN IF .POPCODE(.PX) EQL SETCM AND .POPCODE(.LNKDN) EQL MOVEM THEN RETURN POPT17() END; END; GLOBAL ROUTINE PEEP21= %(************************************************************* CHECKS FOR PEEPHOLES KEYED BY INSTRS ENDING IN #21 INCLUDING: TLZ,TLO **************************************************************)% BEGIN %(***CHECK FOR: TLZ R,X TLO R,X TLZ R,Y TLO R,Y *********************************************)% IF (.POPCODE(.PX) EQL TLO OR .POPCODE(.PX) EQL TLZ) AND PRVNONSKIP THEN RETURN POPT73(); END; GLOBAL ROUTINE PEEP30= %(*************************************************************************** CHECK FOR PEEPHOLES KEYED BY INSTRS HAVING THE LASET 5 BITS OF THE OPCODE EQUAL TO 30. THIS INCLUDES : SOS ***************************************************************************)% BEGIN %(***CHECK FOR: SOS R,X MOVE R,X ******)% IF NONOPEQNXT !IF REG,INDEX,INDIRECT AND ADDRESS FIELDS OF THE SOS ! ARE IDENTICAL TO THOSE OF THE NEXT INSTR THEN BEGIN IF (.POPCODE(.PX) EQL SOS) AND (.POPCODE(.LNKDN) EQL MOVE) THEN RETURN POPT23() END; RETURN FALSE END; GLOBAL ROUTINE PEEP36= %(********************************************************************** HANDLES PEEPHOLES WHOSE KEY OPCODES END IN #36 BUT FOR THE MOST PART HANDLES THE PEEPOPCODES: PEEP OPCODE=#776, IN REALITY A BLKI TO AN UNASSIGNED DEV THE BOTTOM 9 BITS ARE MORE IMPORTANT: #700 ==> TURN PEEPHOLER OFF #701 ==> TURN PEEPHOLER ON #702 ==> REVERT PEEPHOLE STATUS TO PREVIOUS VALUE CALLED WITH PEEP POINTER POINTING TO THE PEEPHOLE INSTRUCTION **********************************************************************)% BEGIN %FIRST OFF DO WE HAVE AN IORM INSTRUCTION% IF .POPCODE(.PX) EQL IORM THEN RETURN POPT74(); %(******NOW WE CHECK IF WE CAN DO SOME PEEPING******)% IF .POPCODE(.PX) NEQ PEEPHOLE THEN RETURN FALSE; IF .PCODEWD(.PX)<0,9> EQL PEEPOFF THEN BEGIN PSTACK[PSTKPTR_.PSTKPTR+1]_.PEEPOK; PEEPOK_0; END ELSE IF .PCODEWD(.PX)<0,9> EQL PEEPON THEN BEGIN PSTACK[PSTKPTR_.PSTKPTR+1]_.PEEPOK; PEEPOK_-1; END ELSE IF .PCODEWD(.PX)<0,9> EQL PEEPREV THEN BEGIN IF NOT .PEEPOK THEN PSTOP_.PX; PEEPOK_.PSTACK[.PSTKPTR]; PSTKPTR_.PSTKPTR-1; END; %(******WE MAKE THE PEEPHOLE INSTRUCTION AS PEEP NO-OP TO NOTE THAT WE HAVE PERFORMED THE ACTION. THIS SAVES US GRIEF IF WE HIT THE PEEPHOLE MORE THAN ONCE (USUALLY UNLIKELY)******)% PCODEWD(.PX)<0,9>_ PEEPNOP; RETURN FALSE END; GLOBAL ROUTINE PEEPA0= %(*************************************************************************** CHECKS FOR THE PEEPHOLES: R,X R,Y R,X THIS ROUTINE IS CALLED FROM THE ROUTINES FOR MOVE,MOVEI,MOVNI,MOVSI CALLED WITH PEEPPTR POINTING TO AN INSTRUCTION KNOWN TO BE MOVE,MOVEI, MOVSI, OR MOVNI ***************************************************************************)% BEGIN %(***IF THE INSTR AFTER NEXT IS IDENTICAL TO THIS ONE***)% IF WHOLEEQ2ND THEN BEGIN %(***...AND THE NEXT INSTR IS AN OPERATION TO MEMORY***)% IF OPTOMEM(.POPCODE(.LNKDN)) THEN BEGIN %(***...AND THE ADDRESS FIELD OF THE NEXT INSTR IS NOT EQUAL TO THE REG BEING LOADED IN THIS INSTR ***)% IF (.PRELOC(.LNKDN) NEQ NORELOC) OR (.PADDR(.LNKDN) NEQ .PREG(.PX)) THEN BEGIN %(***AND THE ADDRESS FIELD OF THE NEXT INSTR IS NOT EQUAL TO THE ADDRESS FIELD BEING LOADED***)% IF NOT MEMRFEQNXT !ADDRESS FIELD OF NXT INSTR IDENTICAL THEN RETURN POPT21() !IF CAN PERFORM THIS PEEPHOLE ELSE RETURN FALSE END ELSE RETURN FALSE END ELSE RETURN FALSE END ELSE RETURN FALSE END; %(*************************************************************************** ROUTINES TO PERFORM EACH OF THE PEEPHOLES. A ROUTINE CORRESPONDING TO A PEEPHOLE IS CALLED IF THE INSTRS OF THE PEEPHOLE HAVE BEEN DETECTED. THE FINAL CHECKS FOR LABELS WITHIN THE PEEPHOLE AND/OR SKIP INSTRS PRECEEDING THE PEEPHOLE (WHICH MIGHT INVALIDATE IT) ARE PERFORMED WITHIN THESE ROUTINES. THESE ROUTINES ARE ALL CALLED WITH THE GLOBAL PEEPPTR POINTING TO INSTRUCTION ON WHICH THE PEEPHOLE WAS KEYED EACH OF THESE ROUTINES RETURNS TRUE IF IT CAN PERFORM THE PEEPHOLE, FALSE OTHERWISE. EACH LEAVES THE GLOBAL "FRSTNEW" POINTING TO THE EARLIEST INSTR THAT IT MODIFIED (IF THE PEEPHOLE WAS PERFORMED). (THE ROUTINE WHICH THESE ROUTINES USE TO DELETE AN INSTR("DELPBI") LEAVES FRSTNEW POINTING TO THE LOC FROM WHICH INSTR WAS DELETED. FOR MOST PEEPHOLES, THIS IS ALSO THE FIRST LOC CHANGED) ***************************************************************************)% GLOBAL ROUTINE POPT01= %(************************ FOR: MOVEM R,X MOVE R,X GOES TO: MOVEM R,X CALLED WITH PEEPTR POINTING TO THE MOVEM *****************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !THE INSTR PRECEEDING MOVEM MUST NOT SKIP RETURN DELCODE(.LNKDN); !DELETE THE MOVE END; GLOBAL ROUTINE POPT02= %(************************* FOR: 5(125) NON-UUO NONSKIP JRST L L: XXXXX GOES TO: 5(125) NON-UUO NONSKIP L: XXXXX AND: 5(125) NON-UUO NONSKIP SKIP-INSTR JRST L L: XXXXX GOES TO: 5(125) NON-UUO NON-SKIP L: XXXXX CALLED WITH PEEPPTR POINTING TO THE JRST *************************)% BEGIN %(***IF THE PRECEEDING INSTR IS A TEST INSTR (UNLIKELY), DONT BOTHER***)% IF (.POPCODE(.LNKUP) AND #700) EQL #600 THEN RETURN FALSE; %(***IF THE INSTR BEFORE THE JRST DOES NOT SKIP, SIMPLY REMOVE THE JRST***)% IF PRVNONSKIP THEN BEGIN RETURN DELCODE(.PX); END ELSE %(***IF THE INSTR 2 INSTRS BACK DOES NOT SKIP 5(125) AND IF THE PREVIOUS INSTR IS A SKIP AND NOT A UUO, THEN 1. IF THE SKIP INSTR HAS NO SIDE EFFECTS, DELETE IT 2. IF IT HAS SIDE EFFECTS, MAKE IT NEVER SKIP ********)% %5(125)% IF NONSKIP(.POPCODE(.LNKUP2)) AND .POPCODE(.LNKUP) GEQ #110 THEN BEGIN IF .PLABEL(.LNKUP) THEN RETURN FALSE; IF NOT DELCODE(.PX) THEN RETURN FALSE; %(******MAKE SURE WE KNOW WHERE WE ARE******)% PX _ .LNKUP2; %(***IF THE SKIP INSTR IS CAM OR CAI, CAN DELETE IT***)% IF (T1_.POPCODE(.LNKUP) AND #770) EQL CAI OR .T1 EQL CAM THEN RETURN DELCODE(.LNKUP) !DELETE THE SKIP ELSE %(***IF INSTR IS SKIP AND REG FIELD IS 0, CAN DELETE IT***)% IF .T1 EQL SKIP AND .PREG(.LNKUP) EQL 0 THEN RETURN DELCODE(.LNKUP) !DELETE THE SKIP %(***OTHERWISE MAKE THE INSTR SKIP NEVER BY MAKING THE LAST OCTIT BE 0******)% ELSE POPCODE(.LNKUP)_.POPCODE(.LNKUP) AND #770; RETURN TRUE END ELSE RETURN FALSE; END; GLOBAL ROUTINE POPT03= %(************************* FOR: MOVEI R,0 MOVEM R,X GOES TO: SETZB R,X CALLED WITH PEEPPTR POINTING TO THE MOVEI ****************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !INSTR BEFORE MOVEI MUST NOT SKIP IF .PLABEL(.LNKDN) THEN RETURN FALSE; !MOVEM MUST NOT HAVE A LABEL %(***TRANSFORM THE MOV TO A SETZB AND DELETE THE MOVEM***)% PCODEWD(.PX)_.PCODEWD(.LNKDN); POPCODE(.PX)_SETZB; PRELOC(.PX)_.PRELOC(.LNKDN); RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT04= %(**************************** FOR: MOVNI R,1 MOVEM R,X OR: MOVEI R,1 MOVNM R,X GOES TO: SETOB R,X CALLED WITH PEEPPTR POINTING TO THE MOVNI ******************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !INSTR BEFORE MOVNI MUST NOT SKIP IF .PLABEL(.LNKDN) !MOVEM MUST NOT HAVE A LABEL THEN RETURN FALSE; %(***CHANGE THE MOV TO A SETOB, DELETE THE MOVEM***)% PCODEWD(.PX)_.PCODEWD(.LNKDN); POPCODE(.LNKDN)_SETOB; PRELOC(.PX)_.PRELOC(.LNKDN); RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT06= %(************************** FOR: MOVEI R,1 ADDB R,X GOES TO: AOS R,X CALLED WITH PEEPPTR POINTING TO THE MOVEI **************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !INSTR BEFORE MOVEI MUST NOT SKIP IF .PLABEL(.LNKDN) !ADDM MUST NOT HAVE A LABEL THEN RETURN FALSE; IF .PREG(.LNKDN) EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH AN "AOS" %(***TRANSFORM THE MOVEI TO AOS R,X AND DELETE THE ADDB***)% PCODEWD(.PX)_.PCODEWD(.LNKDN); POPCODE(.PX)_AOS; PRELOC(.PX)_.PRELOC(.LNKDN); RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT07= %(************************ FOR: MOVNI R,1 ADDB R,X GOES TO: SOS R,X CALLED WITH PEEPPTR POINTING TO THE MOVNI. ****************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !IF INSTR BEFORE MOVNI IS A SKIP ! CANNOT PERFORM OPTIM IF .PLABEL(.LNKDN) !IF ADDB HAS A LABEL, CANNOT THEN RETURN FALSE; ! PERFORM OPTIM IF .PREG(.LNKDN) EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH SOS %(***MAKE THE MOVNI BE SOS, DELETE THE ADDB***)% PCODEWD(.PX)_.PCODEWD(.LNKDN); POPCODE(.PX)_SOS; PRELOC(.PX)_.PRELOC(.LNKDN); RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT09= %(************************** FOR: MOVE R,X ASH R,1 MOVEM R,X GOES TO: MOVE R,X ADDB R,X CALLED WITH PEEPPTR POINTING TO THE ASH *****************************)% BEGIN %(***IF THE INSTR BEFORE THE MOVE SKIPS, CANNOT DO THE OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN FALSE; %(***IF EITHER THE ASH OR THE MOVEM HAS A LABEL CANNOT DO THE OPTIM***)% IF .PLABEL(.PX) THEN RETURN FALSE; IF .PLABEL(.LNKDN) THEN RETURN FALSE; %(***MAKE THE MOVEM BE A ADDB, DELETE THE ASH*****)% POPCODE(.LNKDN)_ADDB; RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT10= %(************************* FOR: MOVEI R,0 MOVEM RA,X MOVEM R,Y GOES TO: MOVEM RA,X SETZB R,Y **************************)% BEGIN %(***ALL PEEPHOLES KEYING FROM MOVEI ARE INVALIDATED BY BEING PRECEEDED BY A SKIP INSTR***)% IF NOT PRVNONSKIP THEN RETURN FALSE; %(***THE MOVEM INSTRS MUST NOT HAVE A LABEL***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PLABEL(.LNKDN2) THEN RETURN FALSE; %(***TRANSFORM THE 3RD INSTR TO "SETZB R,X" REMOVE THE 1ST INSTR***)% POPCODE(.LNKDN2)_SETZB; RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT11= %(************************** FOR: SKIP/CAM/CAI/AOS/SOS JRST Y XXXX ;ANY INSTR Y: ZZZZ ;ANY INSTR GOES TO: SKIP/CAM/CAI/AOS/SOS WITH SENSE REVERSED XXXX Y: ZZZZ CALLED WITH PEEPPTR POINTING TO THE JRST ********************************)% BEGIN %(***UNLESS THE INDEX AND INDIRECT BITS OF THE JRST ARE 0, CANNOT DO THE OPTIM***)% IF (.PCODEWD(.PX) AND #37000000) NEQ 0 THEN RETURN FALSE; %(***IF THE INITIAL SKIP/CAM/CAI/AOS/SOS IS PRECEEDED BY ANOTHER INSTR THAT CAN SKIP, CANNOT PERFORM THE OPTIMIZATION***)% IF NOT NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN FALSE; IF .PLABEL(.PX) THEN RETURN FALSE; IF .POPCODE(.LNKDN) EQL PEEPHOLE THEN RETURN FALSE; %(***REVERSE THE SENSE OF THE SKIP/CAM/CAI/AOS/SOS DO THIS BY COMPLEMENTING THE FIRST BIT OF THE LAST OCTIT******)% POPCODE(.LNKUP)_.POPCODE(.LNKUP) XOR #4; %(***DELETE THE JRST***************)% RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT14= %(****************************** FOR: ASH R,K1 ASH R,K2 GOES TO: ASH R,K1+K2 AND FOR: FSC R,K3 FSC R,K4 GOES TO: FSC R,K3+K4 CALLED WITH PEEPPTR POINTING TO THE FIRST ASH OR FSC *********************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !IF PREV INSTR SKIPS IF .PLABEL(.LNKDN) !IF 2ND ASH(FSC) HAS A LABEL THEN RETURN FALSE; %(***IF THE INDEX AND INDIRECT FIELDS ARE NOT 0, CANNOT DO THE OPTIM***)% IF ((.PCODEWD(.PX) OR .PCODEWD(.LNKDN)) AND #37000000) NEQ 0 THEN RETURN FALSE; %(***IF THE SUM OF THE 2 CONSTANTS IS GREATER THAN 18 BITS, CANNOT DO THIS OPTIM***)% T1_.POFFSET(.PX)+.POFFSET(.LNKDN); IF .T1 GTR #777777 THEN RETURN FALSE; %(***SUBSTITUTE "K1+K2" INTO THE 2ND ASH AND DELETE THE 1ST ONE***)% PADDR(.PX)_.T1; RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT15= %(*************************** FOR: MOVEM/DMOVEM R,X SKIP R,X JRST L GOES TO: MOVEM/DMOVEM R,X JUMP R,L CALLED WITH PEEPPTR POINTING TO THE MOVEM *****************************)% BEGIN %(***INSTR BEFORE THE MOVEM/DMOVEM MUST NOT SKIP***)% IF NOT PRVNONSKIP THEN RETURN FALSE; %(***THE SKIP AND JRST MUST NOT HAVE LABELS ON THEM***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PLABEL(.LNKDN2) THEN RETURN FALSE; %(***MAKE THE SKIP BE A JUMP ON THE OPPOSITE CONDITION***)% T1_(.POPCODE(.LNKDN) AND #7) XOR #4; !SET T1 TO CODE FOR OPPOSITE CONDITION !TO THAT ON WHICH SKIP OCCURED POPCODE(.LNKDN)_JUMP OR .T1; !JUMP ON CONDITION INDICATED BY T1 PADDR(.LNKDN)_.PADDR(.LNKDN2); !USE LABEL FROM JRST PRELOC(.LNKDN)_.PRELOC(.LNKDN2); %(***DELETE THE "JRST" ***)% RETURN DELCODE(.LNKDN2); END; GLOBAL ROUTINE POPT16= %(**************************** FOR: MOVN R,X MOVEM R,X GOES TO: MOVNS R,X CALLED WITH PEEPPTR POINTING TO THE MOVN ******************************)% BEGIN IF NOT NONSKIP(.POPCODE(.LNKUP)) THEN RETURN FALSE; IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PREG(.PX) EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH "MOVNS" %(***CHANGE THE MOVN TO MOVNS AND DELETE THE MOVEM***)% POPCODE(.PX)_MOVNS; RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT17= %(*************************************************************************** FOR: SETCM R,X MOVEM R,X GOES TO: SETCMB R,X CALLED WITH PEEPPTR POINTING TO SETCM ***************************************************************************)% BEGIN IF NOT NONSKIP(.POPCODE(.LNKUP)) THEN RETURN FALSE; IF .PLABEL(.LNKDN) THEN RETURN FALSE; %(***CHANGE THE SETCM TO SETCMB, DELETE THE MOVEM***)% POPCODE(.PX)_SETCMB; RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT18= %(*************************** FOR: MOVEM R,X NONSKIP-INSTR THAT DOES NOT CHANGE R OR X MOVE R,X GOES TO: MOVEM R,X NONSKIP-INSTR THAT DOES NOT CHANGE R OR X CALLED WITH PEEPPTR POINTING TO THE "MOVEM" *****************************)% BEGIN IF NOT PRVNONSKIP THEN RETURN FALSE; !THE INSTR PRECEEDING THE MOVEM MUST NOT SKIP %(***NEITHER THE INSTR BETWEEN THE "MOVEM" AND THE "MOVE" NOR THE "MOVE" SHOULD HAVE A LABEL ON IT***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PLABEL(.LNKDN2) THEN RETURN FALSE; RETURN DELCODE(.LNKDN2); !DELETE THE MOVE END; GLOBAL ROUTINE POPT19= %(******************************* FOR: CAI R,0 JRST L GOES TO: JUMP R,L CALLED WITH PEEPPTR POINTING TO THE JRST *******************************)% BEGIN %(***IF THE INSTR PRECEEDING THE CAI CAN SKIP - DONT BOTHER ***)% IF NOT NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN FALSE; %(***IF THE JRST HAS A LABEL DONT BOTHER (NOTE THAT WILL HAVE REMOVED THE LABEL IF COULD DO SO) ****)% IF .PLABEL(.PX) THEN RETURN FALSE; %(***MAKE THE COMPARE-INSTR BE A JUMP ON THE OPPOSITE CONDITION***)% T1_(.POPCODE(.LNKUP) AND #7) XOR #4; !SET T1 TO THE CODE FOR THE ! OPPOSITE CONDITION TO THAT FOR ! WHICH A SKIP OCCURRED POPCODE(.LNKUP)_JUMP OR .T1; !JUMP ON CONDITION INDICATED BY T1 PADDR(.LNKUP)_.PADDR(.PX); !USE LABEL FROM JRST PRELOC(.LNKUP)_.PRELOC(.PX); %(***DELETE THE JRST***)% RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT21= %(************************************* FOR: R,X R,Y R,X GOES TO: R,X R,Y CALLED WITH PEEPPTR POINTING TO THE FIRST *************************************)% BEGIN %(***IF THE 2ND OR 3RD INSTR OF THE PEEPHOLE HAS A LABEL ON IT CANNOT DO THIS OPTIM***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PLABEL(.LNKDN2) THEN RETURN FALSE; %(***IF THE INSTR PRECEEDING THE 1ST INSTR OF THE PEEPHOLE CAN SKIP, THEN CANNOT DO THIS OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP)) THEN RETURN FALSE; %(***DELETE THE 2ND MOVE***)% RETURN DELCODE(.LNKDN2); END; GLOBAL ROUTINE POPT22= %(*************************** FOR: MOVE R,X SKIP 0,X GOES TO: SKIP R,X AND: MOVE R,X SKIP 0,R GOES TO: SKIP R,X CALLED WITH PEEPPTR POINTING TO THE MOVE *****************************)% BEGIN %(***IF THE SKIP HAS A LABEL, CANT DO THIS OPTIM***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; %(***IF THE INSTR BEFORE THE MOVE CAN SKIP, CANT DO THE OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP)) THEN RETURN FALSE; %(***IF THE REG IN THE MOVE IS REG 0, CANNOT DO THIS OPT (SINCE CANNOT LOAD REG 0 WITH A SKIP)***)% IF .PREG(.PX) EQL REG0 THEN RETURN FALSE; %(***SET THE REG FIELD OF THE SKIPGE TO THAT OF THE MOVE***)% PREG(.LNKDN)_.PREG(.PX); %(***SET THE MEMREF FIELD OF THE SKIPGE TO THAT OF THE MOVE***)% POPCODE(.PX)_.POPCODE(.LNKDN); %(***DELETE THE SKIP***)% RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT23= %(***************************** FOR: AOS R,X MOVE R,X GOES TO: AOS R,X AND FOR: SOS R,X MOVE R,X GOES TO: SOS R,X CALLED WITH PEEPPTR POINTING TO THE AOS ******************************)% BEGIN %(***IF THE MOVE HAS A LABEL, CANNOT DO THE OPTIM***)% IF .PLABEL(.LNKDN) THEN RETURN FALSE; %(***IF THE INSTR BEFORE THE AOS CAN SKIP, CANNOT DO THE OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP)) THEN RETURN FALSE; IF .PREG(.LNKDN) EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH AOS/SOS %(***DELETE THE MOVE***)% RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT24= %(********************** FOR: ADDI R,1 JRST L GOES TO: AOJA R,L AND: SUBI R,1 JRST L GOES TO: SOJA R,L CALLED WITH PEEPPTR POINTING TO THE JRST ************************)% BEGIN %(***IF THE JRST HAS A LABEL, CANNOT DO THE OPTIM***)% IF .PLABEL(.PX) THEN RETURN FALSE; %(***IF THE INSTR PRECEEDING THE ADDI MAY SOMETIMES SKIP, CANNOT DO THIS OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN FALSE; %(***MAKE THE ADDI/SUBI BE AN "AOJA" OR "SOJA"***)% POPCODE(.LNKUP)_(IF .POPCODE(.LNKUP) EQL ADDI THEN AOJA ELSE SOJA); %(***MOVE THE JUMP ADDRESS***)% PRELOC(.LNKUP)_.PRELOC(.PX); PADDR(.LNKUP)_.PADDR(.PX); %(***DELETE THE JRST***)% RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT27= %(************************ FOR: MOVEI R1,0 MOVEI R2,0 GOES TO: SETZB R1,R2 CALLED WITH PEEPPTR POINTING TO THE FIRST MOVEI **************************)% BEGIN IF .PLABEL(.LNKDN) !IF THE 2ND MOVEI HAS A LABEL THEN RETURN FALSE; IF NOT NONSKIP(.POPCODE(.LNKUP)) !IF THE INSTR BEFORE THE 1ST MOVEI CAN SKIP THEN RETURN FALSE; %(***CHANGE THE OPCODE ON THE FIRST MOVEI TO SETZB***)% POPCODE(.PX)_SETZB; %(***CHANGE THE MEMORY FIELD OF THE FIRST MOVEI TO BE THE REG IN THE SECOND MOVEI***)% PADDR(.PX)_.PREG(.LNKDN); %(***DELETE THE SECOND MOVEI***)% RETURN DELCODE(.LNKDN); END; GLOBAL ROUTINE POPT29= %(********************* FOR: R,X MOVE R,X GOES TO: R,X CALLED WITH PEEPPTR POINTING TO THE MOVE **********************)% BEGIN %(***IF THE MOVE HAS A LABEL, CANNOT DO THIS OPTIM**)% IF .PLABEL(.PX) THEN RETURN FALSE; %(***IF THE INSTR BEFORE THE OPERATION TO MEMORY CAN SKIP, CANNOT DO THSI OPTIM***)% IF NOT NONSKIP(.POPCODE(.LNKUP2)) THEN RETURN FALSE; %(***CANNOT DO THIS OPTIM ON AN "IDIVM" BECAUSE "IDIVB" CLOBBERS THE REG AFTER THE REG BEING USED WHILE "IDIVM" DID NOT CLOBBER THAT REG ******)% IF .POPCODE(.LNKUP) EQL IDIVM THEN RETURN FALSE; %(***MAKE THE OPERATION TO MEMORY BE TO BOTH***)% POPCODE(.LNKUP)_.POPCODE(.LNKUP) OR #1; !TURN ON LOW ORDER BIT ! OF OPCODE %(***DELETE THE MOVE***)% RETURN DELCODE(.PX); END; GLOBAL ROUTINE POPT30= %(*********************** FOR: MOVE R,X JUMP R,L GOES TO: SKIP R,X JRST L CALLED WITH PEEPPTR POINTING TO THE MOVE **************************)% BEGIN IF .PLABEL(.LNKDN) !IF THE JUMP HAS A LABEL THEN RETURN FALSE; IF NOT NONSKIP(.POPCODE(.LNKUP)) !IF THE INSTR BEFORE THE MOVE CAN SKIP THEN RETURN FALSE; IF .PREG(.PX) EQL REG0 THEN RETURN FALSE; !IF THE MOVE IS TO REG 0 ! CANNOT LOAD REG 0 WITH A SKIP T1_(.POPCODE(.LNKDN) AND #7) XOR #4; !SET T1 TO THE CODE FOR ! THE CONDITION OPPOSITE TO THAT ! FOR WHICH JUMP OCCURRED POPCODE(.PX)_SKIP OR .T1; !CHANGE THE MOVE TO A SKIP ON ! THE CONDITION INDICATED BY T1 POPCODE(.LNKDN)_JRST; !CHANGE THE JUMP TO A JRST PREG(.LNKDN)_0; !TURN OFF THE REG FIELD IN THE JRST RETURN TRUE END; GLOBAL ROUTINE POPT70= %(************************************ FOR: MOVE R,X TLNE R,400000 GOES TO: SKIPGE R,X FOR: MOVE R,X TLNN R,400000 GOES TO: SKIPL R,X CALLED WITH PEEP POINTER POINTING TO TLN INSTRUCTION **************************************)% BEGIN IF .PREG(.PX) EQL 0 THEN RETURN FALSE; IF .PADDR(.PX) NEQ #400000 THEN RETURN FALSE; IF .PLABEL(.PX) EQL 0 THEN BEGIN POPCODE(.LNKUP)_IF .POPCODE(.PX) EQL TLNE THEN SKIPGE ELSE SKIPL; RETURN DELCODE(.PX); END ELSE BEGIN IF .PLABEL(.LNKUP) THEN RETURN FALSE; PADDR(.PX)_.PADDR(.LNKUP); PRELOC(.PX)_.PRELOC(.LNKUP); POPCODE(.PX)_IF .POPCODE(.PX) EQL TLNE THEN SKIPGE ELSE SKIPL; RETURN DELCODE(.LNKUP); END; END; GLOBAL ROUTINE POPT71= %(************************************************ FOR: AOJ R,0 JRST X GOES TO: AOJA R,X FOR: SOJ R,0 JRST X GOES TO: SOJA R,X CALLED WITH PEEP POINTER POINTING TO AOJ/SOJ *****************************************************)% BEGIN IF .PLABEL(.LNKDN) EQL 0 THEN BEGIN POPCODE(.PX)_.POPCODE(.PX)+#4; !AOJ/SOJ TO AOJA/SOJA PRELOC(.PX)_.PRELOC(.LNKDN); PADDR(.PX)_.PADDR(.LNKDN); RETURN DELCODE(.LNKDN); END ELSE BEGIN IF .PLABEL(.PX) THEN RETURN FALSE; POPCODE(.LNKDN)_.POPCODE(.PX)+#4; PREG(.LNKDN)_.PREG(.PX); RETURN DELCODE(.PX); END; END; GLOBAL ROUTINE POPT72= %(************************************************* FOR: JUMP<> R, L JRST FOO L: ???? GOES TO: JUMP>< R, FOO !TEST SENSE INVERTED L: ???? CALLED WITH PEEP POINTER POINTING TO JRST INSTR ********************************************************)% BEGIN IF .PLABEL(.PX) THEN RETURN FALSE; IF .PADDR(.LNKUP) EQL .LNKDN AND .PRELOC(.LNKUP) EQL CTRELOC THEN BEGIN PADDR(.LNKUP)_.PADDR(.PX); POPCODE(.LNKUP)_.POPCODE(.LNKUP) XOR 4; RETURN DELCODE(.PX); END; RETURN FALSE; END; GLOBAL ROUTINE POPT73= %(********************************************************************** FOR: T?! R,X ?==R OR L T?! R,Y !==Z OR O GOES TO: T?! R,X OR Y CALLED WITH PEEP POINTER POINTING TO THE FIRST T?! **********************************************************************)% BEGIN IF .PLABEL(.LNKDN) THEN RETURN FALSE; IF .PCODEWD(.PX)<18,5> EQL 0 AND .PCODEWD(.PX)<18,18> EQL .PCODEWD(.LNKDN)<18,18> AND (.PRELOC(.PX) OR .PRELOC(.LNKDN)) EQL NORELOC THEN BEGIN PCODEWD(.PX)<0,18>_.PCODEWD(.PX)<0,18> OR .PCODEWD(.LNKDN)<0,18>; RETURN DELCODE(.LNKDN) END ELSE RETURN FALSE END; GLOBAL ROUTINE POPT74= BEGIN IF .PCODEWD(.PX) NEQ .PCODEWD(.LNKDN2) OR .PLABEL(.LNKDN) NEQ 0 OR .PLABEL(.LNKDN2) NEQ 0 THEN RETURN FALSE; IF .PREG(.PX) NEQ .PREG(.LNKUP) OR .PRELOC(.LNKUP) NEQ NORELOC OR .PCODEWD(.LNKUP)<18,18> NEQ .PCODEWD(.LNKDN)<18,18> OR .PRELOC(.LNKDN) NEQ NORELOC OR .POPCODE(.LNKUP) EQL MOVE OR .PCODEWD(.LNKUP)<18,5> NEQ 0 THEN RETURN FALSE; DELCODE(.LNKDN2); PCODEWD(.LNKUP)<0,18>_.PCODEWD(.LNKUP)<0,18> OR .PCODEWD(.LNKDN)<0,18>; RETURN DELCODE(.LNKDN) END; GLOBAL ROUTINE POPT75= %(******************************************************************************** FOR: PUSHJ R,FOO POPJ R, GOES TO: JRST FOO CALLED WITH PEEP POINTER POINTING TO THE POPJ ********************************************************************************)% BEGIN IF .PLABEL(.PX) THEN RETURN FALSE; IF .PREG(.PX) NEQ .PREG(.LNKUP) THEN RETURN FALSE; POPCODE(.LNKUP)_ JRST; PREG(.LNKUP)_0; RETURN DELCODE(.PX) END; GLOBAL ROUTINE NONSKIP(OPCODE)= %(*************************************************************************** TO TEST WHETHER AN OPCODE IS AN INSTR THAT SKIPS . (NOTE THAT INSTRUCTIONS THAT "JUMP" ARE NOT CONSIDERED TO"SKIP" ***************************************************************************)% BEGIN %4.11% %(*****MAKE SURE NO UUO OR SPECIAL INSTRUCTION *****)% %4.11% IF .OPCODE LSS #110 THEN RETURN FALSE; %(*****IF LAST 3 BITS ARE ZERO, NEVER SKIP*****)% IF (.OPCODE AND #7) EQL 0 THEN RETURN TRUE ELSE %(***OPCODES OF THE FORM 3?? ARE EITHER SKIPS OR JUMPS***)% IF (.OPCODE AND #700) EQL #300 THEN BEGIN %(***IF HAVE CAM(31?),SKIP(33?),AOS(35?),OR SOS(37?), RETURN FALSE***)% IF (.OPCODE AND #710) EQL #310 THEN RETURN FALSE %(***IF HAVE CAI(30?) RETURN FALSE***)% ELSE IF (.OPCODE AND #770) EQL #300 THEN RETURN FALSE %(***IF HAVE JUMP(32?), AOJ(34?), OR SOJ(36?) RETURN TRUE***)% ELSE RETURN TRUE END ELSE %(***OPCODES OF THE FORM 6?? ARE TEST INSTRS***)% IF (.OPCODE AND #700) EQL #600 THEN RETURN FALSE ELSE RETURN TRUE END; GLOBAL ROUTINE OPTOMEM(OPCODE)= %(*************************************************************************** THIS ROUTINE TESTS WHETHER OPCODE IS ONE OF THE FOLLOWING: ADDM,SUBM,IMULM,IDIVM,FADRM,FSBRM,FMPRM,FDVRM,MOVEM,MOVNM IF SO IT REURNS TRUE, OTHERWISE IT RETURNS FALSE ***************************************************************************)% BEGIN %(***HALF OF THE OPCODES BEING TESTED FOR HAVE THE LAST OCTIT EQUAL TO 2***)% IF (.OPCODE AND #7) EQL #2 THEN BEGIN %(***CHECK FOR MOVEM,MOVNM,IMULM,IDIVM***)% IF (.OPCODE GEQ MOVEM) AND (.OPCODE LEQ IDIVM) THEN RETURN TRUE %(***CHECK FOR ADDM***)% ELSE IF .OPCODE EQL ADDM THEN RETURN TRUE ELSE RETURN FALSE END %(***THE OTHER HALF OF THE OPCODES BEING TESTED FOR HAVE THE LAST OCTIT EQUAL TO 6***)% ELSE IF (.OPCODE AND #7) EQL #6 THEN BEGIN %(***CHECK FOR FADRM,FSBRM,FMPRM,FDVRM***)% IF (.OPCODE GEQ FADRM) AND (.OPCODE LEQ FDVRM) THEN RETURN TRUE %(***CHECK FOR SUBM***)% ELSE IF .OPCODE EQL SUBM THEN RETURN TRUE ELSE RETURN FALSE END ELSE RETURN FALSE END; GLOBAL ROUTINE AROPTOMEM(OPCODE)= %(*************************************************************************** THIS ROUTINE TESTS WHETHER OPCODE IS ONE OF THE FOLLOWING: ADDM,SUBM,IMULM,IDIVM,FADRM,FSBRM,FMPRM,FDVRM IF SO IT RETURNS TRUE, OTHERWISE IT RETURNS FALSE ***************************************************************************)% BEGIN %(***SEVERAL OF THE OPCODES BEING TESTED FOR HAVE LAST OCTIT EQL TO 2***)% IF (.OPCODE AND #7) EQL 2 THEN BEGIN %(***CHECK FOR ADDM,IMULM, AND IDIVM***)% IF .OPCODE EQL IMULM OR .OPCODE EQL IDIVM OR .OPCODE EQL ADDM THEN RETURN TRUE END ELSE %(***THE REST OF THE OPCODES HAVE LAST OCTIT EQUAL TO 6***)% IF (.OPCODE AND #7) EQL #6 THEN BEGIN %(***CHECK FOR FADRM,FSBRM,FMPRM,FDVRM***)% IF (.OPCODE GEQ FADRM) AND (.OPCODE LEQ FDVRM) THEN RETURN TRUE %(***CHECK FOR SUBM***)% ELSE IF (.OPCODE EQL SUBM) THEN RETURN TRUE END; RETURN FALSE END; GLOBAL ROUTINE DELCODE(IND)= BEGIN IF .PLABEL(.IND) THEN RETURN FALSE; CT[.CT[.IND,0],0]_.CT[.IND,0]; CT[.CT[.IND,0],0]_.CT[.IND,0]; IF .IND EQL .PX THEN PX_.LNKUP; DELCELL(.IND); !RETURN TO FREE STORAGE RETURN TRUE END; !END OF H3PEEP.BLI