File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / fpevent / pack_inst.s
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:17 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. This routine will assume longword lengths for the operand
*  addresses.
*  The test instruction data will initially be in 5 locations:
*	op_code      : This is the instruction's op. code
*	addr_code    : This is the code for the addressing mode to use
*	addr_code2   : This is the code for the 2nd operand's addressing mode.
*	addr_codeB   : This is the 2nd addressing mode for indexed addressing
*	addr_1       : This is the 1st address operand
*	addr_2       : This is the 2nd address operand
*
*  In addition, the test code may be pipelined with another instruction in
*  front of it. The data for the pipeline instruction will be:
*	pipe_inst1   : This is instruction goes before the test instruction.
*	addr_code_p1 : This is the 1st instruction's addressing mode.
*  
*  The data will be concatinated to 4 longwords:
*	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 > <  "NOP"  >
*                  <  "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"   >
* end_of_inst_buf:
*
*  The instruction may have 0 or 1 operand(s). There may be 0, 1, 2, or 4
*  bytes to each operand address. For a 2 operand instruction with 0 bytes
*  in the operand address fields and not indexed, the buffer would look like:
*	inst_buf:  < op-code > <addr_code> <addr_code> <  "NOP"  >
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* end_of_inst_buf:
*
*
*  If the test is a pipelined test then there will be an extra instruction
*  added at the begining of the buffer. For a 1 operand instruction with
*  register addressing the buffer would look like this:
*	inst_buf:  <pipe_inst> <pipe_addr> < op-code > <addr_code> 
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* 		   <  "NOP"  > <  "NOP"  > <  "NOP"  > <  "NOP"  >
* end_of_inst_buf:
*
*  After the last byte of the instruction the buffer will be padded with NOPs.
*
*  30-May-85  Added pipelined instruction.
*****************************************************************************/

	.text
	.align 1
	.globl _pack_inst
_pack_inst:
	.word 0x4			/* save r4 */
	moval	_inst_buf,r1		/* get the instruction buf's addr */
  
##########################################################################
#  for "pipelined" tests start the code with the PIPE_INST1 instruction 
##########################################################################
	tstl	_pipe_test		/* is the pipe test flag set?   */
	beql	1f			/* skip this section if not     */
	movl	_pipe_inst1,r0		/* get the initial pipeline inst */
	movb	r0,(r1)			/*    and put it in the buffer  */
	incl	r1
	movl	_addr_code_p1,r0	/* get the piped instruction's  */
	movb	r0,(r1)			/*    addressing mode           */
	incl	r1
1:
##########################################################################
#  put the op-code into the buffer
##########################################################################
	movl	_op_code,r0
	movb	r0,(r1)			/* put the op-code in the buffer */
	incl	r1
	tstl	_no_ops			/* get the # of operands */
	bneq	1f
	jmp	4f			/*  ... no operands */
1:
##########################################################################
#  save the 1st addressing mode
##########################################################################
	movl	_addr_code,r0
	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 1st address field 
##########################################################################
	movl	_addr_1,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:
	cmpl	_no_ops,$2		/* check the # of operands */
	bgeq	1f
	jmp	4f			/* only 1 operand */
1:
##########################################################################
#  save the 2nd addressing mode
##########################################################################
	movl	_addr_code2,r0
	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 2nd address field 
##########################################################################
	movl	_addr_2,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:
	cmpl	_no_ops,$3		/* check the # of operands */
	bgeq	1f
	jmp	4f			/* only 2 operands */
1:
##########################################################################
#  save the 3rd addressing mode
##########################################################################
	movl	_addr_code3,r0
	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	4f			/*  no address field */
1:
##########################################################################
#  save the 3rd address field 
##########################################################################
	movl	_addr_3,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
4:
##########################################################################
#  Now pad the rest of the buffer with NOPs
##########################################################################
	subl3	$_inst_buf,r1,_inst_size /* save the size of the instr. */
	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.