|
|
1.1 root 1:
2: # **************************************************************************
3: # *
4: # * INSTRUCTION CODE PACKING ROUTINE
5: # *
6: # * This routine will take the various parts that make up an instruction and
7: # * pack them together into a buffer of code that can be inserted into the
8: # * test sequence.
9: # * The instruction may have 0, 1, 2, or 3 operand(s).
10: # * There may be 0, 1, 2, or 4 bytes to each operand address.
11: # * The instruction may be preceded and followed by a pipelined instruction.
12: # *
13: # * The data will be found in the following locations
14: # * op_code : This is the instruction's op. code
15: # * addr_code : This is the 1st operand's addressing mode
16: # * addr_code2 : This is the 2nd operand's addressing mode
17: # * addr_code3 : This is the 3rd operand's addressing mode
18: # * addr_codeB : This is the 2nd addressing mode for indexed addressing
19: # * addr_1 : This is the 1st address specifier
20: # * addr_2 : This is the 2nd address specifier
21: # * addr_3 : This is the 3rd address specifier
22: # * pipe_inst1 : This is the entry instruction for pipelined tests
23: # * pipe_inst2 : This is the exit instruction for pipelined tests
24: # * addr_code_p1 : This is the addressing mode for pipe_inst1
25: # * addr_code_p2 : This is the addressing mode for pipe_inst2
26: # *
27: # * They will be concatinated to 5 longwords (e.g.):
28: # * inst_buf: < op-code > < addr_code> < addr_1.a > < addr_1.b >
29: # * < addr_1.c > < addr_1.d > <addr_code2> < addr_2.a >
30: # * < addr_2.b > < addr_2.c > < addr_2.d > <addr_code3>
31: # * < addr_3.a > < addr_3.b > < addr_3.c > < addr_3.d >
32: # * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
33: # * end_of_inst_buf:
34: # *
35: # * or, for indexed adddressing:
36: # * inst_buf: < op-code > <addr_code > <addr_codeB> < addr_1.b >
37: # * < addr_1.b > < addr_1.c > < addr_1.d > <addr_code2>
38: # * <addr_codeB> < addr_2.a > < addr_2.b > < addr_2.c >
39: # * < addr_2.d > < "NOP" > < "NOP" > < "NOP" >
40: # * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
41: # *
42: # * or, for a pipelined test with longword addressing
43: # * inst_buf: < pipe_inst1 > <addr_code_p1> < op_code > < addr_code >
44: # * < addr_1.a > < addr_1.b > < addr_1.c > < addr_1.d >
45: # * < addr_code2 > < addr_2.a > < addr_2.b > < addr_2.c >
46: # * < addr_2.d > < addr_code3 > < addr_3.a > < addr_3.b >
47: # * < addr_3.c > < addr_3.d > < pipe_inst2 > <addr_code_p2>
48: # *
49: # ************************************************************************
50:
51: .text
52: .align 1
53: .globl _pack_inst
54: _pack_inst:
55: .word 0
56: moval _inst_buf,_pack_ptr /* get the buffer address */
57: #
58: # insert the piped entry instruction for pipeline tests
59: tstl _pipe_test
60: beql 1f /* branch if not pipelined */
61: movl _pipe_inst1,r0 /* get the 1st pipeline instr */
62: movb r0,*_pack_ptr /* put it into the buffer */
63: incl _pack_ptr
64: movl _addr_code_p1,r0 /* get 1st pipeline addr mode */
65: movb r0,*_pack_ptr /* put it into the buffer */
66: incl _pack_ptr
67: #
68: # put the test instructions op-code into the buffer
69: 1: callf $4,_pack_op_code /* pack the op-code */
70: tstl _no_ops /* are there any operands? */
71: beql 1f /* no */
72: #
73: # put the 1st addressing data into the buffer
74: movl _addr_code,_pack_code /* get the 1st addressing mode */
75: movl _addr_1,_pack_offset /* get the 1st address offset */
76: callf $4,_pack_addr /* pack the 1st operand's info */
77: cmpl $1,_no_ops /* is there only 1 operand? */
78: beql 1f /* yes */
79: #
80: # put the 2nd addressing data into the buffer
81: movl _addr_code2,_pack_code /* get the 2nd addressing mode */
82: movl _addr_2,_pack_offset /* get the 2nd address offset */
83: callf $4,_pack_addr /* pack the 2nd operand's info */
84: cmpl $2,_no_ops /* are there only 2 operands? */
85: beql 1f /* yes */
86: #
87: # put the 3rd addressing data into the buffer
88: movl _addr_code3,_pack_code /* get the 3rd addressing mode */
89: movl _addr_3,_pack_offset /* get the 3rd address offset */
90: callf $4,_pack_addr /* pack the 3rd operand's info */
91: #
92: # insert the piped exit instruction for pipeline tests
93: 1: tstl _pipe_test
94: beql 1f /* branch if not pipelined */
95: movl _pipe_inst2,r0 /* get the 1st pipeline instr */
96: movb r0,*_pack_ptr /* put it into the buffer */
97: incl _pack_ptr
98: movl _addr_code_p2,r0 /* get 1st pipeline addr mode */
99: movb r0,*_pack_ptr /* put it into the buffer */
100: incl _pack_ptr
101: #
102: # fill the rest of the buffer with NOPs
103: 1: callf $4,_nop_fill /* pad the rest with NOPs */
104: ret /* return */
105:
106: .align 2
107: _pack_ptr:
108: .long 0
109: _pack_code:
110: .long 0
111: _pack_offset:
112: .long 0
113:
114:
115:
116: # **************************************************************************
117: # * pack the op-code into the buffer
118: # **************************************************************************
119: .text
120: .align 1
121: .globl _pack_op_code
122: _pack_op_code:
123: .word 0
124: movl _op_code,r0 /* get the op-code */
125: movl _pack_ptr,r1 /* get the offset into the buffer */
126: movb r0,(r1) /* put the op-code in the buffer */
127: incl _pack_ptr /* bump the buffer offset */
128: ret /* return */
129:
130:
131:
132: # **************************************************************************
133: # * pack an addressing mode into the buffer
134: # **************************************************************************
135: .text
136: .align 1
137: .globl _pack_addr
138: _pack_addr:
139: .word 0
140: movl _pack_code,r0 /* get the current addressing mode */
141: movl _pack_ptr,r1 /* get the offset into the buffer */
142: movb r0,(r1) /* put addressing mode in the buffer */
143: incl r1
144: cmpl r0,$0x40 /* check for indexed addressing */
145: blss 1f
146: cmpl r0,$0x4f
147: bgtr 1f
148: movl _addr_codeB,r0 /* indexed - put in 2nd addr mode */
149: movb r0,(r1)
150: incl r1
151: 1:
152: tstl _addr_size /* check # bytes in addr field */
153: bneq 1f
154: jmp 3f /* no address field */
155: 1:
156: ##########################################################################
157: # save the address field
158: ##########################################################################
159: movl _pack_offset,r0 /* get the address field */
160: cmpl _addr_size,$1
161: beql 2f /* jump if 1 byte address field */
162: cmpl _addr_size,$2
163: beql 1f /* jump if 2 byte address field */
164: shrl $24,r0,r2 /* 4 byte field -get the M.S. byte */
165: movb r2,(r1) /* put the addr's MSB in the buffer */
166: incl r1
167: shrl $16,r0,r2 /* get the next byte of the field */
168: movb r2,(r1) /* put the addr's MSW in the buffer */
169: incl r1
170: 1:
171: shrl $8,r0,r2 /* get byte #1 of the field */
172: movb r2,(r1)
173: incl r1
174: 2:
175: movb r0,(r1) /* save the L.S. byte of the field */
176: incl r1
177: 3:
178: movl r1,_pack_ptr /* update the buffer offset */
179: ret /* return */
180:
181:
182:
183: # **************************************************************************
184: # * Now pad the rest of the buffer with NOPs
185: # **************************************************************************
186: .text
187: .align 1
188: .globl _nop_fill
189: _nop_fill:
190: .word 0
191: movl _pack_ptr,r1 /* get the offset to the buffer */
192: subl3 $_inst_buf,r1,_inst_size /* save the instruction's size */
193: movl $0x10,r0 /* get a "NOP" instruction and */
194: 1: movb r0,(r1) /* pad the instruction buffer */
195: aoblss $_end_of_inst_buf,r1,1b
196: ret /* return */
197:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.