|
|
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. This routine will assume longword lengths for the operand
9: * addresses.
10: * The test instruction data will initially be in 5 locations:
11: * op_code : This is the instruction's op. code
12: * addr_code : This is the code for the addressing mode to use
13: * addr_code2 : This is the code for the 2nd operand's addressing mode.
14: * addr_codeB : This is the 2nd addressing mode for indexed addressing
15: * addr_1 : This is the 1st address operand
16: * addr_2 : This is the 2nd address operand
17: *
18: * In addition, the test code may be pipelined with another instruction in
19: * front of it. The data for the pipeline instruction will be:
20: * pipe_inst1 : This is instruction goes before the test instruction.
21: * addr_code_p1 : This is the 1st instruction's addressing mode.
22: *
23: * The data will be concatinated to 4 longwords:
24: * inst_buf: < op-code > <addr_code> < addr_1.a > <addr_1.b >
25: * <addr_1.c > <addr_1.d > <addr_code2> <addr_2.a >
26: * <addr_2.b > <addr_2.c > < addr_2.d > < "NOP" >
27: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
28: * end_of_inst_buf:
29: *
30: * or, for indexed adddressing:
31: * inst_buf: < op-code > <addr_code > <addr_codeB> < addr_1.b >
32: * < addr_1.b > < addr_1.c > < addr_1.d > <addr_code2>
33: * <addr_codeB> < addr_2.a > < addr_2.b > < addr_2.c >
34: * < addr_2.d > < "NOP" > < "NOP" > < "NOP" >
35: * end_of_inst_buf:
36: *
37: * The instruction may have 0 or 1 operand(s). There may be 0, 1, 2, or 4
38: * bytes to each operand address. For a 2 operand instruction with 0 bytes
39: * in the operand address fields and not indexed, the buffer would look like:
40: * inst_buf: < op-code > <addr_code> <addr_code> < "NOP" >
41: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
42: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
43: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
44: * end_of_inst_buf:
45: *
46: *
47: * If the test is a pipelined test then there will be an extra instruction
48: * added at the begining of the buffer. For a 1 operand instruction with
49: * register addressing the buffer would look like this:
50: * inst_buf: <pipe_inst> <pipe_addr> < op-code > <addr_code>
51: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
52: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
53: * < "NOP" > < "NOP" > < "NOP" > < "NOP" >
54: * end_of_inst_buf:
55: *
56: * After the last byte of the instruction the buffer will be padded with NOPs.
57: *
58: * 30-May-85 Added pipelined instruction.
59: *****************************************************************************/
60:
61: .text
62: .align 1
63: .globl _pack_inst
64: _pack_inst:
65: .word 0x4 /* save r4 */
66: moval _inst_buf,r1 /* get the instruction buf's addr */
67:
68: ##########################################################################
69: # for "pipelined" tests start the code with the PIPE_INST1 instruction
70: ##########################################################################
71: tstl _pipe_test /* is the pipe test flag set? */
72: beql 1f /* skip this section if not */
73: movl _pipe_inst1,r0 /* get the initial pipeline inst */
74: movb r0,(r1) /* and put it in the buffer */
75: incl r1
76: movl _addr_code_p1,r0 /* get the piped instruction's */
77: movb r0,(r1) /* addressing mode */
78: incl r1
79: 1:
80: ##########################################################################
81: # put the op-code into the buffer
82: ##########################################################################
83: movl _op_code,r0
84: movb r0,(r1) /* put the op-code in the buffer */
85: incl r1
86: tstl _no_ops /* get the # of operands */
87: bneq 1f
88: jmp 4f /* ... no operands */
89: 1:
90: ##########################################################################
91: # save the 1st addressing mode
92: ##########################################################################
93: movl _addr_code,r0
94: movb r0,(r1) /* put addressing mode in the buffer */
95: incl r1
96: cmpl r0,$0x40 /* check for indexed addressing */
97: blss 1f
98: cmpl r0,$0x4f
99: bgtr 1f
100: movl _addr_codeB,r0 /* indexed - put in 2nd addr mode */
101: movb r0,(r1)
102: incl r1
103: 1:
104: tstl _addr_size /* check # bytes in addr field */
105: bneq 1f
106: jmp 3f /* no address field */
107: 1:
108: ##########################################################################
109: # save the 1st address field
110: ##########################################################################
111: movl _addr_1,r0 /* get the address field */
112: cmpl _addr_size,$1
113: beql 2f /* jump if 1 byte address field */
114: cmpl _addr_size,$2
115: beql 1f /* jump if 2 byte address field */
116: shrl $24,r0,r2 /* 4 byte field -get the M.S. byte */
117: movb r2,(r1) /* put the addr's MSB in the buffer */
118: incl r1
119: shrl $16,r0,r2 /* get the next byte of the field */
120: movb r2,(r1) /* put the addr's MSW in the buffer */
121: incl r1
122: 1:
123: shrl $8,r0,r2 /* get byte #1 of the field */
124: movb r2,(r1)
125: incl r1
126: 2:
127: movb r0,(r1) /* save the L.S. byte of the field */
128: incl r1
129: 3:
130: cmpl _no_ops,$2 /* check the # of operands */
131: bgeq 1f
132: jmp 4f /* only 1 operand */
133: 1:
134: ##########################################################################
135: # save the 2nd addressing mode
136: ##########################################################################
137: movl _addr_code2,r0
138: movb r0,(r1) /* put addressing mode in the buffer */
139: incl r1
140: cmpl r0,$0x40 /* check for indexed addressing */
141: blss 1f
142: cmpl r0,$0x4f
143: bgtr 1f
144: movl _addr_codeB,r0 /* indexed - put in 2nd addr mode */
145: movb r0,(r1)
146: incl r1
147: 1:
148: tstl _addr_size /* check # bytes in addr field */
149: bneq 1f
150: jmp 3f /* no address field */
151: 1:
152: ##########################################################################
153: # save the 2nd address field
154: ##########################################################################
155: movl _addr_2,r0 /* get the address field */
156: cmpl _addr_size,$1
157: beql 2f /* jump if 1 byte address field */
158: cmpl _addr_size,$2
159: beql 1f /* jump if 2 byte address field */
160: shrl $24,r0,r2 /* 4 byte field -get the M.S. byte */
161: movb r2,(r1) /* put the addr's MSB in the buffer */
162: incl r1
163: shrl $16,r0,r2 /* get the next byte of the field */
164: movb r2,(r1) /* put the addr's MSW in the buffer */
165: incl r1
166: 1:
167: shrl $8,r0,r2 /* get byte #1 of the field */
168: movb r2,(r1)
169: incl r1
170: 2:
171: movb r0,(r1) /* save the L.S. byte of the field */
172: incl r1
173: 3:
174: cmpl _no_ops,$3 /* check the # of operands */
175: bgeq 1f
176: jmp 4f /* only 2 operands */
177: 1:
178: ##########################################################################
179: # save the 3rd addressing mode
180: ##########################################################################
181: movl _addr_code3,r0
182: movb r0,(r1) /* put addressing mode in the buffer */
183: incl r1
184: cmpl r0,$0x40 /* check for indexed addressing */
185: blss 1f
186: cmpl r0,$0x4f
187: bgtr 1f
188: movl _addr_codeB,r0 /* indexed - put in 2nd addr mode */
189: movb r0,(r1)
190: incl r1
191: 1:
192: tstl _addr_size /* check # bytes in addr field */
193: bneq 1f
194: jmp 4f /* no address field */
195: 1:
196: ##########################################################################
197: # save the 3rd address field
198: ##########################################################################
199: movl _addr_3,r0 /* get the address field */
200: cmpl _addr_size,$1
201: beql 2f /* jump if 1 byte address field */
202: cmpl _addr_size,$2
203: beql 1f /* jump if 2 byte address field */
204: shrl $24,r0,r2 /* 4 byte field -get the M.S. byte */
205: movb r2,(r1) /* put the addr's MSB in the buffer */
206: incl r1
207: shrl $16,r0,r2 /* get the next byte of the field */
208: movb r2,(r1) /* put the addr's MSW in the buffer */
209: incl r1
210: 1:
211: shrl $8,r0,r2 /* get byte #1 of the field */
212: movb r2,(r1)
213: incl r1
214: 2:
215: movb r0,(r1) /* save the L.S. byte of the field */
216: incl r1
217: 4:
218: ##########################################################################
219: # Now pad the rest of the buffer with NOPs
220: ##########################################################################
221: subl3 $_inst_buf,r1,_inst_size /* save the size of the instr. */
222: movl $0x10,r0 /* get a "NOP" instruction and */
223: 1: movb r0,(r1) /* pad the instruction buffer */
224: aoblss $_end_of_inst_buf,r1,1b
225: ret /* return */
226:
227:
228:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.