Trailing-Edge
-
PDP-10 Archives
-
BB-4157E-BM
-
fortran-compiler/peepop.bli
There are 12 other files named peepop.bli in the archive. Click here to see a list.
!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,1981 BY DIGITAL EQUIPMENT CORPORATION
!AUTHOR: S. MURPHY/G.J. BUNZA/MD/AHM
MODULE PEEPOP(SREG=#17,VREG=#15,FREG=#16,DREGS=4,RESERVE(0,1,2,3)) =
BEGIN
SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
SWITCHES LIST;
GLOBAL BIND PEEPOV = 6^24 + 0^18 + 78; ! Version Date: 25-Aug-81
%(
***** Begin Revision History *****
63 ----- ----- FIX THE PEEPHOLE "POPT22" SO THAT WONT TRY
TO LOAD REG 0 WITH A SKIP
FIX THE PEEPHOLE "POPT06" SO WONT TRY TO LOAD
REG 0 WITH AN AOS, FIX "POPT07" SO WONT
TRY TO LOAD REG 0 WITH AN SOS
FIX THE PEEPHOLE "POPT16" SO WONT TRY TO LOAD REG
0 WITH "MOVNS"
FIX PEEPHOLE "POPT23" SO WONT TRY TO LOAD REG 0
WITH AOS/SOS
FIX PEEPHOLE "POPT30" SO WONT TRY TO LOAD REG 0
WITH SKIP
64 ----- ------ DEFINE (AND USE) "REG0"
65 ----- ------ ADDITIONAL PEEPHOLES REFLECTED
IN PEEP31, POPT31, POPT32, POPT33, POPT34, POPT35
66 ----- ----- FIX BUG IN POPT33 - CANNOT DO THIS PEEPHOLE
IF THE PREVIOUS INSTR COULD SKIP
67 ----- ----- FIX BUG FOR SPR 13,451; IN PEEP05 MUST CHECK
FOR OPCOD=MOVSI BEFORE CALL PEEPA0; IN PEEP11
MUST CHECK FOR OPCOD=MONVI BEFORE
CALL PEEPA0
68 ----- ----- CHANGE REF TO THE FLAG "DEBUG" TO
"DBGLABL"
69 ----- ----- FIX DEF OF THE MACRO "NXTJRST"; FIX PEEPA0
TO NOT REMOVE 2ND MOVE R,X(R)
70 ----- ----- IN PEEPHOLE "POPT12", FOR JUMPGE, JRST
MUST COPY THE LABEL FROM THE JRST TO THE JUMP
(THIS PEEPHOLE WAS PREVIOUSLY NEVER EXECUTED DUE
TO BUG FIXED IN EDIT 69)
***** Begin Version 4A *****
71 233 ----- IN POPT12, IF THERE IS A LABEL ON THE JUMP INSTR,
IT SHOULD BE LEFT ALONE (FOR SOME UNFATHOMABLE
REASON WE WERE PUTTING IT ONTO THE DESTINATION
OF THE JUMP-WITH-SENSE-REVERSED)
72 245 15039 IN POPT12, THE ADDRESS OF A JRST IS MOVED WITHOUT
ALSO MOVING THE SYMBOL POINTER AND THE INDEX AND
INDIRECT BITS.
73 251 15652 IN POPT12, IF THE JRST IS LABELED AND INDIRECT,
DON'T ELIMINATE IT.
74 253 15425 IN PEEP02, CHECK FOR INSTRUCTIONS WHICH CLOBBER THE NEXT AC,
DIVIDES AND FIX/FLOAT ON KA-10'S
75 257 15511 ADD PEEP35 AND POPT36 TO ELIMINATE ADDI-SUBI PAIRS
GENERATED BY SOME DO LOOP EXPRESSIONS
76 261 15772 ADD XCT TO EDIT 253 (FOR FORDDT NON-OPTIMIZATIONS)
77 305 16518 ADD CHECK TO MOVEM PEEPOPT FOR NEXT INSTRUCTION
MODIFYING INDEX OF MOVEM AND MOVE
***** Begin Version 6 *****
78 1130 Q20-01647,Q20-01648
Fix bad Y field reference in PEEP02 by changing
PEEPPTR[0,PBFSYMPTR] to PEEPPTR[0,PBFADDR].
Also insert missing dot before PEEPPTR[1,PBFSYMPTR]
in macro PRVNONEQNXT. (AHM)
***** End Revision History *****
)%
FORWARD PEEPOPTIMZ,PEEPA,PEEP00,PEEP01,PEEP02,PEEP03,PEEP10,PEEP11,PEEP14,
PEEP05,PEEP20,PEEP21,PEEP22,PEEP24,PEEP25,PEEP27,PEEP30,PEEP31,
PEEP32,PEEP35,PEEPA0,
POPT01,POPT02,POPT03,POPT04,POPT05,POPT06,POPT07,POPT08,
POPT09,POPT10,POPT11,POPT12,POPT13,POPT14,POPT15,
POPT16,POPT17,POPT18,POPT19,POPT20,POPT21,POPT22,POPT23,POPT24,
POPT25,POPT26,POPT27,POPT28,POPT29,POPT30,POPT31,POPT32,POPT33,
POPT34,POPT35,POPT36,
NONSKIP,OPTOMEM,AROPTOMEM,EQVPOSSIBLE,AEQLC0, DELPBI,ADDLAB;
FORWARD CLOBNEXT;
EXTERNAL PBUFF,PBFPTR;
EXTERNAL PEEPPTR;
%(***************************************************************************
PEEPHOLE OPTIMIZER MODULE.
THE ROUTINE PEEPOPTIMZ IS CALLED AFTER EACH INSTR IS GENERATED.
A BUFFER OF THE LAST 25 INSTRUCTIONS GENERATED IS KEPT AND IT
IS OVER INSTRUCTIONS IN THIS BUFFER THAT PEEPHOLE OPTIMS ARE
PERFORMED.
AFTER EACH INSTR HAS BEEN GENERATED, THE PEEPHOLE OPTIMIZER
EXAMINES THE 3RD TO LAST INSTRUCTION IN THE BUFFER WHICH
IT USES TO KEY INTO THE VARIOUS PEEPHOLES. NOTE THAT FOR
SOME PEEPHOLES, THIS INSTR MIGHT BE THE LAST INSTR IN THE PEEPHOLE, FOR
SOM THE 1ST, ETC.
THE GLOBAL PEEPPTR POINTS TO THE INSTR TO BE USED AS A KEY.
INITIALLY, A DISPATCH IS MADE ON THE BASIS OF THE LAST
5 BITS OF THE OPCODE OF THE KEY INSTRUCTION.
THEN, DEPENDING ON WHERE THE DISPATCH WAS MADE TO, A
SERIES OF TESTS WILL BE MADE ON OTHER CHARACTERISTICS OF THE
INSTRUCTION IN RELATION TO INSTRS SURROUNDING IT.
***************************************************************************)%
%(***************************************************************************
DEFINE MACROS TO TEST CERTAIN COMMON CHARACTERISTICS OF PEEPHOLES.
THIS MACROS ASSUME THAT THE GLOBAL PEEPPTR POINTS TO THE
KEY INSTR BEING TESTED.
THEY ALSO ASSUME THE EXISTENCE OF TEMPORARIES T1, T2
***************************************************************************)%
%(***ASSUMING THAT ADDRESS FIELD OF THIS INSTR IS A LABEL AND
THAT "ADDRF" POINTS TO THE LABEL TABLE ENTRY, IS
THAT LABEL ASSIGNED TO THE NEXT INSTR****)%
MACRO AEQNXTLAB=
BEGIN
MAP BASE ADDRF:T1;
T1_.PEEPPTR[1,PBFLABEL]; !LABEL ON NEXT INSTR
IF .T1 EQL NOLABEL THEN FALSE
ELSE
IF .ADDRF[SNCADDRWD] EQL .T1[SNCADDRWD] !THIS WD IS IDENTICAL FOR ALL LABELS
! CORRESP TO THE SAME INSTR
THEN
%(***INDEX AND INDIRECT FIELDS OF THIS INSTR MUST BE 0)%
((.PEEPPTR[0,PBFINSTR] AND #37000000) EQL 0)
ELSE
FALSE
END$;
%(***ASSUMING THAT ADDRESS FIELD OF THIS INSTR IS A LABEL AND THAT
"ADDRF" POINTS TO THE LABEL TABLE ENTRY, IS THAT LABEL ASSIGNED
TO THE INSTR AFTER NEXT.***)%
MACRO AEQ2NDLAB=
BEGIN
MAP BASE ADDRF:T1;
T1_.PEEPPTR[2,PBFLABEL];
IF .T1 EQL NOLABEL THEN FALSE
ELSE
IF .ADDRF[SNCADDRWD] EQL .T1[SNCADDRWD]
THEN
((.PEEPPTR[0,PBFINSTR] AND #37000000) EQL 0) !INDEX AND INDIRECT FIELDS MUST BE 0
ELSE
FALSE
END$;
%(***ARE THE REG, IX, IND AND ADDRESS FIELDS OF THIS INSTR EQUAL TO
THOSE ON THE NEXT INSTR****)%
MACRO NONOPEQNXT=
(
((.PEEPPTR[0,PBFINSTR] AND #777777777) EQL (.PEEPPTR[1,PBFINSTR] AND #777777777) )
AND
(.PEEPPTR[0,PBFSYMPTR] EQL .PEEPPTR[1,PBFSYMPTR]) !MUST HAVE SAME SYM TAB ENTRY
! TO PREVENT PROBS WITH COMMON VARS
)$;
%(***ARE THE REG, IND, IX, AND ADDR FIELDS OF THIS INSTR EQL TO THOSE OF THE
PREV INSTR****)%
MACRO NONOPEQPRV=
(
((.PEEPPTR[0,PBFINSTR] AND #777777777) EQL (.PEEPPTR[-1,PBFINSTR] AND #777777777) )
AND
(.PEEPPTR[0,PBFSYMPTR] EQL .PEEPPTR[-1,PBFSYMPTR])
)$;
%(***ARE THE REG, IND, IX, AND ADDR FIELDS OF THIS INSTR EQL TO
THOSE OF THE INSTR AFTER NEXT****)%
MACRO NONOPEQ2ND=
(
((.PEEPPTR[0,PBFINSTR] AND #777777777) EQL (.PEEPPTR[2,PBFINSTR] AND #777777777) )
AND
(.PEEPPTR[0,PBFSYMPTR] EQL .PEEPPTR[2,PBFSYMPTR])
)$;
%(***ARE THE REG, IND, IX, AND ADDR FIELDS OF THE PREVIOUS INSTR EQL
TO THOSE OF THE NEXT INSTR*****)%
MACRO PRVNONEQNXT=
(
( (.PEEPPTR[-1,PBFINSTR] AND #777777777) EQL (.PEEPPTR[1,PBFINSTR] AND #777777777) )
AND
(.PEEPPTR[-1,PBFSYMPTR] EQL .PEEPPTR[1,PBFSYMPTR])
)$; %1130%
%(***ARE THE INDIRECT, INDEX, AND ADDRESS FIELDS OF THIS INSTR EQL TO
THOSE OF THE NEXT INSTR***)%
MACRO MEMRFEQNXT=
(
(.PEEPPTR[0,PBFMEMREF] EQL .PEEPPTR[1,PBFMEMREF])
AND
(.PEEPPTR[0,PBFSYMPTR] EQL .PEEPPTR[1,PBFSYMPTR])
)$;
%(***IS THE REG FIELD OF THIS INSTR EQL TO THE REG FIELD OF THE NEXT***)%
MACRO REQNXTR=
(.PEEPPTR[0,PBFREG] EQL .PEEPPTR[1,PBFREG]) $;
%(***IS THE REG FIELD OF THIS INSTR EQL TO THE REG FIELD OF THE PREV INSTR***)%
MACRO REQPRVR=
(.PEEPPTR[0,PBFREG] EQL .PEEPPTR[-1,PBFREG]) $;
%(***IS THE REG FIELD OF THE KEY INSTR EAL TO THE REG FIELD OF INSTR AFTER NEXT***)%
MACRO REQ2NDR=
(.PEEPPTR[0,PBFREG] EQL .PEEPPTR[2,PBFREG]) $;
%(***IS THIS INSTR(INCLUDING ADDR,INDIRECT,REG,INDEX,AND OPCODE) IDENTICAL TO THE
INSTR AFTER NEXT***)%
MACRO WHOLEEQ2ND=
((.PEEPPTR[0,PBFINSTR] EQL .PEEPPTR[2,PBFINSTR]) AND (.PEEPPTR[0,PBFSYMPTR] EQL .PEEPPTR[2,PBFSYMPTR]))$;
%(******ARE THE CURRENT INSTRUC AND THE NEXT IDENTICAL
AND NEITHER HAS A SYMBOL TABLE REF*****)%
MACRO WHOLEQNXTK=
((.PEEPPTR[0,PBFINSTR] EQL .PEEPPTR[1,PBFINSTR]) AND
(.PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM) AND
(.PEEPPTR[1,PBFSYMPTR] EQL PBFNOSYM))$;
%(***IS ADDRESS (INDIRECT AND INDEX) FIELD EQUAL TO 0*******)%
MACRO AEQ0=
(.PEEPPTR[0,PBFMEMREF] EQL 0 AND .PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM)$;
%(***IS ADDRESS (INDIRECT AND INDEX) FIELD EQUAL TO 1********)%
MACRO AEQ1=
(.PEEPPTR[0,PBFMEMREF] EQL 1 AND .PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM)$;
%(***IS ADDRESS FIELD EQUAL TO REGISTER FIELD***)%
MACRO AEQR=
(.PEEPPTR[0,PBFREG] EQL .PEEPPTR[0,PBFMEMREF] AND .PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM)$;
%(***IS NEXT INSTR A "JRST*******)%
MACRO NXTJRST=
(.PEEPPTR[1,PBFOPCOD] EQL JRSTOCD)$;
%(***IS PREVIOUS INSTRUCTION A NON-SKIP INSTR***)%
MACRO PRVNONSKIP=
(NONSKIP(.PEEPPTR[-1,PBFOPCOD]) )$;
%(***IS NEXT INSTR A NON-SKIP INSTR*****)%
MACRO NXTNONSKIP=
(NONSKIP(.PEEPPTR[1,PBFOPCOD]) )$;
%(******IS SECOND INSTRUCTION BACK A NON SKIP INSTRUCTION*****)%
MACRO PRV2NONSKIP=
(NONSKIP(.PEEPPTR[-2,PBFOPCOD]))$;
MAP PEEPHOLE PEEPPTR; !PTR TO THE WORD ON WHICH ARE KEYING
OWN FRSTNEW; !PTR TO THE FIRST INSTR CHANGED BY THE
! PEEPHOLE JUST PERFORMED
! CHECK FOR PEEPHOLES
OWN BASE 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)
GLOBAL ROUTINE PEEPOPTIMZ=
%(***************************************************************************
PEEPHOLE OPTIMIZER.
THIS ROUTINE IS CALLED WITH THE GLOBAL PEEPPTR SET TO
PT TO THE 3RD TO LAST INSTR INSTRUCTION GENERATED.
IT CALLS THE ROUTINE "PEEPA" TO PERFORM ANY PEEPHOLE OPTIM THAT
THIS INSTR KEYS TO THAT CAN BE PERFORMED.
IF AN OPTIMIZ CAN BE PERFORMED, IT THEN PERFORMS ANY OPTIMS THAT
CAN BE KEYED OFF OF ANY INSTRS STARTING WITH THE INSTR
3 BEFORE THE EARLIEST INSTR CHANGED BY THE PEEPHOLE.
***************************************************************************)%
BEGIN
LOCAL SAVPEEPPTR;
LOCAL PPTR1; !USED FOR ADDITIONAL PASS OVER ALL INSTRS CHANGED
IF PEEPA()
THEN
%(***IF WERE ABLE TO PERFORM AN OPTIMIZATION****)%
BEGIN
SAVPEEPPTR_.PEEPPTR; !SAVE BECAUSE ARE RECURSIVE
PPTR1_.FRSTNEW-2*PBFENTSIZE; !2 INSTRS BEFORE 1ST NEW ONE
%(***DONT GO BACK ANY FURTHER THAN THE 3RD INSTR IN THE BUFFER (SINCE SOME
PEEPHOLES REQUIRE LOOKING AT THE 2 INSTRS PRECEEDING THE KEY INSTR) **)%
IF .PPTR1 LSS ( PBUFF+2*PBFENTSIZE) THEN PPTR1_(PBUFF+2*PBFENTSIZE);
UNTIL (.PPTR1 GTR .SAVPEEPPTR) OR (.PPTR1 GTR .PBFPTR-3*PBFENTSIZE)
DO
BEGIN
PEEPPTR_.PPTR1;
PEEPOPTIMZ();
PPTR1_.PPTR1+PBFENTSIZE;
END;
END;
END;
GLOBAL ROUTINE PEEPA=
%(***************************************************************************
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
RETURN
( CASE .PEEPPTR[0,PBFOPKEY] OF SET
PEEP00(); !ASH (240 ENDS IN 00), AND MOVE (200 ENDS IN 00)
PEEP01(); !MOVEI
PEEP02(); !MOVEM
PEEP03(); !SETZB
FALSE; !NO KEYS ENDING IN 04
PEEP05(); ! MOVSI
FALSE; ! 06
FALSE; ! 07
PEEP10(); ! AOS (#350 HAS LAST 5 BITS EQL TO 10),MOVN(#210)
PEEP11(); !MOVNI
FALSE; ! 12 (MOVNM,SETCAM)
FALSE; ! 13
PEEP14(); !JRST
FALSE; ! 15
FALSE; ! 16
FALSE; ! 17
PEEP20(); ! DMOVE, SETCM(#460)
PEEP21(); !JUMPL
PEEP22(); ! FIX
FALSE; ! 23
PEEP24(); ! DMOVEM
PEEP25(); !JUMPGE
FALSE; ! 26
PEEP27(); ! FLTR
PEEP30(); !SOS
PEEP31(); !DFN
PEEP32(); !FSC
FALSE; ! 33
FALSE; ! 34
PEEP35(); !SUBI
FALSE; ! 36
FALSE ! 37
TES )
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
***************************************************************************)%
BEGIN
%(***CHECK FOR PEEPHOLES KEYED BY MOVE***)%
IF .PEEPPTR[0,PBFOPCOD] EQL MOVEOCD
THEN
BEGIN
%(***CHECK FOR THE PEEPHOLE
<ADDM,SUBM,IMULM,IDIVM,FADRM,...> 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(.PEEPPTR[-1,PBFOPCOD]) !IF PREV INSTR IS TO MEMORY
THEN(IF POPT29() THEN RETURN TRUE)
END;
%(***CHECK FOR:
MOVE R,X
SKIP<GE,G,L,LE,N,NE> 0,X
AND FOR:
MOVE R,X
SKIP<GE,G,L,LE,N,NE> 0,R
********)%
IF ((.PEEPPTR[1,PBFOPCOD] AND #770) EQL SKIPOCD) AND (.PEEPPTR[1,PBFREG] 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 .PEEPPTR[0,PBFREG] EQL .PEEPPTR[1,PBFMEMREF]
AND .PEEPPTR[1,PBFSYMPTR] EQL PBFNOSYM
THEN RETURN POPT22()
END;
%(***CHECK FOR THE PEEPHOLE
MOVE R,X
JUMP<E,N,GT,LT,GE,LE> R,L
******)%
IF .PEEPPTR[0,PBFREG] EQL .PEEPPTR[1,PBFREG]
THEN
BEGIN
IF (.PEEPPTR[1,PBFOPCOD] AND #770) EQL JUMPOCD
THEN RETURN POPT30()
END;
%(***CHECK FOR THE PEEPHOLE:
MOVE R,X
<MOVEM,ADDM,...> R,Y
MOVE R,X
*******)%
RETURN PEEPA0()
END
%(***CHECK FOR PEEPHOLES KEYED BY ASH***)%
ELSE
IF .PEEPPTR[0,PBFOPCOD] EQL ASHOCD
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 (.PEEPPTR[-1,PBFOPCOD] EQL MOVEOCD)
AND (.PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD)
THEN RETURN POPT09();
END;
END;
%(****CHECK FOR:
ASH R,A
ASH R,B
******)%
IF .PEEPPTR[1,PBFOPCOD] EQL ASHOCD
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 ((.PEEPPTR[1,PBFADDR] XOR .PEEPPTR[0,PBFADDR]) AND #400000) EQL 0
THEN RETURN POPT14();
END
END;
RETURN FALSE;
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 .PEEPPTR[0,PBFOPCOD] EQL MOVEIOCD
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 .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
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 .PEEPPTR[2,PBFOPCOD] EQL MOVEMOCD
AND .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
THEN RETURN POPT10();
END
ELSE
%(***CHECK FOR:
MOVEI R1,0
MOVEI R2,0
*******)%
IF .PEEPPTR[1,PBFMEMREF] EQL 0 AND .PEEPPTR[1,PBFSYMPTR] EQL PBFNOSYM
THEN
BEGIN
IF .PEEPPTR[1,PBFOPCOD] EQL MOVEIOCD
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 .PEEPPTR[1,PBFOPCOD] EQL ADDBOCD
THEN RETURN POPT06()
END
END
ELSE
%(***CHECK FOR THE PEEPHOLE:
MOVEI R,X
<MOVEM,ADDM,...> 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 .PEEPPTR[0,PBFOPCOD] EQL MOVEMOCD
THEN
BEGIN
%(***CHECK FOR:
MOVEM R,X
MOVE R,X
******)%
IF .PEEPPTR[1,PBFOPCOD] EQL MOVEOCD
THEN
RETURN POPT01()
ELSE
%(****CHECK FOR:
MOVEM R,X
SKIP<N,E,L,LE,G,GE> R,X
JRST L
*********)%
IF .PEEPPTR[2,PBFOPCOD] EQL JRSTOCD
THEN
BEGIN
IF (.PEEPPTR[1,PBFOPCOD] AND #770) EQL SKIPOCD
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 .PEEPPTR[0,PBFOPCOD] EQL MOVEMOCD
THEN
BEGIN
%(***CHECK FOR:
MOVEM R,X
NONSKIP-INSTR THAT DOES NOT CHANGE R OR X
MOVE R,X
*******)%
IF .PEEPPTR[2,PBFOPCOD] EQL MOVEOCD
THEN
BEGIN
%(***IF THE INSTR AFTER THE MOVEM CAN SKIP, DONT BOTHER***)%
IF NOT NONSKIP(.PEEPPTR[1,PBFOPCOD]) 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(.PEEPPTR[1,PBFOPCOD]) THEN RETURN FALSE
ELSE
! IF THE ADDR REF IN THE NEXT INSTR IS X
IF (.PEEPPTR[0,PBFMEMREF] EQL .PEEPPTR[1,PBFMEMREF]) THEN RETURN FALSE
ELSE
! IF THE ADDR OF THE NEXT INSTR IS R
IF (.PEEPPTR[1,PBFSYMPTR] EQL PBFNOSYM)
AND (.PEEPPTR[1,PBFMEMREF] EQL .PEEPPTR[0,PBFREG])
THEN RETURN FALSE
! IF X IS INDEXED, NEED TO CHECK THAT NEXT INSTR
! DOES NOT MODIFY THE INDEX
ELSE
IF (.PEEPPTR[0,PBFINDEX] AND #17) NEQ 0 ! IF MOVEM AND MOVE ARE INDEXED
AND
(.PEEPPTR[0,PBFINDEX] AND #17) EQL .PEEPPTR[1,PBFREG] ! AND INDEX IS R OF NEXT INSTR
AND NOT OPTOMEM(.PEEPPTR[1,PBFOPCOD]) ! AND NEXT INSTR MODIFIES INDEX
THEN RETURN FALSE
ELSE
! IF X IS A REG, THEN MUST CHECK FOR REG ON NEXT INSTR=X
IF (.PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM)
%1130% AND (.PEEPPTR[0,PBFADDR] EQL .PEEPPTR[1,PBFREG])
THEN RETURN FALSE
ELSE
! SEE IF DIV R-1, OR KA-10 FIX R-1
IF CLOBNEXT() 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
***************************************************************************)%
BEGIN
%(***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 .PEEPPTR[0,PBFOPCOD] EQL SETZBOCD
THEN
BEGIN
%(***CHECK FOR:
SETZB R,X
MOVE R,X
*******)%
IF .PEEPPTR[1,PBFOPCOD] EQL MOVEOCD
THEN
RETURN POPT01(); !USE SAME ROUTINE AS FOR MOVEM-MOVE
END
END;
RETURN FALSE
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 (.PEEPPTR[0,PBFOPCOD] EQL AOSOCD) AND (.PEEPPTR[1,PBFOPCOD] EQL MOVEOCD)
THEN RETURN POPT23()
%(***CHECK FOR THE PEEPHOLE:
MOVN R,X
MOVEM R,X
****)%
ELSE
IF .PEEPPTR[0,PBFOPCOD] EQL MOVNOCD AND .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
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 .PEEPPTR[0,PBFOPCOD] EQL MOVNIOCD
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 .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
THEN RETURN POPT04()
ELSE
%(***CHECK FOR:
MOVNI R,1
ADDB R,X
*********)%
IF .PEEPPTR[1,PBFOPCOD] EQL ADDBOCD
THEN RETURN POPT07();
END;
END;
END;
%(***CHECK FOR:
MOVNI R,X
MOVEM(ADDM,...) R,Y
MOVNI R,X
*****)%
IF .PEEPPTR[0,PBFOPCOD] EQL MOVNIOCD
THEN
RETURN PEEPA0()
ELSE 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
BIND SETZOCD=#400;
%(******NO PEEP FOUND HEREIN (AT THIS TIME) USES ANYTHING
BUT A JRST TO KEY OFF OF! ******)%
IF .PEEPPTR[0,PBFOPCOD] NEQ JRSTOCD 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 .PEEPPTR[0,PBFSYMPTR] EQL PBFLABREF
THEN
BEGIN
%(***IF THE JRST HAS A LABEL ON IT, THEN IF POSSIBLE MOVE THAT
LABEL TO THE LOC OF THE ADDRESS OF THE JRST***)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL
THEN POPT13();
%(******CHECK FOR:
JUMP??/AOJ??/SOJ?? X
JRST X
******)%
IF NONOPEQPRV THEN IF POPT35() THEN RETURN TRUE;
ADDRF_.PEEPPTR[0,PBFADDR];
%(***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_.PEEPPTR[-1,PBFOPCOD]) AND #700) EQL #300
THEN
BEGIN
IF (.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;
%(******CHECK FOR:
MOVEI R,0 OR SETZ R,0
JRST .+2 JRST .+2
******)%
IF (T1_.PEEPPTR[-1,PBFOPCOD]) EQL MOVEIOCD
OR (.T1 EQL SETZOCD)
THEN IF POPT31() THEN RETURN TRUE;
%(******CHECK FOR:
MOVE R,X
JRST .+2
******)%
IF .PEEPPTR[-1,PBFOPCOD] EQL MOVEOCD
THEN IF POPT32() THEN RETURN TRUE;
END;
%(******CHECK FOR:
CAI/CAM
JRST L
CAI/CAM
JRST L
******)%
IF (.PEEPPTR[-1,PBFOPCOD] AND #760) EQL CAIOCD
AND (.PEEPPTR[1,PBFOPCOD] AND #760) EQL CAIOCD
AND WHOLEEQ2ND
THEN IF POPT33() THEN RETURN TRUE;
%(***CHECK FOR:
CAI<G,GE,L,LE,N,E> R,0
JRST L
*********)%
IF .PEEPPTR[-1,PBFMEMREF] EQL 0
THEN
BEGIN
IF (.PEEPPTR[-1,PBFSYMPTR] EQL PBFNOSYM) AND ((.PEEPPTR[-1,PBFOPCOD] AND #770) EQL CAIOCD)
THEN IF POPT19() THEN RETURN TRUE;
END;
END;
%(****CHECK FOR:
ADDI R,1
JRST L
AND FOR:
SUBI R,1
JRST L
*********)%
IF .PEEPPTR[-1,PBFMEMREF] EQL 1 AND .PEEPPTR[-1,PBFSYMPTR] EQL PBFNOSYM
THEN
%(***IF ADDR FIELD OF INSTR BEFORE THE JRST IS IMMEDIATE 1***)%
BEGIN
IF .PEEPPTR[-1,PBFOPCOD] EQL ADDIOCD OR .PEEPPTR[-1,PBFOPCOD] EQL SUBIOCD
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 .PEEPPTR[0,PBFOPCOD] EQL MOVSIOCD
THEN
BEGIN
PEEPPTR[0,PBFOPCOD]_MOVEIOCD;
FRSTNEW_.PEEPPTR;
RETURN TRUE
END
END;
%(***CHECK FOR:
MOVSI R,X
MOVEM(ADDM,...) R,Y
MOVSI R,X
*****)%
IF .PEEPPTR[0,PBFOPCOD] EQL MOVSIOCD
THEN
RETURN PEEPA0()
ELSE RETURN FALSE
END;
GLOBAL ROUTINE PEEP20=
%(***************************************************************************
CHECKS FOR PEEPHOLES KEYED BY INSTRS WHOSE OPCODES END IN OCTAL 20
THIS INCLUDES:
DMOVE,SETCM
***************************************************************************)%
BEGIN
%(***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 .PEEPPTR[0,PBFOPCOD] EQL SETCMOCD AND .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
THEN RETURN POPT17()
END;
%(***CHECK FOR:
DMOVE R,[0
0]
*******)%
IF (T1_.PEEPPTR[0,PBFSYMPTR]) GTR PBFCODMAX !IF THE "SYMBOL TABLE PTR" IS
! NOT REALLY SOME SPECIAL CODE
THEN
BEGIN
MAP BASE T1;
IF .T1[OPR1] EQL CONSTFL !IF ARE LOADING A CONSTANT
THEN
BEGIN
%(***IF BOTH WORDS OF THE CONSTANT ARE 0***)%
IF .T1[CONST1] EQL 0 AND .T1[CONST2] EQL 0
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL DMOVEOCD
THEN
BEGIN
%(***FOR:
DMOVE R,[0-0]
DMOVEM R,X
*******)%
IF REQNXTR AND .PEEPPTR[1,PBFOPCOD] EQL DMOVEMOCD
THEN
BEGIN
IF POPT28()
THEN RETURN TRUE
END;
%(***IF HAVE DMOVE R,[0-0] AND
DO NOT IMMEDIATELY STORE THE 0'S***)%
RETURN POPT26()
END
END
END
END;
RETURN FALSE;
END;
GLOBAL ROUTINE PEEP21=
%(***************************************************************************
CHECKS FOR ANY PEEPHOLES KEYED BY INSTRS WHOSE OPCODES END IN
OCTAL 21
THIS INCLUDES:
JUMPL
***************************************************************************)%
BEGIN
%(***CANNOT LOOK AT LABEL TABLE ENTRY FOR ADDR FIELD UNLESS ARE SURE THAT
ADDRESS FIELD IS A LABEL (SINCE INSTR MIGHT NOT BE JUMPL)***)%
IF .PEEPPTR[0,PBFSYMPTR] EQL PBFLABREF
THEN
BEGIN
ADDRF_.PEEPPTR[0,PBFADDR];
%(***CHECK FOR:
JUMPL X
JRST Y
X: ZZZZZ ;ANY INSTR
*******)%
IF AEQ2NDLAB
THEN
BEGIN
IF NXTJRST
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL JUMPLOCD
THEN
RETURN POPT12();
END;
END;
END;
RETURN FALSE
END;
GLOBAL ROUTINE PEEP22=
%(***************************************************************************
CHECKS FOR ANY PEEPHOLES KEYED BY INSTRS WHOSE OPCODES END IN
OCTAL 22. THIS INCLUDES:
FIX
***************************************************************************)%
BEGIN
%(***CHECK FOR:
MOVE R,X
FIX R,R
******)%
IF REQPRVR
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL FIXOCD AND .PEEPPTR[-1,PBFOPCOD] EQL MOVEOCD
THEN
BEGIN
IF (.PEEPPTR[0,PBFREG] EQL .PEEPPTR[0,PBFMEMREF])
AND .PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM
THEN
RETURN POPT20()
END
END;
RETURN FALSE;
END;
GLOBAL ROUTINE PEEP24=
%(***************************************************************************
CHECK FOR PEEPHOLES KEYED BY INSTRS HAVING THE LAST 5 BITS OF THE OPCODE
EQUAL TO 24
THIS INCLUDES THE INSTRS:
DMOVEM
***************************************************************************)%
BEGIN
%(***CHECK FOR PEEPHOLES FOR WHICH REG AND ADDR OF THE INSTR AFTER THE DMOVEM
ARE THE SAME AS THEY ARE FOR THE DMOVEM
*******)%
IF NONOPEQNXT
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL DMOVEMOCD
THEN
BEGIN
%(***CHECK FOR:
DMOVEM R,X
DMOVE R,X
****)%
IF .PEEPPTR[1,PBFOPCOD] EQL DMOVEOCD
THEN RETURN POPT01() !USE SAME ROUTINE AS USE
! FOR MOVEM-MOVE
%(***CHECK FOR:
DMOVEM R,X
MOVE R,X
******)%
ELSE
IF .PEEPPTR[1,PBFOPCOD] EQL MOVEOCD
THEN RETURN POPT01()
ELSE
%(***CHECK FOR:
DMOVEM R,X
SKIP<N,E,L,LE,G,GE> R,X
JRST L
********)%
IF .PEEPPTR[2,PBFOPCOD] EQL JRSTOCD
THEN
BEGIN
IF (.PEEPPTR[1,PBFOPCOD] AND #770) EQL SKIPOCD
THEN RETURN POPT15(); !USE SAME ROUTINE AS FOR MOVEM-SKIP-JRST
END
END
END
ELSE RETURN FALSE
END;
GLOBAL ROUTINE PEEP25=
%(***************************************************************************
CHECK FOR PEEPHOLES KEYED BY INSTRS HAVING THE LAST 5 BITS OF THE
OPCODE EQUAL TO 25.
THIS INCLUDES THE INSTRUCTIONS:
JUMPGE
***************************************************************************)%
BEGIN
%(***CANNOT LOOK AT LABEL TABLE ENTRY FOR ADDRESS UNLESS KNOW
THAT ADDRESS FIELD IS A LABEL (INSTR MIGHT NOT BE JUMPGE) ****)%
IF .PEEPPTR[0,PBFSYMPTR] EQL PBFLABREF
THEN
BEGIN
ADDRF_.PEEPPTR[0,PBFADDR];
%(***CHECK FOR:
JUMPGE X
JRST Y
X: ZZZZZ ;ANY INSTR
*******)%
IF AEQ2NDLAB
THEN
BEGIN
IF NXTJRST
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL JUMPGEOCD
THEN
RETURN POPT12();
END;
END;
END;
RETURN FALSE;
END;
GLOBAL ROUTINE PEEP27=
%(***************************************************************************
CHECK FOR PEEPHOLES KEYED BY INSTRS HAVING THE LAST 5 BITS OF THE OPCODE
EQUAL TO 27. THIS INCLUDES THE INSTRS:
FLTR
***************************************************************************)%
BEGIN
%(***CHECK FOR:
MOVE R,X
FLTR R,R
******)%
IF REQPRVR
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL FLTROCD AND .PEEPPTR[-1,PBFOPCOD] EQL MOVEOCD
THEN
BEGIN
IF (.PEEPPTR[0,PBFREG] EQL .PEEPPTR[0,PBFMEMREF])
AND .PEEPPTR[0,PBFSYMPTR] EQL PBFNOSYM
THEN
RETURN POPT20()
END
END;
RETURN FALSE;
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 (.PEEPPTR[0,PBFOPCOD] EQL SOSOCD) AND (.PEEPPTR[1,PBFOPCOD] EQL MOVEOCD)
THEN RETURN POPT23()
END;
RETURN FALSE
END;
GLOBAL ROUTINE PEEP31=
%(***********************************************************************
CHECK FOR PEEPS KEYED BY INSTRUCTIONS HAVING THE LAST 5 BITS
OF THE OPCODE EQUAL TO 31 OCTAL.
THIS INCLUDES:
DFN
***********************************************************************)%
BEGIN
BIND DFNOCD=#131;
%(******CHECK FOR:
SKIPGE R,X
DFN R,R+1
DFN R,R+1
******)%
IF .PEEPPTR[0,PBFOPCOD] EQL DFNOCD AND WHOLEQNXTK
THEN RETURN POPT34();
RETURN FALSE
END;
GLOBAL ROUTINE PEEP32=
%(***************************************************************************
CHECKS FOR PEEPHOLES KEYED BY INSTRS WHOSE OPCODES END IN
OCTAL 32
THIS INCLUDES THE INSTRS:
FSC
***************************************************************************)%
BEGIN
%(***CHECK FOR:
MOVE R,X
FSC R,1
MOVEM R,X
*******)%
IF PRVNONEQNXT
THEN
BEGIN
IF AEQ1
THEN
BEGIN
IF REQNXTR
THEN
BEGIN
IF .PEEPPTR[0,PBFOPCOD] EQL FSCOCD
AND .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
AND .PEEPPTR[-1,PBFOPCOD] EQL MOVEOCD
THEN RETURN POPT08();
END;
END;
END;
%(***CHECK FOR:
FSC R,A
FSC R,B
*******)%
IF .PEEPPTR[1,PBFOPCOD] EQL FSCOCD
THEN
BEGIN
IF REQNXTR
THEN
BEGIN
IF PEEPPTR[0,PBFOPCOD] EQL FSCOCD
THEN RETURN POPT14();
END;
END;
RETURN FALSE;
END;
GLOBAL ROUTINE PEEP35=
%(**********************************************************************
CHECK FOR PEEPHOLES KEYED BY INSTRS HAVING THE LAST 5 BITS OF THE
OPCODE EQUAL TO 35
THIS INCLUDES THE INSTRUCTIONS:
SUBI
**********************************************************************)%
BEGIN
%(****CHECK FOR ADDI SUBI PAIRS WHICH OFFSET EACH OTHER.
THESE CAN BE GENERATED BY DO LOOP EXPRESSIONS AND BEST
CAUGHT HERE.
*****)%
IF .PEEPPTR[0,PBFOPCOD] EQL SUBIOCD
THEN RETURN POPT36();
RETURN FALSE
END;
GLOBAL ROUTINE PEEPA0=
%(***************************************************************************
CHECKS FOR THE PEEPHOLES:
<MOVE,MOVEI,MOVNI,MOVSI> R,X
<MOVEM,ADDM,SUBM,IMULM,IDIVM,FADRM,...> R,Y
<MOVE,MOVEI,MOVNI,MOVSI> 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
IF (.PEEPPTR[0,PBFINDEX] NEQ 0 ) AND (.PEEPPTR[0,PBFINDEX] EQL .PEEPPTR[0,PBFREG])
THEN RETURN FALSE; !IF THIS INSTR USES AN INDEX REG WHOSE VAL IT CHANGES
! CANNOT DO THE PEEPHOLE
%(***...AND THE NEXT INSTR IS AN OPERATION TO MEMORY***)%
IF OPTOMEM(.PEEPPTR[1,PBFOPCOD])
THEN
BEGIN
%(***...AND THE ADDRESS FIELD OF THE NEXT INSTR IS NOT EQUAL TO
THE REG BEING LOADED IN THIS INSTR ***)%
IF (.PEEPPTR[1,PBFSYMPTR] NEQ PBFNOSYM) OR (.PEEPPTR[1,PBFMEMREF] NEQ .PEEPPTR[0,PBFREG])
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
! OR POSSIBLE EQUIVALENCE BETWEEN THE 2 SYMS PREVENTS THE PEEPHOLE
AND NOT EQVPOSSIBLE(.PEEPPTR[0,PBFSYMPTR],.PEEPPTR[1,PBFSYMPTR])
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
AND:
DMOVEM R,X
DMOVE R,X
GOES TO:
DMOVEM R,X
AND:
DMOVEM R,X
MOVE R,X
GOES TO:
DMOVEM R,X
CALLED WITH PEEPTR POINTING TO THE MOVEM/DMOVEM
*****************************)%
BEGIN
IF NOT PRVNONSKIP THEN RETURN FALSE; !THE INSTR PRECEEDING MOVEM MUST NOT SKIP
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !THERE MUST NOT BE A LABEL ON THE MOVE
THEN RETURN FALSE;
DELPBI(.PEEPPTR+PBFENTSIZE); !DELETE THE MOVE
RETURN TRUE
END;
GLOBAL ROUTINE POPT02=
%(*************************
FOR:
NONSKIP
JRST L
L: XXXXX
GOES TO:
NONSKIP
L: XXXXX
AND:
NONSKIP
SKIP-INSTR
JRST L
L: XXXXX
GOES TO:
NON-SKIP
L: XXXXX
(NOTE: IN THE FIRST RELEASE WE DONT BOTHER FOLDING:
NONSKIP
SKIP-INSTR
SKIP-INSTR
JRST L
L: XXXX
WHICH COULD BE FOLDED TO:
NONSKIP
L: XXXX
ETC. )
CALLED WITH PEEPPTR POINTING TO THE JRST
*************************)%
BEGIN
%(***UNLESS THE INDEX AND INDIRECT BITS OF THE JRST ARE 0, CANNOT DO THE OPTIM***)%
IF (.PEEPPTR[0,PBFINSTR] AND #37000000) NEQ 0 THEN RETURN FALSE;
%(***IF THE PRECEEDING INSTR IS A TEST INSTR (UNLIKELY), DONT BOTHER***)%
IF (.PEEPPTR[-1,PBFOPCOD] AND #700) EQL #600
THEN RETURN FALSE;
%(***IF THE INSTR BEFORE THE JRST DOES NOT SKIP, SIMPLY REMOVE THE JRST***)%
IF PRVNONSKIP
THEN
BEGIN
DELPBI(.PEEPPTR);
RETURN TRUE
END
ELSE
%(***IF THE INSTR 2 INSTRS BACK DOES NOT SKIP
AND IF THE PREVIOUS INSTR IS A SKIP, THEN
1. IF THE SKIP INSTR HAS NO SIDE EFFECTS, DELETE IT
2. IF IT HAS SIDE EFFECTS, MAKE IT NEVER SKIP
********)%
IF NONSKIP(.PEEPPTR[-2,PBFOPCOD])
THEN
BEGIN
DELPBI(.PEEPPTR); !DELETE THE JRST
%(***IF THE SKIP INSTR IS CAM OR CAI, CAN DELETE IT***)%
IF (T1_.PEEPPTR[-1,PBFOPCOD] AND #770) EQL CAIOCD
OR .T1 EQL CAMOCD
THEN DELPBI(.PEEPPTR-PBFENTSIZE)
ELSE
%(***IF INSTR IS SKIP AND REG FIELD IS 0, CAN DELETE IT***)%
IF .T1 EQL SKIPOCD AND .PEEPPTR[-1,PBFREG] EQL 0
THEN DELPBI(.PEEPPTR-PBFENTSIZE)
%(***OTHERWISE MAKE THE INSTR SKIP NEVER BY MAKING THE LAST
OCTIT BE 0******)%
ELSE
PEEPPTR[-1,PBFOPCOD]_.PEEPPTR[-1,PBFOPCOD] AND #770;
RETURN TRUE
END
ELSE RETURN FALSE;
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL
THEN RETURN FALSE; !MOVEM MUST NOT HAVE A LABEL
%(***TRANSFORM THE MOVEM TO A SETZB AND DELETE THE MOVEI***)%
PEEPPTR[1,PBFOPCOD]_SETZBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !MOVEM MUST NOT HAVE A LABEL
THEN RETURN FALSE;
%(***CHANGE THE MOVEM TO A SETOB, DELETE THE MOVNI***)%
PEEPPTR[1,PBFOPCOD]_SETOBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
END;
GLOBAL ROUTINE POPT05=
%(***************************
FOR:
HRLZI R,0
MOVEM R,X
GOES TO:
SETZB R,X
CALLED WITH PEEPPTR POINTING TO THE HRLZI
*****************************)%
BEGIN
IF NOT PRVNONSKIP THEN RETURN FALSE; !INSTR BEFORE HRLZI MUST NOT SKIP
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !MOVEM MUST NOT HAVE A LABEL
THEN RETURN FALSE;
%(***MAKE THE MOVEM BE A SETZB, DELETE THE HRLZI***)%
PEEPPTR[1,PBFOPCOD]_SETZBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !ADDM MUST NOT HAVE A LABEL
THEN RETURN FALSE;
IF .PEEPPTR[1,PBFREG] EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH AN "AOS"
%(***TRANSFORM ADDM R,X TO AOS R,X AND DELETE THE MOVEI***)%
PEEPPTR[1,PBFOPCOD]_AOSOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !IF ADDB HAS A LABEL, CANNOT
THEN RETURN FALSE; ! PERFORM OPTIM
IF .PEEPPTR[1,PBFREG] EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH SOS
%(***MAKE THE ADDB BE SOS, DELETE THE MOVNI***)%
PEEPPTR[1,PBFOPCOD]_SOSOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
END;
GLOBAL ROUTINE POPT08=
%(********************************
FOR:
MOVE R,X
FSC R,1
MOVEM R,X
GOES TO:
MOVE R,X
FADRB R,X
CALLED WITH PEEPPTR POINTING TO THE FSC
************************************)%
BEGIN
%(***THE INSTR PRECEEDING THE MOVE MUST NOT SKIP***)%
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD])
THEN RETURN FALSE;
%(***THE FSC AND THE MOVEM MUST NOT HAVE LABELS***)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***MAKE THE MOVEM BE FADRB, DELETE THE FSC***)%
PEEPPTR[1,PBFOPCOD]_FADRBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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(.PEEPPTR[-2,PBFOPCOD]) THEN RETURN FALSE;
%(***IF EITHER THE ASH OR THE MOVEM HAS A LABEL CANNOT DO THE OPTIM***)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***MAKE THE MOVEM BE A ADDB, DELETE THE ASH*****)%
PEEPPTR[1,PBFOPCOD]_ADDBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[2,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***TRANSFORM THE 3RD INSTR TO "SETZB R,X"
REMOVE THE 1ST INSTR***)%
PEEPPTR[2,PBFOPCOD]_SETZBOCD;
DELPBI(.PEEPPTR);
RETURN TRUE
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 (.PEEPPTR[0,PBFINSTR] 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(.PEEPPTR[-2,PBFOPCOD]) THEN RETURN FALSE;
%(***IF THE JRST HAS A LABEL, THAT LABEL MUST BE ADDED TO THE SET OF LABELS
CORRESPONDING TO THE LOC "Y" RATHER THAN BEING ASSIGNED
TO THE INSTR FOLLOWING THE JRST AS IS USUALLY DONE***)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL
THEN
BEGIN
ADDLAB(.PEEPPTR[0,PBFLABEL],.PEEPPTR+PBFENTSIZE*2);
PEEPPTR[0,PBFLABEL]_NOLABEL;
END;
%(***REVERSE THE SENSE OF THE SKIP/CAM/CAI/AOS/SOS
DO THIS BY COMPLEMENTING THE FIRST BIT OF THE LAST OCTIT******)%
PEEPPTR[-1,PBFOPCOD]_.PEEPPTR[-1,PBFOPCOD] XOR #4;
%(***DELETE THE JRST***************)%
DELPBI(.PEEPPTR);
FRSTNEW_.PEEPPTR-PBFENTSIZE; !IN THIS PEEPHOLE, THE INSTR DELETED
! IS NOT THE FIRST ONE CHANGED
RETURN TRUE
END;
GLOBAL ROUTINE POPT12=
%(*********************************
FOR:
JUMP<GE,L> Y
JRST Z
Y: XXXX ;ANY INSTR
GOES TO:
JUMP<L,GE> Z
Y: XXXX
CALLED WITH PEEPPTR POINTING TO THE JUMPGE OR JUMPL
*********************************)%
BEGIN
%(***IF THE JUMP IS PRECEEDED BY AN INSTR THAT SKIPS, CANNOT DO OPTIM***)%
IF NOT PRVNONSKIP THEN RETURN FALSE;
%(***IF THE JRST HAS A LABEL, THEN
1. IF THE LOC CORRESPONDING TO Z HAS ALREADY
BEEN PASSED TO THE OUTPUT MODULE, CANNOT DO THE OPTIM
2. IF Z IS EITHER A FORWARD REFERENCE OR IS STILL IN THE
PEEPHOLE BUFFER, ADD THE LABEL WHICH IS ON THE JRST TO
THE SET OF LABELS CORRESPONDING TO Z
****************)%
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL
THEN
BEGIN
OWN BASE ZLABEL;
% IF THE JRST HAS A LABEL AND IS INDIRECT, CAN'T CHANGE IT%
IF .PEEPPTR[1,PBFSYMPTR] NEQ PBFLABREF THEN RETURN FALSE;
ZLABEL_.PEEPPTR[1,PBFADDR];
IF .ZLABEL[SNSTATUS] EQL OUTPBUFF THEN RETURN FALSE
ELSE
BEGIN
ADDLAB(.PEEPPTR[1,PBFLABEL],.ZLABEL);
PEEPPTR[1,PBFLABEL]_NOLABEL;
END;
END;
%(***MAKE JUMPL INTO JUMPGE, JUMPGE INTO JUMPL***)%
PEEPPTR[0,PBFOPCOD]_.PEEPPTR[0,PBFOPCOD] XOR #4;
PEEPPTR[0,PBFMEMREF]_.PEEPPTR[1,PBFMEMREF]; !SET ADDR OF JUMP TO THAT FROM JRST
PEEPPTR[0,PBFSYMPTR]_.PEEPPTR[1,PBFSYMPTR]; !AND ADDRESS TYPE
%(***DELETE THE JRST*******)%
DELPBI(.PEEPPTR+PBFENTSIZE);
FRSTNEW_.PEEPPTR; !IN THIS PEEPHOLE, THE INSTR DELETED
! IS NOT THE FIRST ONE CHANGED
RETURN TRUE
END;
GLOBAL ROUTINE POPT13=
%(***************************
FOR:
X: JRST Y
IF Y HAS NOT YET BEEN PASSED TO THE OUTPUT MODULE (IE
IS EITHER A FORWARD REFERENCE OR IS STILL IN THE PEEPHOLE BUFFER)
CHANGE THE LABEL X TO CORRESPOND TO THE SAME LOC AS THE LABEL Y
CALLED WITH PEEPPTR POINTING TO THE JRST
*************************)%
BEGIN
OWN BASE YLABEL:XLABEL;
IF .FLGREG<DBGLABL> !DO NOT DO THIS PEEPHOLE WHEN THE USER
! HAS SPECIFIED THE "DEBUG" SWITCH
! (USERS FIND THE MOTION OF LABELS CONFUSING
! WHEN DEBUGGING)
THEN RETURN FALSE;
%(***UNLESS THE INDEX AND INDIRECT BITS OF THE JRST ARE 0, CANNOT DO THE OPTIM***)%
IF (.PEEPPTR[0,PBFINSTR] AND #37000000) NEQ 0 THEN RETURN FALSE;
XLABEL_.PEEPPTR[0,PBFLABEL];
YLABEL_.PEEPPTR[0,PBFADDR];
%(***IF Y HAS ALREADY BEEN PASSED TO THE OUTPUT MODULE, CANNOT DO THIS OPTIM***)%
IF .YLABEL[SNSTATUS] EQL OUTPBUFF
THEN RETURN FALSE
%(***IF THE LABEL Y AND THE LABEL X ARE ALREADY ASSOCIATED WITH THE
SAME LOC (USER PROGRAM HAS INFINITE LOOP:
Y: JRST X
X: JRST Y
DO NOT CREATE AN INFINITE LOOP IN THE LABEL TABLE
*********)%
ELSE
IF .YLABEL[SNCADDRWD] EQL .XLABEL[SNCADDRWD] THEN RETURN FALSE
ELSE
BEGIN
ADDLAB(.PEEPPTR[0,PBFLABEL],.YLABEL);
PEEPPTR[0,PBFLABEL]_NOLABEL;
RETURN TRUE
END;
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !IF 2ND ASH(FSC) HAS A LABEL
THEN RETURN FALSE;
%(***IF THE INDEX AND INDIRECT FIELDS ARE NOT 0, CANNOT DO THE OPTIM***)%
IF ((.PEEPPTR[0,PBFINSTR] OR .PEEPPTR[1,PBFINSTR]) AND #37000000) NEQ 0
THEN RETURN FALSE;
%(***IF THE SUM OF THE 2 CONSTANTS IS GREATER THAN 18 BITS, CANNOT DO THIS OPTIM***)%
T1_ EXTSIGN(.PEEPPTR[0,PBFADDR]) + EXTSIGN(.PEEPPTR[1,PBFADDR]);
IF ABS(.T1) GTR #777777 THEN RETURN FALSE;
%(***SUBSTITUTE "K1+K2" INTO THE 2ND ASH AND DELETE THE 1ST ONE***)%
PEEPPTR[1,PBFADDR]_.T1;
DELPBI(.PEEPPTR);
RETURN TRUE
END;
GLOBAL ROUTINE POPT15=
%(***************************
FOR:
MOVEM/DMOVEM R,X
SKIP<GE,LE,G,L,N,E> R,X
JRST L
GOES TO:
MOVEM/DMOVEM R,X
JUMP<L,G,LE,GE,E,N> 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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[2,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***MAKE THE SKIP BE A JUMP ON THE OPPOSITE CONDITION***)%
T1_(.PEEPPTR[1,PBFOPCOD] AND #7) XOR #4; !SET T1 TO CODE FOR OPPOSITE CONDITION
!TO THAT ON WHICH SKIP OCCURED
PEEPPTR[1,PBFOPCOD]_JUMPOCD OR .T1; !JUMP ON CONDITION INDICATED BY T1
PEEPPTR[1,PBFMEMREF]_.PEEPPTR[2,PBFMEMREF]; !USE LABEL FROM JRST
PEEPPTR[1,PBFSYMPTR]_.PEEPPTR[2,PBFSYMPTR];
%(***DELETE THE "JRST" ***)%
DELPBI(.PEEPPTR+2*PBFENTSIZE);
%(***THE EARLIEST INSTR MODIFIED IS AT ONE INSTR AFTER PEEPPTR***)%
FRSTNEW_.PEEPPTR+PBFENTSIZE;
RETURN TRUE;
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(.PEEPPTR[-1,PBFOPCOD]) THEN RETURN FALSE;
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[0,PBFREG] EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH "MOVNS"
%(***CHANGE THE MOVN TO MOVNS AND DELETE THE MOVEM***)%
PEEPPTR[0,PBFOPCOD]_MOVNSOCD;
DELPBI(.PEEPPTR+PBFENTSIZE);
FRSTNEW_.PEEPPTR; !PTR TO EARLIEST INSTR MODIFIED
RETURN TRUE
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(.PEEPPTR[-1,PBFOPCOD]) THEN RETURN FALSE;
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***CHANGE THE SETCM TO SETCMB, DELETE THE MOVEM***)%
PEEPPTR[0,PBFOPCOD]_SETCMBOCD;
DELPBI(.PEEPPTR+PBFENTSIZE);
FRSTNEW_.PEEPPTR; !PTR TO 1ST INSTR CHANGED
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[2,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
DELPBI(.PEEPPTR+ 2*PBFENTSIZE); !DELETE THE MOVE
RETURN TRUE
END;
GLOBAL ROUTINE POPT19=
%(*******************************
FOR:
CAI<G,L,GE,LE,N,E> R,0
JRST L
GOES TO:
JUMP<LE,GE,L,G,E,N> R,L
CALLED WITH PEEPPTR POINTING TO THE JRST
*******************************)%
BEGIN
%(***IF THE INSTR PRECEEDING THE CAI CAN SKIP - DONT BOTHER ***)%
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD])
THEN RETURN FALSE;
%(***IF THE JRST HAS A LABEL DONT BOTHER (NOTE THAT WILL HAVE REMOVED THE LABEL
IF COULD DO SO) ****)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***MAKE THE COMPARE-INSTR BE A JUMP ON THE OPPOSITE CONDITION***)%
T1_(.PEEPPTR[-1,PBFOPCOD] AND #7) XOR #4; !SET T1 TO THE CODE FOR THE
! OPPOSITE CONDITION TO THAT FOR
! WHICH A SKIP OCCURRED
PEEPPTR[-1,PBFOPCOD]_JUMPOCD OR .T1; !JUMP ON CONDITION INDICATED BY T1
PEEPPTR[-1,PBFMEMREF]_.PEEPPTR[0,PBFMEMREF]; !USE LABEL FROM JRST
PEEPPTR[-1,PBFSYMPTR]_.PEEPPTR[0,PBFSYMPTR];
%(***DELETE THE JRST***)%
DELPBI(.PEEPPTR);
%(***THE EARLIEST INSTR MODIFIED IS AT ONE INSTR BEFORE PEEPPTR***)%
FRSTNEW_.PEEPPTR-PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT20=
%(*************************
FOR:
MOVE R,X
FIX/FLTR R,R
GOES TO:
FIX/FLTR R,X
CALLED WITH PEEPPTR POINTING TO THE FIX OR FLTR
***************************)%
BEGIN
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD]) THEN RETURN FALSE;
%(***THE ADDRESS FIELD OF THE FIX/FLTR SHOULD BE SET TO THAT OF THE MOVE***)%
PEEPPTR[0,PBFMEMREF]_.PEEPPTR[-1,PBFMEMREF];
PEEPPTR[0,PBFSYMPTR]_.PEEPPTR[-1,PBFSYMPTR];
%(***DELETE THE MOVE***)%
DELPBI(.PEEPPTR-PBFENTSIZE);
RETURN TRUE
END;
GLOBAL ROUTINE POPT21=
%(*************************************
FOR:
<MOVE,MOVNI,MOVEI,MOVSI> R,X
<MOVEM,ADDM,SUBM,IMULM,IDIVM,FADRM,...> R,Y
<MOVE,MOVNI,MOVEI,MOVSI> R,X
GOES TO:
<MOVE,MOVNI,MOVEI,MOVSI> R,X
<MOVEM,ADDM,SUBM,IMULM,IDIVM,FADRM,...> R,Y
CALLED WITH PEEPPTR POINTING TO THE FIRST <MOVE,MOVEI,MOVSI,MOVNI>
*************************************)%
BEGIN
%(***IF THE 2ND OR 3RD INSTR OF THE PEEPHOLE HAS A LABEL ON IT
CANNOT DO THIS OPTIM***)%
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[2,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***IF THE INSTR PRECEEDING THE 1ST INSTR OF THE PEEPHOLE CAN SKIP, THEN
CANNOT DO THIS OPTIM***)%
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) THEN RETURN FALSE;
%(***DELETE THE 2ND MOVE***)%
DELPBI(.PEEPPTR+2*PBFENTSIZE);
RETURN TRUE
END;
GLOBAL ROUTINE POPT22=
%(***************************
FOR:
MOVE R,X
SKIP<G,GE,L,LE,E,NE> 0,X
GOES TO:
SKIP<G,GE,L,LE,E,NE> R,X
AND:
MOVE R,X
SKIP<G,GE,L,LE,E,NE> 0,R
GOES TO:
SKIP<G,GE,L,LE,E,NE> R,X
CALLED WITH PEEPPTR POINTING TO THE MOVE
*****************************)%
BEGIN
%(***IF THE SKIP HAS A LABEL, CANT DO THIS OPTIM***)%
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***IF THE INSTR BEFORE THE MOVE CAN SKIP, CANT DO THE OPTIM***)%
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) 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 .PEEPPTR[0,PBFREG] EQL REG0 THEN RETURN FALSE;
%(***SET THE REG FIELD OF THE SKIPGE TO THAT OF THE MOVE***)%
PEEPPTR[1,PBFREG]_.PEEPPTR[0,PBFREG];
%(***SET THE MEMREF FIELD OF THE SKIPGE TO THAT OF THE MOVE***)%
PEEPPTR[1,PBFMEMREF]_.PEEPPTR[0,PBFMEMREF];
PEEPPTR[1,PBFSYMPTR]_.PEEPPTR[0,PBFSYMPTR];
%(***DELETE THE MOVE***)%
DELPBI(.PEEPPTR);
RETURN TRUE;
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***IF THE INSTR BEFORE THE AOS CAN SKIP, CANNOT DO THE OPTIM***)%
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) THEN RETURN FALSE;
IF .PEEPPTR[1,PBFREG] EQL REG0 THEN RETURN FALSE; !CANNOT LOAD REG 0 WITH AOS/SOS
%(***DELETE THE MOVE***)%
DELPBI(.PEEPPTR+PBFENTSIZE);
RETURN TRUE
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 .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***IF THE INSTR PRECEEDING THE ADDI MAY SOMETIMES SKIP, CANNOT DO THIS OPTIM***)%
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD]) THEN RETURN FALSE;
%(***MAKE THE JRST BE AN "AOJA" OR "SOJA"***)%
PEEPPTR[0,PBFOPCOD]_(IF .PEEPPTR[-1,PBFOPCOD] EQL ADDIOCD THEN AOJAOCD ELSE SOJAOCD);
%(***PUT THE REGISTER FIELD FROM THE ADDI INTO THE AOJA***)%
PEEPPTR[0,PBFREG]_.PEEPPTR[-1,PBFREG];
%(***DELETE THE ADDI***)%
DELPBI(.PEEPPTR-PBFENTSIZE);
RETURN TRUE
END;
GLOBAL ROUTINE POPT25=
%(*********************
FOR:
MOVE R,[0]
GOES TO:
MOVEI R,0
THIS CAN ONLY HAPPEN WHEN DEALING WITH DOUBLE-PREC AND COMPLEX CONSTANTS
ON THE KA10
***********************)%
BEGIN
PEEPPTR[0,PBFOPCOD]_MOVEIOCD;
PEEPPTR[0,PBFMEMREF]_0;
PEEPPTR[0,PBFSYMPTR]_PBFNOSYM;
FRSTNEW_.PEEPPTR; !PTR TO EARLIEST INSTR MODIFIED BY THIS PEEPHOLE
RETURN TRUE
END;
GLOBAL ROUTINE POPT26=
%(***********************
FOR:
DMOVE R,[0
0]
GOES TO:
SETZB R,R+1
**************************)%
BEGIN
%(***CHANGE THE DMOVE TO A SETZB***)%
PEEPPTR[0,PBFOPCOD]_SETZBOCD;
PEEPPTR[0,PBFMEMREF]_.PEEPPTR[0,PBFREG]+1;
PEEPPTR[0,PBFSYMPTR]_PBFNOSYM;
FRSTNEW_.PEEPPTR; !PTR TO EARLIEST INSTR MODIFIED
RETURN TRUE
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 .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !IF THE 2ND MOVEI HAS A LABEL
THEN RETURN FALSE;
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) !IF THE INSTR BEFORE THE 1ST MOVEI CAN SKIP
THEN RETURN FALSE;
%(***CHANGE THE OPCODE ON THE SECOND MOVEI TO SETZB***)%
PEEPPTR[1,PBFOPCOD]_SETZBOCD;
%(***CHANGE THE MEMORY FIELD OF THE 2ND MOVEI TO BE TH REG IN THE 1ST MOVEI***)%
PEEPPTR[1,PBFMEMREF]_.PEEPPTR[0,PBFREG];
%(***DELETE THE 1ST MOVEI***)%
DELPBI(.PEEPPTR);
RETURN TRUE
END;
GLOBAL ROUTINE POPT28=
%(**************************
FOR:
DMOVE R,[0-0]
DMOVEM R,X
GOES TO:
SETZB R,X
SETZB R+1,X+1
CALLED WITH PEEPPTR POINTING TO THE DMOVE
******************************)%
BEGIN
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !IF THE DMOVEM HAS A LABEL
THEN RETURN FALSE;
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) !IF INSTR BEFORE DMOVE CAN SKIP
THEN RETURN FALSE;
%(***SET THE 2 INSTRS TO SETZB***)%
PEEPPTR[0,PBFOPCOD]_SETZBOCD;
PEEPPTR[1,PBFOPCOD]_SETZBOCD;
%(***SET MEMREF OF THE FIRST SETZB TO X***)%
PEEPPTR[0,PBFSYMPTR]_.PEEPPTR[1,PBFSYMPTR];
PEEPPTR[0,PBFMEMREF]_.PEEPPTR[1,PBFMEMREF];
%(***SET MEMREF OF 2ND SETZB TO X+1, AN REG TO R+1***)%
PEEPPTR[1,PBFADDR]_.PEEPPTR[1,PBFADDR]+1;
PEEPPTR[1,PBFREG]_.PEEPPTR[1,PBFREG]+1;
FRSTNEW_.PEEPPTR; !PTR TO 1ST INSTR CHANGED
RETURN TRUE
END;
GLOBAL ROUTINE POPT29=
%(*********************
FOR:
<ADDM,SUBM,IMULM,FADRM...> R,X
MOVE R,X
GOES TO:
<ADDB,SUBB,IMULB,FADRB...> R,X
CALLED WITH PEEPPTR POINTING TO THE MOVE
**********************)%
BEGIN
%(***IF THE MOVE HAS A LABEL, CANNOT DO THIS OPTIM**)%
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
%(***IF THE INSTR BEFORE THE OPERATION TO MEMORY CAN SKIP, CANNOT DO THSI
OPTIM***)%
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD])
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 .PEEPPTR[-1,PBFOPCOD] EQL IDIVMOCD THEN RETURN FALSE;
%(***MAKE THE OPERATION TO MEMORY BE TO BOTH***)%
PEEPPTR[-1,PBFOPCOD]_.PEEPPTR[-1,PBFOPCOD] OR #1; !TURN ON LOW ORDER BIT
! OF OPCODE
%(***DELETE THE MOVE***)%
DELPBI(.PEEPPTR);
%(***THE 1ST INSTR CHANGED IS THE OP TO MEMORY***)%
FRSTNEW_.PEEPPTR-PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT30=
%(***********************
FOR:
MOVE R,X
JUMP<E,N,GT,LT,LE,GE> R,L
GOES TO:
SKIP<N,E,LE,GE,GT,LT> R,X
JRST L
CALLED WITH PEEPPTR POINTING TO THE MOVE
**************************)%
BEGIN
IF .PEEPPTR[1,PBFLABEL] NEQ NOLABEL !IF THE JUMP HAS A LABEL
THEN RETURN FALSE;
IF NOT NONSKIP(.PEEPPTR[-1,PBFOPCOD]) !IF THE INSTR BEFORE THE MOVE CAN SKIP
THEN RETURN FALSE;
IF .PEEPPTR[0,PBFREG] EQL REG0 THEN RETURN FALSE; !IF THE MOVE IS TO REG 0
! CANNOT LOAD REG 0 WITH A SKIP
T1_(.PEEPPTR[1,PBFOPCOD] AND #7) XOR #4; !SET T1 TO THE CODE FOR
! THE CONDITION OPPOSITE TO THAT
! FOR WHICH JUMP OCCURRED
PEEPPTR[0,PBFOPCOD]_SKIPOCD OR .T1; !CHANGE THE MOVE TO A SKIP ON
! THE CONDITION INDICATED BY T1
PEEPPTR[1,PBFOPCOD]_JRSTOCD; !CHANGE THE JUMP TO A JRST
PEEPPTR[1,PBFREG]_0; !TURN OFF THE REG FIELD IN THE JRST
FRSTNEW_.PEEPPTR; !PTR TO FIRST INSTR CHANGED
RETURN TRUE
END;
GLOBAL ROUTINE POPT31=
%(********************************************************************************
FOR:
MOVEI R,0 OR SETZ R,0
JRST .+2 JRST .+2
GOES TO:
TDZA R,R
CALLED WITH PEEPPTR POINTING TO THE JRST
********************************************************************************)%
BEGIN
BIND TDZAOCD=#634;
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF .PEEPPTR[-1,PBFMEMREF] NEQ 0 OR .PEEPPTR[-1,PBFSYMPTR] NEQ PBFNOSYM
THEN RETURN FALSE;
IF NOT PRV2NONSKIP THEN RETURN FALSE;
PEEPPTR[-1,PBFOPCOD]_TDZAOCD;
PEEPPTR[-1,PBFMEMREF]_.PEEPPTR[-1,PBFREG];
DELPBI(.PEEPPTR);
FRSTNEW_ .PEEPPTR-PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT32=
%(********************************************************************************
FOR:
MOVE R,X
JRST .+2
GOES TO:
SKIPA R,X (R # 0)
CALLED WITH PEEPPTR POINTING TO JRST
********************************************************************************)%
BEGIN
BIND SKIPAOCD=#334;
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL OR (NOT PRV2NONSKIP)
THEN RETURN FALSE;
IF .PEEPPTR[-1,PBFREG] EQL 0 THEN RETURN FALSE;
PEEPPTR[-1,PBFOPCOD]_ SKIPAOCD;
DELPBI(.PEEPPTR);
FRSTNEW_ .PEEPPTR - PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT33=
%(********************************************************************************
FOR:
CAI/CAM AC,K
JRST X
CAI/CAM AC2,L
JRST X
GOES TO:
CAI/CAM AC,K WITH SKIP SENSE REVERSED
CAI/CAM AC2,L
JRST X
CALLED WITH PEEPPTR POINTING TO THE FIRST JRST
********************************************************************************)%
BEGIN
IF NOT NONSKIP(.PEEPPTR[-2,PBFOPCOD]) THEN RETURN FALSE;
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
PEEPPTR[-1,PBFOPCOD]_ .PEEPPTR[-1,PBFOPCOD] XOR 4;
DELPBI(.PEEPPTR);
FRSTNEW_ .PEEPPTR - PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT34=
%(********************************************************************************
FOR:
SKIPGE R,X
DFN R,R+1
DFN R,R+1
GOES TO:
SKIPL R,X
DFN R,R+1
CALLED WITH PEEPPTR POINTING TO THE FIRST DFN
********************************************************************************)%
BEGIN
BIND SKIPGEOCD=#335, SKIPLOCD=#331;
IF .PEEPPTR[-1,PBFOPCOD] NEQ SKIPGEOCD
OR .PEEPPTR[0,PBFREG] NEQ .PEEPPTR[-1,PBFREG]
THEN RETURN FALSE;
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
PEEPPTR[-1,PBFOPCOD]_ SKIPLOCD;
DELPBI(.PEEPPTR);
FRSTNEW_ .PEEPPTR - PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT35=
%(********************************************************************************
FOR:
JUMP??/AOJ??/SOJ?? R,X
JRST X
GOES TO:
JUMPA/AOJA/SOJA R,X
CALLED WITH PEEPPTR POINTING TO THE JRST
********************************************************************************)%
BEGIN
LOCAL POP;
BIND AOJOCD=#340, SOJOCD=#360;
IF .PEEPPTR[0,PBFLABEL] NEQ NOLABEL THEN RETURN FALSE;
IF (POP_.PEEPPTR[-1,PBFOPCOD] AND #770) NEQ JUMPOCD
AND (.POP NEQ AOJOCD)
AND (.POP NEQ SOJOCD)
THEN RETURN FALSE;
IF (.PEEPPTR[-1,PBFOPCOD] AND 7) EQL 0 THEN RETURN FALSE;
DELPBI(.PEEPPTR);
PEEPPTR[-1,PBFOPCOD]_.POP + 4;
FRSTNEW_ .PEEPPTR - PBFENTSIZE;
RETURN TRUE
END;
GLOBAL ROUTINE POPT36=
%(**********************************
FOR:
NONSKIP
ADDI R,N
SUBI R,N
GOES TO:
NONSKIP
AND:
NONSKIP
SUBI R,N
ADDI R,N
GOES TO:
NONSKIP
CALLED WITH PEEPPTR POINTING TO THE SUBI
***********************************)%
BEGIN
REGISTER T1;
IF .PEEPPTR[-1,PBFOPCOD] EQL ADDIOCD
THEN T1_-1
ELSE
IF .PEEPPTR[0,PBFOPCOD] EQL ADDIOCD
THEN T1_0
ELSE
RETURN FALSE;
%(***IF WE HAVE AN ADDI SUBI PAIR, MAKE SURE THE PRECEEDING
INSTRUCTION IS NON-SKIP AND THAT THERE IS NO LABEL ON THE
SECOND OF THE PAIR***)%
IF NOT NONSKIP(.PEEPPTR[.T1-1,PBFOPCOD])
THEN RETURN FALSE;
IF .PEEPPTR[.T1+1,PBFLABEL] NEQ NOLABEL
THEN RETURN FALSE;
%(***THEN IF BOTH INSTRUCTIONS REFERENCE THE SAME AC AND USE
THE SAME IMMEDIATE VALUE, GET RID OF BOTH***)%
IF .PEEPPTR[.T1,PBFMEMREF] EQL .PEEPPTR[.T1+1,PBFMEMREF]
AND
.PEEPPTR[.T1,PBFSYMPTR] EQL .PEEPPTR[.T1+1,PBFSYMPTR]
AND
.PEEPPTR[.T1,PBFREG] EQL .PEEPPTR[.T1+1,PBFREG]
THEN
BEGIN
DELPBI(.PEEPPTR+(.T1+1)*PBFENTSIZE);
DELPBI(.PEEPPTR+.T1*PBFENTSIZE);
RETURN TRUE
END
ELSE
RETURN FALSE;
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
%(***IF LAST 3 BITS ARE 0, 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 MOVEMOCD) AND (.OPCODE LEQ IDIVMOCD)
THEN RETURN TRUE
%(***CHECK FOR ADDM***)%
ELSE
IF .OPCODE EQL ADDMOCD
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 FADRMOCD) AND (.OPCODE LEQ FDVRMOCD)
THEN RETURN TRUE
%(***CHECK FOR SUBM***)%
ELSE
IF .OPCODE EQL SUBMOCD
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 IMULMOCD OR .OPCODE EQL IDIVMOCD OR .OPCODE EQL ADDMOCD
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 FADRMOCD) AND (.OPCODE LEQ FDVRMOCD)
THEN RETURN TRUE
%(***CHECK FOR SUBM***)%
ELSE
IF (.OPCODE EQL SUBMOCD) THEN RETURN TRUE
END;
RETURN FALSE
END;
GLOBAL ROUTINE EQVPOSSIBLE(SYMPT1,SYMPT2)=
%(***************************************************************************
FOR SYMPT1,SYMPT2 THE VALUES OF 2 PSYMPTR FIELDS, RETURN
TRUE IFF IT IS POSSIBLE THAT THESE TWO SYMBOLS ARE EQUIVALENCED
TO EACHOTHER
***************************************************************************)%
BEGIN
MAP PEXPRNODE SYMPT1:SYMPT2;
IF .SYMPT1 LEQ PBFCODMAX !IF EITHER OF THESE PSYMPTR FIELDS
OR .SYMPT2 LEQ PBFCODMAX !IS A SPECIAL CODE RATHER THAN A SYMBOL
THEN RETURN FALSE ! TABLE ENTRY- THEN THEY ARENT EQV
ELSE
IF .SYMPT1[OPRCLS] NEQ DATAOPR !IF EITHER DOES NOT PT TO
OR .SYMPT2[OPRCLS] NEQ DATAOPR ! A SYMBOL TABLE ENTRY
THEN RETURN FALSE
ELSE
IF NOT .SYMPT1[IDATTRIBUT(INEQV)] !IF THEY DO NOT BOTH OCCUR
OR NOT .SYMPT2[IDATTRIBUT(INEQV)] ! IN EQV STMNTS
THEN RETURN FALSE
ELSE !IF BOTH OCCUR IN EQV STMNTS, DONT BOTHER ANALYZING FURTHER
RETURN TRUE ! (ASSUME POSSIBILTY THAT THEY ARE EQV TO EACHOTHER)
END;
GLOBAL ROUTINE AEQLC0=
%(***************************************************************************
ROUTINE TO TEST WHETHER THE INSTR IN THE BUFFER POINTED TO
BY PEEPPTR HAS AS ITS ADDRESS THE CONSTANT 0
THIS SHOULD ONLY FOR CONSTANTS THAT ARE MULTI-WORD (IE DOUBLE-PRECISION,
COMPLEX,DOUBLE-OCTAL)
***************************************************************************)%
BEGIN
MAP BASE T1; !TEMPORARY USED THRUOUT THIS MODULE
IF (T1_.PEEPPTR[0,PBFSYMPTR]) GTR PBFCODMAX !IF THE "SYMBOL ATBLE PTR" IS
! NOT REALLY SOME SPECIAL CODE
THEN
BEGIN
IF .T1[OPR1] EQL CONSTFL AND .T1[DBLFLG] !IF ADDRESS IS A DOUBLPREC
! OR COMPLEX CONSTANT
THEN
BEGIN
IF .PEEPPTR[0,PBFMEMREF] EQL .T1[IDADDR]
THEN
%(***IF ARE LOOKING AT THE 1ST WD OF THE CONSTANT***)%
RETURN (.T1[CONST1] EQL 0)
ELSE
IF .PEEPPTR[0,PBFMEMREF] EQL (.T1[IDADDR]+1)
THEN
%(***IF ARE LOOKING AT THE 2ND WORD OF THE CONSTANT***)%
RETURN (.T1[CONST2] EQL 0)
END;
END;
RETURN FALSE
END;
GLOBAL ROUTINE DELPBI(IPTR)=
%(***************************************************************************
TO DELETE AN INSTR FROM THE PEEPHOLE BUFFER.
DELETES THE INSTR POINTED TO BY "IPTR" AND MOVES UP ALL THE INSTRS
FOLLOWING IT.
IF THIS INSTR HAD A LABEL ASSOCIATED WITH IT, MUST NOW
ASSOCIATE THAT LABEL WITH THE NEXT INSTR.
LEAVES THE GLOBAL "FRSTNEW" POINTING TO THE LOC FROM WHICH AN INSTR
WAS DELETED (AND INTO WHICH SOME NEW INSTR WAS MOVED)
***************************************************************************)%
BEGIN
MAP PEEPHOLE IPTR;
OWN BASE ILABEL; !LABEL ON THE INSTR BEING REMOVED
ILABEL_.IPTR[0,PBFLABEL];
%(***IF THERE WAS AN ISN ON THE INSTR DELETED AND THERE IS NOT AN ISN ON THE
INSTR AFTER IT, SET THE ISN OF THE FOLLOWING INSTR
TO THAT OF THE DELETED INSTR****)%
IF .IPTR[0,PBFISN] NEQ NOISN AND .IPTR[1,PBFISN] EQL NOISN
THEN IPTR[1,PBFISN]_.IPTR[0,PBFISN];
%(***MOVE INSTRS FOLLOWING THE INSTR REMOVED UP BY ONE ENTRY***)%
BLOCKTR( (.IPTR+PBFENTSIZE), .IPTR, (PBUFF+PBFSIZE)-(.IPTR+PBFENTSIZE) );
%(***IF THERE WAS A LABEL ON THE INSTR REMOVED, ASSOCIATE THAT LABEL WITH
THE INSTR FOLLOWING IT (WHICH HAS NOW BEEN MOVED UP INTO THE SLOT
FORMERLY OCCUPIED BY THE DELETED INSTR) ***)%
IF .ILABEL NEQ NOLABEL
THEN
BEGIN
IF .IPTR[0,PBFLABEL] EQL NOLABEL
THEN IPTR[0,PBFLABEL]_.ILABEL
%(***IF THE NEXT INSTR ALREADY HAS A LABEL, MUST LINK THIS ADDITIONAL
LABEL TO THE LINKED LIST OF LABEL CORRESPONDING TO THIS INSTR***)%
ELSE ADDLAB(.ILABEL,.IPTR[0,PBFLABEL]);
END;
%(***MOVE UP THE GLOBAL PTR TO THE FIRST FREE WD IN THE BUFFER***)%
PBFPTR_.PBFPTR-PBFENTSIZE;
%(***LEAVE THE GLOBAL "FRSTNEW" POINTING TO THE LOC FROM WHICH
AN INSTR WAS DELETED (SINCE THIS LOC NOW CONTAINS SOM NEW VAL) ***)%
FRSTNEW_.IPTR;
END;
GLOBAL ROUTINE ADDLAB(ILABEL,PREVLAB)=
%(***************************************************************************
WHEN SOME INSTR ALREADY HAS ASSOCITED WITH THE LABEL "PREVLAB",
ADD THE LABEL "ILABEL" TO THE SET OF LABELS ASSOCIATED WITH
THAT SAME INSTR.
THE LABEL-TABLE (STMNT NUMBER TABLE) ENTRIES FOR ALL LABELS THAT
ARE ASSOCIATED WITH THE SAME INSTR ARE CHAINED TOGETHER IN THE
"SNNXTLAB" FIELD. ALSO, THE ENTRIES FOR ALL LABELS THAT ARE
ASSOCITED WITH THE SAME INSTR HAVE IDENTICAL VALUES IN THE
"SNCADDRWD" FIELD
***************************************************************************)%
BEGIN
MAP BASE PREVLAB:ILABEL;
%(***SET THE "COMPARISON WD" (WHICH INCLUDES PTR TO 1ST LABEL
WITH SAME ADDR) OF ILABEL EQUAL TO THAT FOR THE
LABEL ALREADY ON THIS INSTR***)%
ILABEL[SNCADDRWD]_.PREVLAB[SNCADDRWD];
%(***FIND THE LAST LABEL ON THE CHAIN OF LABELS CORRESP
TO THIS ADDR AND ADD ILABEL TO THE CHAIN***)%
UNTIL .PREVLAB[SNNXTLAB] EQL LBTBENDMK
DO
PREVLAB_.PREVLAB[SNNXTLAB];
PREVLAB[SNNXTLAB]_.ILABEL;
%(***IF ILABEL HAS ANY FURTHER LABELS CHAINED OFF OF IT,
SET "SNCADDRWD" OF ALL OF THESE TO THE NEW VAL***)%
PREVLAB_.ILABEL[SNNXTLAB];
UNTIL .PREVLAB EQL 0
DO
BEGIN
PREVLAB[SNCADDRWD]_.ILABEL[SNCADDRWD];
PREVLAB_.PREVLAB[SNNXTLAB];
END;
END;
ROUTINE CLOBNEXT=
%(***** CHECK TO SEE IF THE INSTRUCTION AT .PEEPPTR + 1 MIGHT CLOBBER
THE REGISTER USED BY .PEEPPTR BECAUSE IT IS A DIVIDE INSTRUCTION OR IT IS
A FIX/FLOAT SUBROUTINE CALL ON THE KA-10. CALLED BY PEEP02. *****)%
BEGIN
! SEE IF IT IS A FORDDT XCT INSTRUCTION
IF .PEEPPTR[1,PBFOPCOD] EQL XCTOCD
THEN RETURN TRUE
! SEE IF IT IS A DIVIDE OF THE REGISTER IN FRONT OF THE
! ONE USED BY .PEEPPTR
ELSE
IF (.PEEPPTR[1,PBFOPCOD] AND #770) EQL DIVOCD
THEN
IF .PEEPPTR[1,PBFREG] EQL .PEEPPTR[0,PBFREG]-1
THEN RETURN TRUE;
RETURN FALSE;
END;
END
ELUDOM