|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.