Google
 

Trailing-Edge - PDP-10 Archives - FORTRAN-10_V7wLink_Feb83 - 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) DIGITAL EQUIPMENT CORPORATION 1972, 1983
!AUTHOR: S. MURPHY/G.J. BUNZA/MD/AHM/CDM

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 = 7^24 + 0^18 + 1635;	! Version Date:	24-Sep-82

%(

***** 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)

***** Begin Version 7 *****

1541	DCE	25-May-82	-----
	Add several new cases:
		MOVEI R,X	goes to MOVEI R,X
		MOVEI R,X

		MOVSI R,X	goes to MOVSI R,X
		MOVSI R,X

		MOVNI R,X	goes to MOVNI R,X
		MOVNI R,X

	and	MOVEM R,X	goes to MOVEM R,X
		MOVEM R,X

	with appropriate conditions satisfied.

1635	CDM	24-Sept-82
	Fix call to ADDLAB in POPT11.  Argument was pointing to the triplet
	rather than to to label table entry to add to.  Day one bug.

***** 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;

!**;[1541], PEEP01 @3935, DCE, 25-May-82
%1541%		%(***CHECK FOR THE PEEPHOLE:
			MOVEI		R,X
			MOVEI		R,X
		*******)%
%1541%		IF .PEEPPTR[1,PBFOPCOD] EQL MOVEIOCD
%1541%		THEN IF NONOPEQNXT
%1541%		THEN IF PRVNONSKIP
%1541%		THEN
%1541%		BEGIN
%1541%			DELPBI(.PEEPPTR); ! Remove extra instruction
%1541%			RETURN TRUE
%1541%		END;

		%(***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
!**;[1541], PEEP02 @3986, DCE, 25-May-82
%1541%			ELSE
%1541%			%(*****CHECK FOR:
				MOVEM	R,X
				MOVEM	R,X
			*******)%

%1541%			! There is an assumption here that the effective address
%1541%			! will not resolve to a register!  Currently, this is a
%1541%			! very valid assumption.

%1541%			IF .PEEPPTR[1,PBFOPCOD] EQL MOVEMOCD
%1541%			THEN IF PRVNONSKIP
%1541%			THEN
%1541%			BEGIN
%1541%				DELPBI(.PEEPPTR); ! Remove extra instruction
%1541%				RETURN TRUE
%1541%			END;
%1541%			RETURN FALSE;
		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
	This routine (PEEP11) has been rewritten by edit [1541].
***************************************************************************)%
BEGIN
	IF .PEEPPTR[0,PBFOPCOD] NEQ MOVNIOCD THEN RETURN FALSE;

	%(***CHECK FOR PEEPHOLES FOR WHICH KEY INSTR IS:
		MOVNI	R,1
	*********)%

	IF AEQ1
	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;

	%(***CHECK FOR:
		MOVNI	R,X
		MOVNI	R,X
	*****)%
	IF .PEEPPTR[1,PBFOPCOD] EQL MOVNIOCD
	THEN IF NONOPEQNXT
	THEN IF PRVNONSKIP
	THEN
	BEGIN
		DELPBI(.PEEPPTR);
		RETURN TRUE
	END;

	%(***CHECK FOR:
		MOVNI	R,X
		MOVEM(ADDM,...)	R,Y
		MOVNI	R,X
	*****)%
	RETURN PEEPA0()
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
	This routine (PEEP05) was rewritten by edit [1541].
***************************************************************************)%
BEGIN
	IF .PEEPPTR[0,PBFOPCOD] NEQ MOVSIOCD THEN RETURN FALSE;

	IF .PEEPPTR[1,PBFOPCOD] EQL MOVSIOCD
	THEN	! Two MOVSI instructions in a row - might be the same.
	IF NONOPEQNXT THEN ! They ARE the same!
	BEGIN
		DELPBI(.PEEPPTR); ! Remove the first of the pair (keep labels).
		RETURN TRUE
	END;

	%(***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***)%
		PEEPPTR[0,PBFOPCOD]_MOVEIOCD;
		FRSTNEW_.PEEPPTR;
		RETURN TRUE
	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:
		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
%1635%		ADDLAB(.PEEPPTR[0,PBFLABEL],.PEEPPTR[2,PBFLABEL]);
		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