File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / dmp4 / pack_inst.s
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:21 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21


# **************************************************************************
# *
# *		INSTRUCTION CODE PACKING ROUTINE
# *
# *  This routine will take the various parts that make up an instruction and
# *  pack them together into a buffer of code that can be inserted into the
# *  test sequence. 
# *  The instruction may have 0, 1, 2, or 3 operand(s). 
# *  There may be 0, 1, 2, or 4 bytes to each operand address. 
# *  The instruction may be preceded and followed by a pipelined instruction.
# *
# *  The data will be found in the following locations
# *	op_code      :  This is the instruction's op. code
# *	addr_code    :  This is the 1st operand's addressing mode
# *	addr_code2   :  This is the 2nd operand's addressing mode
# *	addr_code3   :  This is the 3rd operand's addressing mode
# *	addr_codeB   :  This is the 2nd addressing mode for indexed addressing
# *	addr_1       :  This is the 1st address specifier
# *	addr_2       :  This is the 2nd address specifier
# *	addr_3       :  This is the 3rd address specifier
# *	pipe_inst1   :  This is the entry instruction for pipelined tests
# *	pipe_inst2   :  This is the exit instruction for pipelined tests
# *	addr_code_p1 :  This is the addressing mode for pipe_inst1
# *	addr_code_p2 :  This is the addressing mode for pipe_inst2
# *  
# *  They will be concatinated to 5 longwords (e.g.):
# *	inst_buf:  <  op-code > < addr_code> < addr_1.a > < addr_1.b >
# * 		   < addr_1.c > < addr_1.d > <addr_code2> < addr_2.a >
# * 		   < addr_2.b > < addr_2.c > < addr_2.d > <addr_code3>
# *                < addr_3.a > < addr_3.b > < addr_3.c > < addr_3.d >
# *                <   "NOP"  > <   "NOP"  > <   "NOP"  > <   "NOP"  >
# * end_of_inst_buf:
# *
# *  or, for indexed adddressing:
# *	inst_buf:  <  op-code > <addr_code > <addr_codeB> < addr_1.b >
# * 		   < addr_1.b > < addr_1.c > < addr_1.d > <addr_code2>
# * 		   <addr_codeB> < addr_2.a > < addr_2.b > < addr_2.c >
# *                < addr_2.d > <  "NOP"   > <  "NOP"   > <  "NOP"   >
# *                <  "NOP"   > <  "NOP"   > <   "NOP"  > <  "NOP"   >
# *
# *  or, for a pipelined test with longword addressing
# *   inst_buf: < pipe_inst1 > <addr_code_p1> <   op_code  > <  addr_code > 
# *		<  addr_1.a  > <  addr_1.b  > <  addr_1.c  > <  addr_1.d  > 
# *		< addr_code2 > <  addr_2.a  > <  addr_2.b  > <  addr_2.c  > 
# *		<  addr_2.d  > < addr_code3 > <  addr_3.a  > <  addr_3.b  > 
# *		<  addr_3.c  > <  addr_3.d  > < pipe_inst2 > <addr_code_p2> 
# *
# ************************************************************************

	.text
	.align 1
	.globl _pack_inst
_pack_inst:
	.word	0
	moval	_inst_buf,_pack_ptr	/* get the buffer address      */
#
# insert the piped entry instruction for pipeline tests
	tstl	_pipe_test
	beql	1f			/* branch if not pipelined     */
	movl	_pipe_inst1,r0		/* get the 1st pipeline instr  */
	movb	r0,*_pack_ptr		/* put it into the buffer      */
	incl	_pack_ptr
	movl	_addr_code_p1,r0	/* get 1st pipeline addr mode  */
	movb	r0,*_pack_ptr		/* put it into the buffer      */
	incl	_pack_ptr
#
# put the test instructions op-code into the buffer
1:	callf	$4,_pack_op_code	/* pack the op-code            */
	tstl	_no_ops			/* are there any operands?     */
	beql	1f			/*   no */
#
# put the 1st addressing data into the buffer
	movl	_addr_code,_pack_code	/* get the 1st addressing mode */
	movl	_addr_1,_pack_offset	/* get the 1st address offset  */
	callf	$4,_pack_addr		/* pack the 1st operand's info */
	cmpl	$1,_no_ops		/* is there only 1 operand?    */
	beql	1f			/*   yes */
#
# put the 2nd addressing data into the buffer
	movl	_addr_code2,_pack_code	/* get the 2nd addressing mode */
	movl	_addr_2,_pack_offset	/* get the 2nd address offset  */
	callf	$4,_pack_addr		/* pack the 2nd operand's info */
	cmpl	$2,_no_ops		/* are there only 2 operands?  */
	beql	1f			/*   yes */
#
# put the 3rd addressing data into the buffer
	movl	_addr_code3,_pack_code	/* get the 3rd addressing mode */
	movl	_addr_3,_pack_offset	/* get the 3rd address offset  */
	callf	$4,_pack_addr		/* pack the 3rd operand's info */
#
# insert the piped exit instruction for pipeline tests
1:	tstl	_pipe_test
	beql	1f			/* branch if not pipelined     */
	movl	_pipe_inst2,r0		/* get the 1st pipeline instr  */
	movb	r0,*_pack_ptr		/* put it into the buffer      */
	incl	_pack_ptr
	movl	_addr_code_p2,r0	/* get 1st pipeline addr mode  */
	movb	r0,*_pack_ptr		/* put it into the buffer      */
	incl	_pack_ptr
#
# fill the rest of the buffer with NOPs
1:	callf	$4,_nop_fill		/* pad the rest with NOPs      */
	ret				/* return */

	.align	2
_pack_ptr:
	.long	0
_pack_code:
	.long	0
_pack_offset:
	.long	0



# **************************************************************************
# *  pack the op-code into the buffer
# **************************************************************************
	.text
	.align 1
	.globl _pack_op_code
_pack_op_code:
	.word	0
	movl	_op_code,r0		/* get the op-code                */
	movl	_pack_ptr,r1		/* get the offset into the buffer */
	movb	r0,(r1)			/* put the op-code in the buffer  */
	incl	_pack_ptr		/* bump the buffer offset         */
	ret				/* return */



# **************************************************************************
# *   pack an addressing mode into the buffer
# **************************************************************************
	.text
	.align 1
	.globl _pack_addr
_pack_addr:
	.word	0
	movl	_pack_code,r0		/* get the current addressing mode   */
	movl	_pack_ptr,r1		/* get the offset into the buffer    */
	movb	r0,(r1)			/* put addressing mode in the buffer */
	incl	r1
	cmpl	r0,$0x40		/* check for indexed addressing */
	blss	1f
	cmpl	r0,$0x4f
	bgtr	1f
	movl	_addr_codeB,r0		/* indexed - put in 2nd addr mode */
	movb	r0,(r1)
	incl	r1
1:
	tstl	_addr_size		/* check # bytes in addr field */
	bneq	1f
	jmp	3f			/*  no address field */
1:
##########################################################################
#  save the address field 
##########################################################################
	movl	_pack_offset,r0		/* get the address field */
	cmpl	_addr_size,$1
	beql	2f			/* jump if 1 byte address field */
	cmpl	_addr_size,$2
	beql	1f			/* jump if 2 byte address field */
	shrl	$24,r0,r2		/* 4 byte field  -get the M.S. byte */
	movb	r2,(r1)			/* put the addr's MSB in the buffer */
	incl	r1
	shrl	$16,r0,r2		/* get the next byte of the field */
	movb	r2,(r1)			/* put the addr's MSW in the buffer */
	incl	r1
1:
	shrl	$8,r0,r2		/* get byte #1 of the field */
	movb	r2,(r1)			
	incl	r1
2:
	movb	r0,(r1)			/* save the L.S. byte of the field */
	incl	r1
3:
	movl	r1,_pack_ptr		/* update the buffer offset */
	ret				/* return */



# **************************************************************************
# *  Now pad the rest of the buffer with NOPs
# **************************************************************************
	.text
	.align 1
	.globl	_nop_fill
_nop_fill:
	.word	0
	movl	_pack_ptr,r1		   /* get the offset to the buffer */
	subl3	$_inst_buf,r1,_inst_size   /* save the instruction's size  */
	movl	$0x10,r0		   /* get a "NOP" instruction  and */
1:	movb	r0,(r1)			   /*   pad the instruction buffer */
	aoblss	$_end_of_inst_buf,r1,1b
	ret				   /* return */


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.