.TOC	"INTLOGADR.MIC -- Integer and Logical Class, and Address Class, Instructions"
.TOC	"Revision 7.0"

;	Bob Supnik

.nobin
;****************************************************************************
;*									    *
;*  COPYRIGHT (c) 1982, 1983, 1984 BY					    *
;*  DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS.		    *
;*  ALL RIGHTS RESERVED.						    *
;* 									    *
;*  THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED   *
;*  ONLY IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE   *
;*  INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER   *
;*  COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY   *
;*  OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE IS  HEREBY   *
;*  TRANSFERRED.							    *
;* 									    *
;*  THE INFORMATION IN THIS SOFTWARE IS  SUBJECT TO CHANGE WITHOUT NOTICE   *
;*  AND  SHOULD  NOT  BE  CONSTRUED AS  A COMMITMENT BY DIGITAL EQUIPMENT   *
;*  CORPORATION.							    *
;* 									    *
;*  DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE  OR  RELIABILITY OF ITS   *
;*  SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.		    *
;*									    *
;****************************************************************************

.TOC	"	Revision History"

; 07	14-Feb-84	[RMS]	Editorial changes for pass 2
;	3-Jan-84	[RMS]	Editorial changes
; 06	15-Nov-83	[RMS]	Optimized ASHL, editorial changes
;	22-Sep-83	[RMS]	Editorial changes
;	15-Sep-83	[RMS]	Removed optimization in ROTL
;	6-Jun-83	[RMS]	Added global labels
; 05	31-May-83	[RMS]	Removed third at/dl field
;	18-May-83	[RMS]	Revised to disable prefetch during bus lock
;	17-May-83	[RMS]	Editorial changes
; 04	13-Mar-83	[RMS]	Major code compression
;	27-Dec-82	[RMS]	Rewrote ASHQ
;				Fixed G[SP].RLOG problem
;	9-Dec-82	[RMS]	Removed extraneous ..e linkages
;	6-Dec-82	[RMS]	Editorial changes
;	28-Nov-82	[RMS]	Editorial changes
; 03	24-Nov-82	[RMS]	Revised allocation limits
;	14-Oct-82	[RMS]	Editorial changes
;	12-Oct-82	[RMS]	Revised allocation limits
;	20-Sep-82	[RMS]	Revised definition of PR[E]
; 02	14-Sep-82	[RMS]	Revised allocation limits
;	6-Sep-82	[RMS]	Editorial changes
;	5-Sep-82	[RMS]	Removed multiply, divide to separate module
;	31-Aug-82	[RMS]	Revised for G(RN+1) restriction
;				Editorial changes on case statements
;	25-Aug-82	[RMS]	Revised for today's spec changes
;	23-Aug-82	[RMS]	Revised ASHL dispatch for allocation conflict
;	20-Aug-82	[RMS]	Revised ASHx for further size reduction
;	17-Aug-82	[RMS]	Revised CVTs not to rely on W0 = SC after FSD
;				Revised for new pass, zext operations
;	15-Aug-82	[RMS]	Revised for new nomenclature
;	13-Aug-82	[RMS]	Removed indirect jump from ADAWI
;				Revised dispatch address for PUSHX
;	10-Aug-82	[RMS]	Continued initial edit, added converts, shifts
; 01	6-Aug-82	[RMS]	First edit for MicroVAX

.bin
;= REGION 2 63F
;= BEGIN INTLOG
.nobin

;	This module implements the integer and logical class, and address class, instructions,
;	except for multiply and divide.  The instructions in these classes are:
;
;
;	Integer and Logical Instructions
;
;	Opcode	 Instruction							N Z V C		Exceptions
;	------	 -----------							-------		----------
;
;	58	 ADAWI add.rw, sum.mw						* * * *		iov
;
;	80	 ADDB2 add.rb, sum.mb						* * * *		iov
;	C0	 ADDL2 add.rl, sum.ml						* * * *		iov
;	A0	 ADDW2 add.rw, sum.mw						* * * *		iov
;
;	81	 ADDB3 add1.rb, add2.rb, sum.wb					* * * *		iov
;	C1	 ADDL3 add1.rl, add2.rl, sum.wl					* * * *		iov
;	A1	 ADDW3 add1.rw, add2.rw, sum.ww					* * * *		iov
;
;	D8	 ADWC add.rl, sum.ml						* * * *		iov
;
;	78	 ASHL cnt.rb, src.rl, dst.wl					* * * 0		iov
;	79	 ASHQ cnt.rb, src.rq, dst.wq					* * * 0		iov
;
;	8A	 BICB2 mask.rb, dst.mb						* * 0 -
;	CA	 BICL2 mask.rl, dst.ml						* * 0 -
;	AA	 BICW2 mask.rw, dst.mw						* * 0 -
;
;	8B	 BICB3 mask.rb, src.rb, dst.wb					* * 0 -
;	CB	 BICL3 mask.rl, src.rl, dst.wl					* * 0 -
;	AB	 BICW3 mask.rw, src.rw, dst.ww					* * 0 -
;
;	88	 BISB2 mask.rb, dst.mb						* * 0 -
;	C8	 BISL2 mask.rl, dst.ml						* * 0 -
;	A8	 BISW2 mask.rw, dst.mw						* * 0 -
;
;	89	 BISB3 mask.rb, src.rb, dst.wb					* * 0 -
;	C9	 BISL3 mask.rl, src.rl, dst.wl					* * 0 -
;	A9	 BISW3 mask.rw, src.rw, dst.ww					* * 0 -
;
;	93	 BITB mask.rb, src.rb						* * 0 -
;	D3	 BITL mask.rl, src.rl						* * 0 -
;	B3	 BITW mask.rw, src.rw						* * 0 -
;
;	94	 CLRB dst.wb							0 1 0 -
;	D4	 CLRL{=F} dst.wl						0 1 0 -
;	7C	 CLRQ{=D=G} dst.wq						0 1 0 -
;	B4	 CLRW dst.ww							0 1 0 -
;
;	91	 CMPB src1.rb, src2.rb						* * 0 *
;	D1	 CMPL src1.rl, src2.rl						* * 0 *
;	B1	 CMPW src1.rw, src2.rw						* * 0 *
;
;	98	 CVTBL src.rb, dst.wl						* * 0 0
;	99	 CVTBW src.rb, dst.wl						* * 0 0
;	F6	 CVTLB src.rl, dst.wb						* * * 0		iov
;	F7	 CVTLW src.rl, dst.ww						* * * 0		iov
;	33	 CVTWB src.rw, dst.wb						* * * 0		iov
;	32	 CVTWL src.rw, dst.wl						* * 0 0
;
;	97	 DECB dif.mb							* * * *		iov
;	D7	 DECL dif.ml							* * * *		iov
;	B7	 DECW dif.mw							* * * *		iov
;
;	96	 INCB sum.mb							* * * *		iov
;	D6	 INCL sum.ml							* * * *		iov
;	B6	 INCW sum.mw							* * * *		iov
;
;	92	 MCOMB src.rb, dst.wb						* * 0 -
;	D2	 MCOML src.rl, dst.wl						* * 0 -
;	B2	 MCOMW src.rw, dst.ww						* * 0 -
;
;	8E	 MNEGB src.rb, dst.wb						* * * *		iov
;	CE	 MNEGL src.rl, dst.wl						* * * *		iov
;	AE	 MNEGW src.rw, dst.ww						* * * *		iov
;
;	90	 MOVB src.rb, dst.wb						* * 0 -
;	D0	 MOVL src.rl, dst.wl						* * 0 -
;	7D	 MOVQ src.rq, dst.wq						* * 0 -
;	B0	 MOVW src.rw, dst.ww						* * 0 -
;
;	9A	 MOVZBW src.rb, dst.wb						0 * 0 -
;	9B	 MOVZBL src.rb, dst.wl						0 * 0 -
;	3C	 MOVZWL src.rw, dst.ww						0 * 0 -
;
;	DD	 PUSHL src.rl, {-(SP).wl}					* * 0 -
;
;	9C	 ROTL cnt.rb, src.rl, dst.wl					* * 0 -
;
;	D9	 SBWC sub.rl, dif.ml						* * * *		iov
;
;	82	 SUBB2 sub.rb, dif.mb						* * * *		iov
;	C2	 SUBL2 sub.rl, dif.ml						* * * *		iov
;	A2	 SUBW2 sub.rw, dif.mw						* * * *		iov
;
;	83	 SUBB3 sub.rb, min.rb, dif.wb					* * * *		iov
;	C3	 SUBL3 sub.rl, min.rl, dif.wl					* * * *		iov
;	A3	 SUBW3 sub.rw, min.rw, dif.ww					* * * *		iov
;
;	95	 TSTB src.rb							* * 0 0
;	D5	 TSTL src.rl							* * 0 0
;	B5	 TSTW src.rw							* * 0 0
;
;	8C	 XORB2 mask.rb, dst.mb						* * 0 -
;	CC	 XORL2 mask.rl, dst.ml						* * 0 -
;	AC	 XORW2 mask.rw, dst.mw						* * 0 -
;
;	8D	 XORB3 mask.rb, src.rb, dst.wb					* * 0 -
;	CD	 XORL3 mask.rl, src.rl, dst.wl					* * 0 -
;	AD	 XORW3 mask.rw, src.rw, dst.ww					* * 0 -
;
;
;	Address Instructions
;
;	Opcode	 Instruction							N Z V C		Exceptions
;	------	 -----------							-------		----------
;
;	9E	 MOVAB src.ab, dst.wl						* * 0 -
;	DE	 MOVAL{=F} src.al, dst.wl					* * 0 -
;	7E	 MOVAQ{=D=G} src.aq, dst.wl					* * 0 -
;	3E	 MOVAW src.aw, dst.wl						* * 0 -
;
;	9F	 PUSHAB src.ab, {-(SP).wl}					* * 0 -
;	DF	 PUSHAL{=F} src.al, {-(SP).wl}					* * 0 -
;	7F	 PUSHAQ{=D=G} src.aq, {-(SP).wl}				* * 0 -
;	3F	 PUSHAW src.aw, {-(SP).wl}					* * 0 -
;
.bin

.nobin
.TOC	"	MOVx, MOVAx, MOVZxy"

;	These instructions move a data item or address from the first
;	(source) operand to the second (destination) operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	MOVB		90	dst.wb <-- src.rb			fre	ra/bb 	iiip	MOVX
;	MOVW		B0	dst.ww <-- src.rw 			fre	ra/ww 	iiip	MOVX
;	MOVL		D0	dst.wl <-- src.rl			fre	ra/ll 	iiip	MOVX
;	MOVQ		7D	dst.wq <-- src.rq			fre	ra/qq 	iiip	MOVX
;
;	MOVAB		9E	dst.wl <-- src.ab			fre	aa/bl 	iiip	MOVX
;	MOVAW		3E	dst.wl <-- src.aw			fre	aa/wl 	iiip	MOVX
;	MOVAL		DE	dst.wl <-- src.al			fre	aa/ll 	iiip	MOVX
;	MOVAQ		7E	dst.wl <-- src.aq			fre	aa/ql 	iiip	MOVX
;
;	MOVZBL		9A	dst.wl <-- zext(src.rb)			fre	ra/bl 	iiip	MOVX
;	MOVZBW		9B	dst.ww <-- zext(src.rb)			fre	ra/bw 	iiip	MOVX
;	MOVZWL		3C	dst.wl <-- zext(src.rw)			fre	ra/wl 	iiip	MOVX
;
;	Entry conditions:
;		W0	=	first (source) operand
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The source has been stored in the destination register or memory location.
;		The next microstate is IID.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- 0
;		C <-- C
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	MOVx, MOVAx, MOVZxy operation:
;
;		dst.wx <-- src.rx [src.ax]

;***	MOVx, MOVAx, MOVZxy not RMODE ***

;MOVB:						; opcode = 90
;MOVW:						; opcode = B0
;MOVL:						; opcode = D0
;MOVQ:						; opcode = 7D
;MOVAB:						; opcode = 9E
;MOVAW:						; opcode = 3E
;MOVAL:						; opcode = DE
;MOVZBL:					; opcode = 9A
;MOVZBW:					; opcode = 9B
;MOVZWL:					; opcode = 3C
MOVX..:						; dispatch for opcode = 10
	;********** Hardware dispatch **********;
	MEM(VA)<--W[0], SET.PSLCC, LEN(DL),	; write data to memory, set PSL CC's
	IF(DL.BWL)_IID				; exit if bwl

	;---------------------------------------;
	MEM(VAP)<--W[1], SET.PSLCC, LONG,	; write second lw to memory,
	OLD.Z.AND.NEW.Z,			; set PSL CC's from combined result
	EXECUTE.IID				; exit for quad

;***	MOVx, MOVAx, MOVZxy RMODE ***

MOVX.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--W[0], SET.PSLCC, LEN(DL),	; write data to register, set PSL CC's
	RN<--RN+1,				; increment register pointer
	IF(DL.BWL)_IID				; exit if bwl

	;---------------------------------------;
	G(RN)<--W[1], SET.PSLCC, LEN(DL),	; write second lw to register,
	OLD.Z.AND.NEW.Z,			; set PSL CC's from combined result
	EXECUTE.IID				; exit for quad

.nobin
.TOC	"	PUSHL, PUSHAx"

;	These instructions push a data item or address onto the stack.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	PUSHL		DD	-(sp) <-- src.rl			fe	rr/ll	iiip	PUSHX
;
;	PUSHAB		9F	-(sp) <-- src.ab			fe	ar/bl	iiip	PUSHX
;	PUSHAW		3F	-(sp) <-- src.aw			fe	ar/wl	iiip	PUSHX
;	PUSHAL		DF	-(sp) <-- src.al			fe	ar/ll	iiip	PUSHX
;	PUSHAQ		7F	-(sp) <-- src.aq			fe	ar/ql	iiip	PUSHX
;
;	Entry conditions:
;		W0	=	first (source) operand
;		DL	=	data type of "second" operand (longword)
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The source has been pushed on the stack.
;		The next microstate is IID.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- 0
;		C <-- C
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	PUSHL, PUSHAx operation:
;
;		-(sp) <-- src.rl [src.ax]

;PUSHL:						; opcode = DD
;PUSHAB:					; opcode = 9F
;PUSHAW:					; opcode = 3F
;PUSHAL:					; opcode = DF
;PUSHAQ:					; opcode = 7F
PUSHX..:					; dispatch for opcode = 15
	;********** Hardware dispatch **********;
	VA&, WBUS<--G[SP]-M[FOUR]		; compute addr of decremented stk ptr
						; can't use RLOG with expl register

	;---------------------------------------;
	MEM(VA)<--W[0], SET.PSLCC, LEN(DL)	; push operand onto stack, set psl cc's

PUSH.DEC.SP..:
	;---------------------------------------;
	G[SP]<--G[SP]-M[FOUR],			; instr can complete, update stk ptr
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	MCOMx, MNEGx"

;	These instructions move a complemented or negated source operand to
;	a destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	MCOMB		92	dst.wb <-- ~src.rb			fre	ra/bb 	iiip	MCOMB
;	MCOMW		B2	dst.ww <-- ~src.rw			fre	ra/ww 	iiip	MCOMB
;	MCOML		D2	dst.wl <-- ~src.rl			fre	ra/ll 	iiip	MCOMB
;
;	MNEGB		8E	dst.wb <-- -src.rb			fre	ra/bb 	iiij	MNEGB
;	MNEGL		AE	dst.ww <-- -src.rw			fre	ra/ww 	iiij	MNEGB
;	MNEGW		CE	dst.wl <-- -src.rl			fre	ra/ll 	iiij	MNEGB
;
;	Entry conditions:
;		W0	=	first (source) operand
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;		(MNEGx)			(MCOMx)
;		N <-- dst lss 0		N <-- dst lss 0
;		Z <-- dst eql 0		Z <-- dst eql 0
;		V <-- overflow		V <-- 0
;		C <-- borrow out	C <-- C
;
;	Size/performance tradeoffs:
;		Each instruction type can be shortened by one word, at the cost of one microcycle
;		in register mode, by using an fe dispatch and jumping to WDEST.
;
;	Note:	MCOMx and MNEGx set the PSL CC's before testing the write accessibility of dst.wx.
;
.bin

;	MCOMx operation:
;
;		dst.wx <-- ~src.rx

;***	MCOMx not RMODE ***

MCOMB..:					; opcode = 92
;MCOMW:						; opcode = B2
;MCOML:						; opcode = D2
	;********** Hardware dispatch **********;
	W[0]<--NOT.W[0], SET.PSLCC, LEN(DL),	; complement the source operand, set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	MCOMx RMODE ***

MCOMB.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--NOT.W[0], SET.PSLCC, LEN(DL),	; complement the source operand
	EXECUTE.IID				; decode next instruction

;	MNEGx operation:
;
;		dst.wx <-- src.rx

;***	MNEGx not RMODE ***

MNEGB..:					; opcode = 8E
;MNEGW:						; opcode = AE
;MNEGL:						; opcode = CE
	;********** Hardware dispatch **********;
	W[0]<--NEG.W[0], SET.PSLCC, LEN(DL),	; negate the source operand, set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	MNEGx RMODE ***

MNEGB.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--NEG.W[0], SET.PSLCC, LEN(DL),	; negate the source operand, set psl cc's
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	ADDx3, BICx3, BISx3, SUBx3, XORx3"

;	These instructions perform a simple operation between two source operands and
;	store the result into the third (destination) operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ADDB3		81	dst.wb <-- src1.rb + src2.rb 		fre	rr/bb 	aaaa	ADDB3
;	ADDW3		A1	dst.ww <-- src1.rw + src2.rw 		fre	rr/ww 	aaaa	ADDB3
;	ADDL3		C1	dst.wl <-- src1.rl + src2.rl		fre	rr/ll 	aaaa	ADDB3
;
;	SUBB3		83	dst.wb <-- src2.rb - src1.rb		fre	rr/bb 	aaab	SUBB3
;	SUBB3		A3	dst.ww <-- src2.rw - src1.rw		fre	rr/ww 	aaab	SUBB3
;	SUBB3		C3	dst.wl <-- src2.rl - src1.rl		fre	rr/ll 	aaab	SUBB3
;
;	BISB3		89	dst.wb <-- src1.rb or src2.rb		fre	rr/bb 	aaap	BISB3
;	BISW3		A9	dst.ww <-- src1.rw or src2.rw		fre	rr/ww 	aaap	BISB3
;	BISL3		C9	dst.wl <-- src1.rl or src2.rl		fre	rr/ll 	aaap	BISB3
;
;	BICB3		8B	dst.wb <-- ~src1.rb and src2.rb		fre	rr/bb 	aaap	BICB3
;	BICW3		AB	dst.ww <-- ~src1.rw and src2.rw		fre	rr/ww 	aaap	BICB3
;	BICL3		CB	dst.wl <-- ~src1.rl and src2.rl		fre	rr/ll 	aaap	BICB3
;
;	XORB3		8D	dst.wb <-- src1.rb xor src2.rb		fre	rr/bb 	aaap	XORB3
;	XORL3		AD	dst.ww <-- src1.rw xor src2.rw		fre	rr/ww 	aaap	XORB3
;	XORW3		CD	dst.wl <-- src1.rl xor src2.rl		fre	rr/ll 	aaap	XORB3
;
;	Entry conditions:
;		W0	=	first (source1) operand
;		W2	=	second (source2) operand if not a register
;		DL	=	data type of second operand (same as third)
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		(ADDx3)			(SUBx3)			(BISx3, BICx3, XORx3)
;		N <-- dst lss 0		N <-- dst lss 0		N <-- dst lss 0
;		Z <-- dst eql 0		Z <-- dst eql 0		Z <-- dst eql 0
;		V <-- overflow		V <-- overflow		V <-- 0
;		C <-- carry out		C <-- borrow out	C <-- C
;
;	Size/performance tradeoffs:
;		Each instruction type can be shortened by one word, at the cost of one microcycle
;		when the second specifier is register mode, by using an fse dispatch.
;
.bin

;	ADDx3 operation:
;
;		dst.wx <-- src1.rx + src2.rx

;***	ADDx3 not RMODE ***

ADDB3..:					; opcode = 81
;ADDL3:						; opcode = C1
;ADDW3:						; opcode = A1
	;********** Hardware dispatch **********;
	W[0]<--W[2]+W[0], SET.ALUCC, LEN(DL),	; do the add using length from DL
	JMP.CASE.SPEC[WDEST..]			; set ALU CC's, and go write result

;***	ADDx3 RMODE ***

ADDB3.OP..:
	;********** Hardware dispatch **********;
	W[0]<--G(RN)+W[0], SET.ALUCC, LEN(DL),	; do the add using length from DL
	JMP.CASE.SPEC[WDEST..]			; set ALU CC's, and go write result

;	SUBx3 operation:
;
;		dst.wx <-- src2.rx - src1.rx

;***	SUBx3 not RMODE ***

SUBB3..:					; opcode = 83
;SUBL3:						; opcode = C3
;SUBW3:						; opcode = A3
	;********** Hardware dispatch **********;
	W[0]<--W[2]-W[0], SET.ALUCC, LEN(DL),	; do the subtract using length from DL
	JMP.CASE.SPEC[WDEST..]			; set ALU CC's, and go write result

;***	SUBx3 RMODE ***

SUBB3.OP..:
	;********** Hardware dispatch **********;
	W[0]<--G(RN)-W[0], SET.ALUCC, LEN(DL),	; do the subtract using length from DL
	JMP.CASE.SPEC[WDEST..]			; set ALU CC's, and go write result

;	BISx3 operation:
;
;		dst.wx <-- src1.rx or src2.rx

;***	BISx3 not RMODE ***

BISB3..:					; opcode = 89
;BISL3:						; opcode = C9
;BISW3:						; opcode = A9
	;********** Hardware dispatch **********;
	W[0]<--W[2].OR.W[0],			; do the bit set using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

;***	BISx3 RMODE ***

BISB3.OP..:
	;********** Hardware dispatch **********;
	W[0]<--G(RN).OR.W[0],			; do the bit set using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

;	BICx3 operation:
;
;		dst.wx <-- ~src1.rx and src2.rx

;***	BICx3 not RMODE ***

BICB3..:					; opcode = 8B
;BICL3:						; opcode = CB
;BICW3:						; opcode = AB
	;********** Hardware dispatch **********;
	W[0]<--W[2].ANDNOT.W[0],		; do the bit clear using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

;***	BICx3 RMODE ***

BICB3.OP..:
	;********** Hardware dispatch **********;
	W[0]<--G(RN).ANDNOT.W[0],		; do the bit clear using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

;	XORx3 operation:
;
;		dst.wx <-- src1.rx xor src2.rx

;***	XORx3 not RMODE ***

XORB3..:					; opcode = 8D
;XORL3:						; opcode = CD
;XORW3:						; opcode = AD
	;********** Hardware dispatch **********;
	W[0]<--W[2].XOR.W[0],			; do the xor using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

;***	XORx3 RMODE ***

XORB3.OP..:
	;********** Hardware dispatch **********;
	W[0]<--G(RN).XOR.W[0],			; do the xor using length from DL
	SET.ALUCC, LEN(DL),			; set ALU CC's
	JMP.CASE.SPEC[WDEST..]			; go write result

.nobin
.TOC	"	ADDx2, BICx2, BISx2, SUBx2, XORx2"

;	These instructions perform a simple operation between a source operand and
;	a destination operand and store the result into the destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ADDB2		80	dst.mb <-- src.rb + dst.mb 		fre	rm/bb 	iiii	ADDB2
;	ADDW2		A0	dst.mw <-- src.rw + dst.mw 		fre	rm/ww 	iiii	ADDB2
;	ADDL2		C0	dst.ml <-- src.rl + dst.ml		fre	rm/ll 	iiii	ADDB2
;
;	SUBB2		82	dst.mb <-- dst.mb - src.rb		fre	rm/bb 	iiij	SUBB2
;	SUBB2		A2	dst.mw <-- dst.mw - src.rw		fre	rm/ww 	iiij	SUBB2
;	SUBB2		C2	dst.ml <-- dst.ml - src.rl		fre	rm/ll 	iiij	SUBB2
;
;	BISB2		88	dst.mb <-- src.rb or dst.mb		fre	rm/bb 	iiip	BISB2
;	BISW2		A8	dst.mw <-- src.rw or dst.mw		fre	rm/ww 	iiip	BISB2
;	BISL2		C8	dst.ml <-- src.rl or dst.ml		fre	rm/ll 	iiip	BISB2
;
;	BICB2		8A	dst.mb <-- ~src.rb and dst.mb		fre	rm/bb 	iiip	BICB2
;	BICW2		AA	dst.mw <-- ~src.rw and dst.mw		fre	rm/ww 	iiip	BICB2
;	BICL2		CA	dst.ml <-- ~src.rl and dst.ml		fre	rm/ll 	iiip	BICB2
;
;	XORB2		8C	dst.mb <-- src.rb xor dst.mb		fre	rm/bb 	iiip	XORB2
;	XORL2		AC	dst.mw <-- src.rw xor dst.mw		fre	rm/ww 	iiip	XORB2
;	XORW2		CC	dst.ml <-- src.rl xor dst.ml		fre	rm/ll 	iiip	XORB2
;
;	Entry conditions:
;		W0	=	first (source) operand
;		W2	=	second (destination) operand if not a register
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;		(ADDx2)			(SUBx2)			(BISx2, BICx2, XORx2)
;		N <-- dst lss 0		N <-- dst lss 0		N <-- dst lss 0
;		Z <-- dst eql 0		Z <-- dst eql 0		Z <-- dst eql 0
;		V <-- overflow		V <-- overflow		V <-- 0
;		C <-- carry out		C <-- borrow out	C <-- C
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	ADDx2 operation:
;
;		dst.mx <-- dst.mx + src.rx

;***	ADDx2 not RMODE ***

ADDB2..:					; opcode = 80
;ADDL2:						; opcode = C0
;ADDW2:						; opcode = A0
	;********** Hardware dispatch **********;
	W[0]<--W[2]+W[0], SET.PSLCC, LEN(DL),	; do the add, set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	ADDx2 RMODE ***

ADDB2.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN)+W[0], SET.PSLCC, LEN(DL),	; do the add, set psl cc's
	EXECUTE.IID				; decode next instruction

;	SUBx2 operation:
;
;		dst.mx <-- dst.mx - src.rx

;***	SUBx2 not RMODE ***

SUBB2..:					; opcode = 82
;SUBL2:						; opcode = C2
;SUBW2:						; opcode = A2
	;********** Hardware dispatch **********;
	W[0]<--W[2]-W[0], SET.PSLCC, LEN(DL),	; do the subtract, set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	SUBx2 RMODE ***

SUBB2.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN)-W[0], SET.PSLCC, LEN(DL),	; do the subtract, set psl cc's
	EXECUTE.IID				; decode next instruction

;	BISx2 operation:
;
;		dst.mx <-- src.rx or dst.mx

;***	BISx2 not RMODE ***

BISB2..:					; opcode = 88
;BISL2:						; opcode = C8
;BISW2:						; opcode = A8
	;********** Hardware dispatch **********;
	W[0]<--W[2].OR.W[0],			; do the bit set using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	BISx2 RMODE ***

BISB2.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN).OR.W[0],			; do the bit set using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

;	BICx2 operation:
;
;		dst.mx <-- ~src.rx and dst.mx

;***	BICx2 not RMODE ***

BICB2..:					; opcode = 8A
;BICL2:						; opcode = CA
;BICW2:						; opcode = AA
	;********** Hardware dispatch **********;
	W[0]<--W[2].ANDNOT.W[0],		; do the add using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	BICx2 RMODE ***

BICB2.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN).ANDNOT.W[0],		; do the bit clear using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

;	XORx2 operation:
;
;		dst.wx <-- src.rx xor dst.mx

;***	XORx2 not RMODE ***

XORB2..:					; opcode = 8C
;XORL2:						; opcode = CC
;XORW2:						; opcode = AC
	;********** Hardware dispatch **********;
	W[0]<--W[2].XOR.W[0],			; do the xor using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	XORx2 RMODE ***

XORB2.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN).XOR.W[0],			; do the xor using length from DL
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	INCx, DECx"

;	These instructions increment or decrement a single destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	INCB		96	dst.mb <-- dst.mb + 1			fe	mr/bb	iiii	INCB
;	INCW		B6	dst.mw <-- dst.mw + 1			fe	mr/ww	iiii	INCB
;	INCL		D6	dst.ml <-- dst.ml + 1			fe	mr/ll	iiii	INCB
;
;	DECB		97	dst.mb <-- dst.mb - 1			fe	mr/bb	iiij	DECB
;	DECW		B7	dst.mw <-- dst.mw - 1			fe	mr/ww	iiij	DECB
;	DECL		D7	dst.ml <-- dst.ml - 1			fe	mr/ll	iiij	DECB
;
;	Entry conditions:
;		W0	=	first operand
;		VA	=	address of first operand if not a register
;		DL	=	data type of "second" operand (same as first)
;		RN	=	register number of first specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;		(INCx)			(DECx)
;		N <-- dst lss 0		N <-- dst lss 0
;		Z <-- dst eql 0		Z <-- dst eql 0
;		V <-- overflow		V <-- overflow
;		C <-- carry out		C <-- borrow out
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	INCx operation:
;
;		dst.mx <-- dst.mx + 1

INCB..:						; opcode = 96
;INCW: 						; opcode = B6
;INCL:						; opcode = D6
	;********** Hardware dispatch **********;
 	W[0]<--W[0]+1, SET.PSLCC, LEN(DL),	; W0 gets incremented source
	IF[RMODE]_[WRITE.RMODE..]		; set CC's using DL

;	This multipurpose location is used to write W0 to MEM(VA).
;	The psl cc's are not changed, and the next microstate is IID.
;	Used by ADDx2, SUBx2, BISx2, BICx2, XORx2, MCOMx, MNGEGx, and others.

WRITE.MEM..:
	;---------------------------------------;
	MEM(VA)<--W[0], LEN(DL), EXECUTE.IID	; write result to memory, decode next

;	This multipurpose location is used to write W0 to G(RN).
;	The psl cc's are not changed, and the next microstate is IID.
;	Used by INCx, DECx, and others.

WRITE.RMODE..:
	;---------------------------------------;
	G(RN)<--W[0], SET.ALUCC, LEN(DL),	; G(RN) gets result (use alu cc's for len(dl))
	EXECUTE.IID				; decode next instruction

;	DECx operation:
;
;		dst.mx <-- dst.mx - 1

DECB..:						; opcode = 97
;DECW: 						; opcode = B7
;DECL:						; opcode = D7
	;********** Hardware dispatch **********;
 	W[0]<--W[0]-1, SET.PSLCC, LEN(DL),	; W0 gets decremented source
	IF[RMODE]_[WRITE.RMODE..]		; set CC's using DL

	;---------------------------------------;
	MEM(VA)<--W[0], LEN(DL), EXECUTE.IID	; write result to memory, decode next

.nobin
.TOC	"	CLRx"

;	These instructions clear a data item in a register or memory.
;	The condition codes are set according to the (zero) result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	CLRB		94	dst.wb <-- 0				fe	vr/bb	iiip	CLRX
;	CLRW		B4	dst.ww <-- 0				fe	vr/ww	iiip	CLRX
;	CLRL		D4	dst.wl <-- 0				fe	vr/ll	iiip	CLRX
;	CLRQ		7C	dst.wq <-- 0				fe	vr/qq	iiip	CLRX
;
;	Entry conditions:
;		VA	=	address of first operand if not a register
;		DL	=	data type of "second" operand (same as first)
;		RN	=	register number of first specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;               N <-- 0
;               Z <-- 1 
;               V <-- 0
;               C <-- C
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	CLRx operation:
;
;		dst.wx <-- 0

;CLRB:						; opcode = 94
;CLRW:						; opcode = B4
;CLRL:						; opcode = D4
;CLRQ:						; opcode = 7C
CLRX..:						; dispatch for opcode = 14
	;********** Hardware dispatch **********;
	W[4]<--0, LONG,				; W4 gets zero
	IF[RMODE]_[CLR.RMODE]			; if register, go write result to register

	;---------------------------------------;
	MEM(VA)<--W[4], SET.PSLCC, LEN(DL),	; write data to memory, set psl cc's
	IF(DL.BWL)_IID.ELSE.[WRITE.MEM(VAP).FROM.W4..]	; exit for bwl else write again

CLR.RMODE:
	;---------------------------------------;
 	G(RN)<--W[4], SET.PSLCC, LEN(DL),	; write data to register, set psl cc's
	RN<--RN+1,				; point to next register
	IF(DL.BWL)_IID.ELSE.[WRITE.G(RN).FROM.W4..]	; exit for bwl else write again

.nobin
.TOC	"	TSTx"

;	These instructions test the source operand against zero.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	TSTB		95	src.rb - 0				fe	rr/bb	iiii	TSTB
;	TSTW		B5	src.rw - 0				fe	rr/ww	iiii	TSTB
;	TSTL		D5	src.rl - 0				fe	rr/ll	iiii	TSTB
;
;	Entry conditions:
;		W0	=	first (source) operand
;		DL	=	data type of "second" operand (same as first)
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The next microstate is IID.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- 0
;		C <-- 0
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	TSTx operation:
;
;		src.rx - 0

TSTB..:						; opcode = 95
;TSTW:						; opcode = B5
;TSTL:						; opcode = D5
	;********** Hardware dispatch **********;
	WBUS<--W[0], SET.PSLCC, LEN(DL),	; set psl cc's
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	CMPx, BITx"

;	These instructions perform a simple operation between two source operands.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	CMPB		91	src1.rb - src2.rb 			fre	rr/bb 	jizj	CMPB
;	CMPW		B1	src1.rw - src2.rw 			fre	rr/ww 	jizj	CMPB
;	CMPL		D1	src1.rl - src2.rl			fre	rr/ll 	jizj	CMPB
;
;	BITB		93	src1.rb and src2.rb			fre	rr/bb 	iiip	BITB
;	BITW		B3	src1.rw and src2.rw			fre	rr/ww 	iiip	BITB
;	BITL		D3	src1.rl and src2.rl			fre	rr/ll 	iiip	BITB
;
;	Entry conditions:
;		W0	=	first (source) operand
;		W2	=	second (destination) operand if not a register
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The next microstate is IID.
;
;	Condition codes:
;		(CMPx)			(BITx)
;		N <-- src1 lss src2	N <-- dst lss 0
;		Z <-- src1 eql src2	Z <-- dst eql 0
;		V <-- 0			V <-- 0
;		C <-- src1 lssu src2	C <-- C
;
;	Size/performance tradeoffs:
;		Each instruction type can be reduced by one word, at the cost of one microcycle
;		if the second specifier is register mode, by using an fse dispatch.
;.
.bin

;	CMPx operation:
;
;		src1.rx - src2.rx

;***	CMPx not RMODE ***

CMPB..:						; opcode = 91
;CMPW:						; opcode = B1
;CMPL:						; opcode = D1
	;********** Hardware dispatch **********;
	WBUS<--W[0]-W[2], SET.PSLCC, LEN(DL),	; compute result, set psl cc's
	EXECUTE.IID				; decode next instruction

;***	CMPx RMODE ***

CMPB.OP..:
	;********** Hardware dispatch **********;
	WBUS<--W[0]-G(RN), SET.PSLCC, LEN(DL),	; compute result, set psl cc's
	EXECUTE.IID				; decode next instruction

;	BITx operation:
;
;		src1.rx and src2.rx

;***	BITx not RMODE ***

BITB..:						; opcode = 93
;BITW:						; opcode = B3
;BITL:						; opcode = D3
	;********** Hardware dispatch **********;
	WBUS<--W[2].AND.W[0],			; compute result
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

;***	BITx RMODE ***

BITB.OP..:
	;********** Hardware dispatch **********;
	WBUS<--G(RN).AND.W[0],			; compute result
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	ADAWI"

;	This instruction does an interlocked add to an aligned word in memory.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ADAWI		58	dst.mw <-- src.rw + dst.mw		fre	rv/ww	iiii	ADAWI
;
;	Entry conditions:
;		W0	=	first (source) operand
;		W2	=	address of second (destination) operand if not a register
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand (word)
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;               N <-- dst lss 0
;               Z <-- dst eql 0
;               V <-- overflow
;               C <-- carry out
;
;	Size/performance tradeoffs:
;		None (register mode must be split out due to interlock).
;
.bin

;	ADAWI operation:
;
;		dst.mw <-- src.rw + dst.mw, interlocked

;***	ADAWI not RMODE ***

ADAWI..:					; opcode = 58
	;********** Hardware dispatch **********;
	WBUS<--W[2].AND.K[1.], SET.ALUCC 	; check bottom bit

	;---------------------------------------;
	VA<--W[2],				; put operand address into VA
	IF[NOT.ALU.Z]_[RSRV.OPER.FLT..]		; if VA<0> not zero, fault

	;---------------------------------------;
	W[1]<--MEM(VA).LOCK, LEN(DL),		; read and lock destination operand, check access
	DISABLE.IB.PREFETCH			; disable prefetching while bus locked

	;---------------------------------------;
	W[1]<--W[1]+W[0], SET.PSLCC, LEN(DL)	; compute result, set psl cc's

	;---------------------------------------;
	MEM(VA).UNLOCK<--W[1], LEN(DL),		; int overflow trap occurs at IID
	ENABLE.IB.PREFETCH,			; re-enable prefetching after bus unlock
	EXECUTE.IID				; due to bit set in IPLA

;***	ADAWI RMODE ***

ADAWI.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN)+W[0], SET.PSLCC, LEN(DL),	; no interlock for reg destination 
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	ADWC, SBWC"

;	These instructions perform a extended precision operations between a source 
;	operand and a destination operand and store the result into the destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ADWC		D8	dst.ml <-- src.rl + dst.ml + C		fre	rm/ll 	iiii	ADWC
;
;	SBWC		D9	dst.ml <-- dst.ml - src.rl - C		fre	rm/ll 	iiij	SBWC
;
;	Entry conditions:
;		W0	=	first (source) operand
;		W2	=	second (destination) operand if not a register
;		VA	=	address of second (destination) operand if not a register
;		DL	=	data type of second operand (longword)
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The PSL condition codes are set.
;		The result has been stored in the destination memory location or register.
;		The next microstate is IID.
;
;	Condition codes:
;		(ADWC)			(SBWC)
;		N <-- dst lss 0		N <-- dst lss 0
;		Z <-- dst eql 0		Z <-- dst eql 0
;		V <-- overflow		V <-- overflow
;		C <-- carry out		C <-- borrow out
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	ADWC operation:
;
;		dst.ml <-- src.rl + dst.ml + C

;***	ADWC not RMODE ***

ADWC..:						; opcode = D8
	;********** Hardware dispatch **********;
	W[0]<--W[2]+W[0]+PSL.C,			; add the two operands with PSL.C
	SET.PSLCC, LEN(DL),			; set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	ADWC RMODE ***

ADWC.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN)+W[0]+PSL.C,		; add with PSL.C
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

;	SBWC operation:
;
;		dst.ml <-- dst.ml - src.rl - C

;***	SBWC not RMODE ***

SBWC..:						; opcode = D9
	;********** Hardware dispatch **********;
	W[0]<--W[2]-W[0]-PSL.C,			; subtract the two operands with PSL.C
	SET.PSLCC, LEN(DL),			; set psl cc's
	GOTO[WRITE.MEM..]			; go write result to memory

;***	SBWC RMODE ***

SBWC.OP..:
	;********** Hardware dispatch **********;
	G(RN)<--G(RN)-W[0]-PSL.C,		; subtract with PSL.C
	SET.PSLCC, LEN(DL),			; set psl cc's
	EXECUTE.IID				; decode next instruction

.nobin
.TOC	"	CVTBW, CVTBL, CVTWL"

;	These instructions move a sign extended data item from the first
;	(source) operand to the second (destination) operand.
;	The conditions codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	CVTBW		99	dst.ww <-- sext(src.rb)			fe	rr/bw	aaaa	CVTBL
;	CVTBL		98	dst.wl <-- sext(src.rb)			fe	rr/bl	aaaa	CVTBL
;	CVTWL		32	dst.wl <-- sext(src.rw)			fe	rr/wl	aaaa	CVTWL
;
;	Entry conditions:
;		W0	=	first (source) operand
;		DL	=	data type of second operand
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- 0
;		C <-- 0
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	CVTBW, CVTBL, CVTWL operation:
;
;		dst.wy <-- sext(src.rx)

;CVTBW..:					; opcode = 98
CVTBL..:					; opcode = 99
	;********** Hardware dispatch **********;
	W[0]<--W[0].SHFL.[24.], SET.ALUCC	; left justify source operand in W0
						; set alu cc's for sext shift

	;---------------------------------------;
	W[0]<--SEXT.W[0].SHFR.[24.],		; right justify and sign extend source operand
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result to memory

CVTWL..:					; opcode = 32
	;********** Hardware dispatch **********;
	W[0]<--W[0].SHFL.[16.], SET.ALUCC	; left justify source operand in W0
						; set alu cc's for sext shift

	;---------------------------------------;
	W[0]<--SEXT.W[0].SHFR.[16.], 		; right justify and sign extend source operand
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result to memory

.nobin
.TOC	"	CVTWB, CVTLB, CVTLW"

;	These instructions truncate and move a data item from the first
;	(source) operand to the second (destination) operand.
;	The conditions codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	CVTWB		33	dst.wb <-- src.rw			fe	rr/wb	aaaa	CVTWB
;	CVTLB		F6	dst.wb <-- src.rl			fe	rr/lb	aaaa	CVTLB
;	CVTLW		F7	dst.ww <-- src.rl			fe	rr/lw	aaaa	CVTLW
;
;	Entry conditions:
;		W0	=	first (source) operand
;		DL	=	data type of second operand
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- overflow
;		C <-- 0
;
;	Size/performance tradeoffs:
;		None.
;
;	Note:	ASHL and ASHQ make EXTENSIVE use of this code for overflow checking.
;		Do NOT change these multiuse statements without careful perusal of
;		ASHL and ASHQ.
;
.bin

;	CVTWB, CVTLB, CVTLW operation:
;
;		dst.wy <-- trunc(src.rx)

CVTLB..:					; opcode = F6
	;********** Hardware dispatch **********;
	SC<--W[0].AND.111K[80], SET.ALUCC,	; test for pos lw fit in byte (alu.z if yes)
	GOTO[CVTX.TO.BYTE]			; go join common flows

CVTWB..:					; opcode = 33
	;********** Hardware dispatch **********;
	SC<--W[0].AND.111K[80], SET.ALUCC	; test for pos w fit in byte (alu.z if yes)

	;---------------------------------------;
	W[SC]<--W[SC].OR.11K[0]0,		; sign extend to negative lw
	IF[ALU.Z]_[CVTX.NO.OVERFLOW]		; if alu.z, fits as positive w

;	CVTLB, CVTWB:
;	At this point, the ALU condition codes reflect whether the source operand
;	is a zero-extended positive byte (alu.z if yes).  SC contains the original
;	operand with bits <6:0> forced to zero, that is, the sign extension portion
;	of the original byte.  Now test SC<31:7> for all one's.

CVTX.TO.BYTE:					; common for CVTWB, CVTLB
	;---------------------------------------;
	WBUS<--W[SC].XOR.111K[80], SET.ALUCC,	; test for sign-extension = all one's (alu.z if yes)
	IF[ALU.Z]_[CVTX.NO.OVERFLOW]		; branch if pos lw fits in byte

;	CVTWB, CVTLB, CVTLW:
;	At this point, the ALU condition codes reflect whether the source operand
;	sign extension was all one's (alu.z if yes).  W0 contains the original operand.

CVTX.NEG.TEST:

;	ASHL (left shift, non-zero result cases):
;	At this point, the ALU condition codes reflect whether the source operand equals
;	the shifted and restored result (alu.z if yes).  W0 contains the shifted operand.

ASHL.LEFT.0.31.EXIT:

;	ASHQ (left shift, zero result cases):
;	At this point, the ALU condition codes reflect whether the source operand was
;	zero (alu.z if yes).  W0 contains the result, which must be duplicated to W1.

ASHQ.LEFT.64.127.EXIT:

;	MULX3:
;	At this point, the ALU condition codes reflect whether the sign extension of
;	the low half of the result equals the high half of the result (alu.z if yes).

MULX3.EXIT..:
	;---------------------------------------;
	W[1]<--W[0], SET.ALUCC, LEN(DL),	; copy W0 to W1 (relevent only for ASHQ)
						; set alu cc's for result value
	CASE2[ALU.NZVC].AT.[CVTX.OVERFLOW]	; case on sign extension = all one's (CVTxy)
						; case on original = shifted (ASHx)

;	CVTLB, CVTWB, CVTLB, ASHL, ASHQ, MULX3:
;	Overflow has been detected.  Set the alu.v flag.  The other alu cc's are correct.

;= ALIGNLIST 10***	(CVTX.OVERFLOW,	CVTX.NO.OVERFLOW)
;  ALU.NZVC set by XOR --> V = C = 0

CVTX.OVERFLOW:
ASHX.OVERFLOW:
	;---------------------------------------; alu.z = 0:
	SET.ALU.V, JMP.CASE.SPEC[WDEST..]	; set alu.v flag, go write result to memory


CVTLW..:					; opcode = F7
	;********** Hardware dispatch **********;
	SC<--W[0].AND.11K[80]0, SET.ALUCC	; test for pos lw fit in word (alu.z if yes)

	;---------------------------------------;
	WBUS<--W[SC].XOR.11K[80]0, SET.ALUCC,	; test for sign-extension = all one's (alu.z if yes)
	IF[NOT.ALU.Z]_[CVTX.NEG.TEST]		; branch if pos lw won't fit in word

;	CVTLB, CVTWB, CVTLW:
;	This location is reached if the source fits in the destination
;	without overflow.  W0 contains the original operand.

;	ASHL (left), ASHQ (zero result cases):
;	This location is reached if overflow has not occurred.  W0 contains the
;	portion of the result that determines the condition codes.

CVTX.NO.OVERFLOW:
	;---------------------------------------; alu.z = 1:
	WBUS<--W[0], SET.ALUCC,	LEN(DL),	; set alu cc's based on result value
	JMP.CASE.SPEC[WDEST..]			; go write result to memory

.nobin
.TOC	"	ROTL"

;	This instruction rotates a longword source operand left or right and stores
;	the result in the destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ROTL		9C	dst.wl <-- src.rl rot cnt.rb		fse	rr/bl 	aaap	ROTL
;
;	Entry conditions:
;		W0	=	first (count) operand
;		SC	=	first (count) operand duplicate
;		W2	=	second (source) operand
;		DL	=	data type of second operand (same as third, longword)
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- 0
;		C <-- C
;
;	Size/performance tradeoffs:
;		None.
;
.bin

;	ROTL operation:
;
;		dst.wl <-- src.rl rot cnt.rb

ROTL..:						; opcode = 9C
	;********** Hardware dispatch **********;
	W[0]<--W[2]				; move src operand to W0

	;---------------------------------------;
	W[0]<--W[0].ROTL.(SC),			; rotate W0 by count
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result to memory

.nobin
.TOC	"	ASHL"

;	This instruction shifts a longword source operand left or right and stores
;	the result in the destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ASHL		78	dst.wl <-- src.rl shift cnt.rb		fse	rr/bl 	aaaa	ASHLX
;
;	Entry conditions:
;		W0	=	first (count) operand
;		SC	=	first (count) operand duplicate
;		W2	=	second (source) operand
;		DL	=	data type of second operand (same as third, longword)
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- overflow
;		C <-- 0
;
;	Size/performance tradeoffs:
;		ASHL cannot use fre optimization because of its need to case on the first statement
;		in either microcode path (addressing limit).
;
;		ASHL can be shortened, at a substantial performance penalty, by using conditional
;		tests rather than a case branch to isolate the out of range cases.
;
;	Note:	ASHL uses a special dispatch ASHLX;  otherwise, the initial case statement cannot
;		be allocated.
;
.bin

;	ASHL operation:
;
;		dst.wl <-- src.rl shift cnt.rb

;ASHL:						; opcode = 78
ASHLX..:					; dispatch for opcode = 18
	;********** Hardware dispatch **********;
	W[0]<--W[2], SET.ALUCC, 		; move src operand to W0
	CASE8[SC7-4].AT.[ASHL.LEFT.0.31]	; case on shift count<7:5>

;= ALIGNLIST 0001*	(ASHL.LEFT.0.31,	ASHL.LEFT.32.63,
;=			 ASHL.LEFT.64.95,	ASHL.LEFT.96.127,
;=			 ASHL.RIGHT.128.97,	ASHL.RIGHT.96.65,
;=			 ASHL.RIGHT.64.33,	ASHL.RIGHT.32.1)

;	ASHL left shift cases:  [0,31] is the only important case.

;	At this point,
;		W0 = W2	=	source operand
;		alu cc's =	set from W0

ASHL.LEFT.0.31:
	;---------------------------------------; 0 <= SC <= 31:
	W[0]<--W[0].SHFL.(SC), SET.ALUCC	; shift source operand left by count
						; set alu cc's for sext shift

	;---------------------------------------;
	W(6)&, WBUS<--SEXT.W[0].SHFR.(SC)	; shift result, sign extended, back to
						; original position

	;---------------------------------------;
	WBUS<--W[2].XOR.W[6], SET.ALUCC,	; compare unshifted original with sign ext result
	GOTO[ASHL.LEFT.0.31.EXIT]		; go test for overflow and store result

;	At the transfer to ASHL.LEFT.0.31.EXIT (in CVT), the result is in W0.
;	The ALU condition codes reflect whether any significant bits were lost
;	in the shift (alu.z if no).

;	ASHL left shift cases:	[32,127] yield result of 0.

;	At this point,
;		W0 = W2	=	source operand
;		alu cc's =	set from W0

ASHL.LEFT.32.63:
	;---------------------------------------; 32 <= SC <= 63:
	W[0]<--0, SET.ALUCC,			; out of range, result zero, set alu cc's
	CASE2[ALU.NZVC].AT.[CVTX.OVERFLOW]	; if source not zero, overflow

ASHL.LEFT.64.95:
	;---------------------------------------; 64 <= SC <= 95:
	W[0]<--0, SET.ALUCC,			; out of range, result zero, set alu cc's
	CASE2[ALU.NZVC].AT.[CVTX.OVERFLOW]	; if source not zero, overflow

ASHL.LEFT.96.127:
	;---------------------------------------; 96 <= SC <= 127:
	W[0]<--0, SET.ALUCC,			; out of range, result zero, set alu cc's
	CASE2[ALU.NZVC].AT.[CVTX.OVERFLOW]	; if source not zero, overflow

;	ASHL right shift cases:	[-128,-33] yield sign of source.

;	At this point,
;		W0 = W2	=	source operand
;		alu cc's =	set from W0

ASHL.RIGHT.128.97:
	;---------------------------------------; -128 <= SC <= -97:
	W[0]<--SEXT.W[0].SHFR.[31.],		; shift out of range, result is sign
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result 

ASHL.RIGHT.96.65:
	;---------------------------------------; -96 <= SC <= -65:
	W[0]<--SEXT.W[0].SHFR.[31.],		; shift out of range, result is sign
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result 

ASHL.RIGHT.64.33:
	;---------------------------------------; -64 <= SC <= -33:
	W[0]<--SEXT.W[0].SHFR.[31.],		; shift out of range, result is sign
	SET.ALUCC,				; set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result 

;	ASHL right shift cases:	[-32,-1] is the only important case.

;	At this point,
;		W0 = W2	=	source operand
;		alu cc's =	set from W0

;	The right shift case [-32,-1] takes advantage of a peculiar property of the shifter.
;	The shifter can shift up to 32 bits to the right, but shift values are interpreted
;	modulo 32.  This limits normal shifts to 31 bits.  However, the shifter can receive
;	a shift value of 32 through the use of the (32-SC) option.  Since this is normally
;	reserved for left shifts, the output value would normally be sent to the wrong
;	register (the A port register).  However, the output can instead be captured off
;	the W-Bus and stored in W6.
;
;	Note that for shifting, only SC<4:0> is examined.  Thus, -32 is 111<00000>, and
;	32-SC will cause a right shift of 32;  while -1 is 111<11111>, and 32-SC will
;	cause a right shift of 1.

ASHL.RIGHT.32.1:
	;---------------------------------------; -32 <= SC <= -1:
	W(6)&, WBUS<--SEXT.W[0].SHFR.(32-SC)	; shift right, inverting shift count
						; capture result in W6 (can't store back in W0)

;	ASHL, ASHQ:
;	At this point, W6 contains the only part of the result that can affect the
;	alu cc's.  Move it to W0, set condition codes, and write result.

ASHL.RIGHT.32.1.EXIT:
ASHQ.RIGHT.64.33.EXIT:
ASHQ.RIGHT.128.65.EXIT:
	;---------------------------------------;
	W[0]<--W[6], SET.ALUCC,			; put result in W0, set alu cc's
	JMP.CASE.SPEC[WDEST..]			; go write result 

.nobin
.TOC	"	ASHQ"

;	This instruction shifts a quadword source operand left or right and stores
;	the result in the destination operand.
;	The condition codes are set according to the result.
;
;	Mnemonic      Opcode	Operation				Fork	AT/DL	CC	Dispatch
;	--------      ------	---------				----	-----	--	--------
;	ASHQ		79	dst.wq <-- src.rq shift cnt.rb		fse	rr/bq 	aaaa	ASHQ
;
;	Entry conditions:
;		W0	=	first (count) operand
;		SC	=	first (count) operand duplicate
;		W3'W2	=	second (source) operand
;		DL	=	data type of second operand (same as third, quadword)
;		RN	=	register number of second specifier
;
;	Exit conditions:
;		The ALU condition codes are set.
;		W1'W0 contains the result.
;		The next microstate is WDEST.
;
;	Condition codes:
;		N <-- dst lss 0
;		Z <-- dst eql 0
;		V <-- overflow
;		C <-- 0
;
;	Size/performance tradeoffs:
;		ASHQ can be shortened, at a substantial performance penalty, by using conditional
;		tests rather than a case branch to isolate the out of range cases.
;
.bin

;	ASHQ operation:
;
;		dst.wq <-- src.rq shift cnt.rb

ASHQ..:						; opcode = 79
	;********** Hardware dispatch **********;
	W[0]<--W[2], SET.ALUCC			; copy data to W0, set alu cc's

	;---------------------------------------;
	W[1]<--W[3], SET.ALUCC,			; copy data to W1
	OLD.Z.AND.NEW.Z,			; update alu cc's
	CASE8[SC7-4].AT.[ASHQ.LEFT.0.31]	; case on shift count<7:5>

;= ALIGNLIST 0001*	(ASHQ.LEFT.0.31,	ASHQ.LEFT.32.63,
;=			 ASHQ.LEFT.64.95,	ASHQ.LEFT.96.127,
;=			 ASHQ.RIGHT.128.97,	ASHQ.RIGHT.96.65,
;=			 ASHQ.RIGHT.64.33,	ASHQ.RIGHT.32.1)

;	ASHQ left shift cases:	[0,31].

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

ASHQ.LEFT.0.31:
	;---------------------------------------; 0 <= SC <= 31:
	W[1]<--W[1]!!W[0].SHFL.(SC), SET.ALUCC	; shift quadword source left, get high result
						; set alu cc's for upcoming sext shift

	;---------------------------------------;
	W(6)&, WBUS<--SEXT.W[1].SHFR.(SC)	; reshift to right, sign extending,
						; for overflow check

	;---------------------------------------;
	WBUS<--W[3].XOR.W[6], SET.ALUCC		; compare unshifted original with shifted/reshifted value

	;---------------------------------------;
	W[0]<--W[0].SHFL.(SC),			; shift low order longword left, get low result
	SET.ALUCC,				; set alu cc's
	CASE2[ALU.NZVC].AT.[ASHQ.LEFT.0.63.OVERFLOW]	; case on alu.z (clear if overflow)

;= ALIGNLIST 10***	(ASHQ.LEFT.0.63.OVERFLOW,	ASHQ.LEFT.0.63.EXIT)
;  ALU.NZVC set by XOR --> V = C = 0

ASHQ.LEFT.0.63.OVERFLOW:
	;---------------------------------------; Z = 0:
	WBUS<--W[1],				; bits lost, complete condition codes
	SET.ALUCC, OLD.Z.AND.NEW.Z,		; with test on high order result
	GOTO[ASHX.OVERFLOW]			; go flag overflow and write result to memory

ASHQ.LEFT.0.63.EXIT:
	;---------------------------------------; Z = 1:
	WBUS<--W[1],				; no bits lost, complete condition codes
	SET.ALUCC, OLD.Z.AND.NEW.Z,		; can't go to WDEST, misc field occupied!
	GOTO[JMP.CASE.SPEC.WDEST..]		; go to instruction to go write result

;	ASHQ left shift cases:	[32,63].

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

ASHQ.LEFT.32.63:
	;---------------------------------------; 32 <= SC <=63:
	W[1]<--W[0].SHFL.(SC), SET.ALUCC	; shift low lw by shift mod 32, move to high lw
						; set alu cc's for upcoming sext shift

	;---------------------------------------;
	W(6)&, WBUS<--SEXT.W[1].SHFR.(SC)	; reshift high lw to right, sign extending,
						; for overflow check

	;---------------------------------------;
	WBUS<--W[3].XOR.P[SEXT.N], SET.ALUCC	; start overflow check:  W3 against sgn(W1)

	;---------------------------------------;
	WBUS<--W[2].XOR.W[6], SET.ALUCC,	; finish comparison of original with
	OLD.Z.AND.NEW.Z				; shifted/reshifted value

	;---------------------------------------;
	W[0]<--0, SET.ALUCC,			; low lw of result is zero, set cc's
	CASE2[ALU.NZVC].AT.[ASHQ.LEFT.0.63.OVERFLOW]	; case on alu.z (clear if overflow)

;	ASHQ left shift cases:	[64,127] yield result of zero.

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

ASHQ.LEFT.64.95:
	;---------------------------------------; 64 <= SC <= 95:
	W[0]<--0,				; shift out of range, result is 0
	GOTO[ASHQ.LEFT.64.127.EXIT]		; go duplicate W1<--W0 and check ovflo

ASHQ.LEFT.96.127:
	;---------------------------------------; 96 <= SC <= 127:
	W[0]<--0,				; shift out of range, result is 0
	GOTO[ASHQ.LEFT.64.127.EXIT]		; go duplicate W1<--W0 and check ovflo

;	ASHQ right shift cases:	[-128,-65] yield sign of source.

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

ASHQ.RIGHT.128.97:
	;---------------------------------------; -128 <= SC <= -97:
	W(6)&, W[1]<--SEXT.W[1].SHFR.[31.],	; shift out of range, result is sign
	GOTO[ASHQ.RIGHT.128.65.EXIT]		; go move W0<--W6 and write result

ASHQ.RIGHT.96.65:
	;---------------------------------------; -96 <= SC <= -65:
	W(6)&, W[1]<--SEXT.W[1].SHFR.[31.],	; shift out of range, result is sign
	GOTO[ASHQ.RIGHT.128.65.EXIT]		; go move W0<--W6 and write result

;	ASHQ right shift cases:	[-64,-33].

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

;	As in ASHL, the ASHQ right shift cases take advantage of the shifter's ability
;	to do a 32-bit shift using the 32-SC option, and its use of only SC<4:0> in
;	calculating the shift value.
;
;	Note that the condition codes can be calculated from the low order result alone:
;	since the shift count is <= -33, bit<31> of the low order result reflects the
;	sign of the quadword, and bits<31:0> the zero test.

ASHQ.RIGHT.64.33:
	;---------------------------------------; -64 <= SC <= -33:
	W(6)&, WBUS<--SEXT.W[1].SHFR.(32-SC)	; shift operand to right, capture result in W6
						; storing in W0 ensures shift range of [-64,-33]

	;---------------------------------------;
	W[1]<--SEXT.W[1].SHFR.[31.],		; W1 gets extended sign
	GOTO[ASHQ.RIGHT.64.33.EXIT]		; go move W0<--W6 and write result 

;	ASHQ right shift cases:	[-32,-1]

;	At this point,
;		W1'W0 = W3'W2 =	source operand
;		alu cc's =	set from W1'W0

ASHQ.RIGHT.32.1:
	;---------------------------------------; -32 <= SC <= -1:
	W(6)&, WBUS<--SEXT.W[1].SHFR.(32-SC)	; shift high order operand to right
						; capture result in W6

	;---------------------------------------;
	SC&, WBUS<--W[1]!!W[0].SHFR.(32-SC),	; shift low order operand to right,
	SET.ALUCC				; capture result in SC
						; start condition code computation

	;---------------------------------------;
	W[1]<--W[6], SET.ALUCC,			; move high order lw into place
	OLD.Z.AND.NEW.Z				; finish alu cc's

;	Here to copy SC to W0 and invoke WDEST.

COPY.SC.TO.W0.WDEST..:
	;---------------------------------------;
	W[0]<--W[SC], 				; move low order lw into place
	JMP.CASE.SPEC[WDEST..]			; go write result

;= END INTLOG
