|
|
1.1 root 1: /*
2: * Copyright (c) 1986, 1987 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Mt. Xinu.
7: *
8: * Redistribution is only permitted until one year after the first shipment
9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
10: * binary forms are permitted provided that: (1) source distributions retain
11: * this entire copyright notice and comment, and (2) distributions including
12: * binaries display the following acknowledgement: This product includes
13: * software developed by the University of California, Berkeley and its
14: * contributors'' in the documentation or other materials provided with the
15: * distribution and in all advertising materials mentioning features or use
16: * of this software. Neither the name of the University nor the names of
17: * its contributors may be used to endorse or promote products derived from
18: * this software without specific prior written permission.
19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22: *
23: * @(#)emulate.s 7.5 (Berkeley) 6/28/90
24: */
25:
26: #if VAX630 || VAX650
27: /*
28: * String instruction emulation - MicroVAX only. These routines are called
29: * from locore.s when an "emulate" fault occurs on the MicroVAX. They are
30: * called with the stack set up as follows:
31: *
32: * (sp): Return address of trap handler
33: * 4(sp): Instruction Opcode (also holds PSL result from emulator)
34: * 8(sp): Instruction PC
35: * 12(sp): Operand 1
36: * 16(sp): Operand 2
37: * 20(sp): Operand 3
38: * 24(sp): Operand 4
39: * 28(sp): Operand 5
40: * 32(sp): Operand 6
41: * 36(sp): old Register 11
42: * 40(sp): old Register 10
43: * 44(sp): Return PC
44: * 48(sp): Return PSL
45: * 52(sp): TOS before instruction
46: *
47: * R11 and r10 are available for use. If any routine needs to use r9-r1
48: * they need to save them first (unless those registers are SUPPOSED to be
49: * messed with by the "instruction"). These routines leave their results
50: * in registers 0-5 explicitly, as needed, and use the macros defined below
51: * to link up with calling routine.
52: */
53:
54: #define return rsb
55: #define savepsl movpsl 4(sp)
56: #define setpsl(reg) movl reg,4(sp)
57: #define overflowpsl movl $2,4(sp)
58: #define arg1 12(sp)
59: #define arg2 16(sp)
60: #define arg3 20(sp)
61: #define arg4 24(sp)
62: #define arg5 28(sp)
63: #define arg6 32(sp)
64: #define argub(num,reg) movzbl 8+4*num(sp),reg
65: #define arguw(num,reg) movzwl 8+4*num(sp),reg
66: #define argul(num,reg) movl 8+4*num(sp),reg
67: #define argb(num,reg) cvtbl 8+4*num(sp),reg
68: #define argw(num,reg) cvtwl 8+4*num(sp),reg
69: #define argl(num,reg) movl 8+4*num(sp),reg
70: #define toarg(reg,num) movl reg,8+4*num(sp)
71:
72:
73: .text
74: .align 1
75: .globl _EMcrc
76: _EMcrc:
77: argl(1,r11) # (1) table address == r11
78: argl(2,r0) # (2) initial crc == r0
79: argl(4,r3) # (4) source address == r3
80: arguw(3,r2) # (3) source length == r2
81: jeql Lcrc_out
82: Lcrc_loop:
83: xorb2 (r3)+,r0
84: extzv $0,$4,r0,r10
85: extzv $4,$28,r0,r1
86: xorl3 r1,(r11)[r10],r0
87: extzv $0,$4,r0,r10
88: extzv $4,$28,r0,r1
89: xorl3 r1,(r11)[r10],r0
90: sobgtr r2,Lcrc_loop
91: tstl r0
92: Lcrc_out:
93: savepsl
94: clrl r1
95: return
96:
97:
98: .align 1
99: .globl _EMmovtc
100: _EMmovtc:
101: arguw(1,r0) # (1) source length == r0
102: argl(2,r1) # (2) source address == r1
103: argub(3,r11) # (3) fill character == r11
104: argl(4,r3) # (4) table address == r3
105: argl(6,r5) # (6) destination address == r5
106: arguw(5,r4) # (5) destination length == r4
107: jeql Lmovtc_out
108: Lmovtc_loop:
109: tstl r0
110: jeql Lmovtc_2loop
111: movzbl (r1)+,r2
112: movb (r3)[r2],(r5)+
113: decl r0
114: sobgtr r4,Lmovtc_loop
115: jbr Lmovtc_out
116: Lmovtc_2loop:
117: movb r11,(r5)+
118: sobgtr r4,Lmovtc_2loop
119: Lmovtc_out:
120: cmpl r4,r0
121: savepsl
122: clrl r2
123: return
124:
125:
126: .align 1
127: .globl _EMmovtuc
128: _EMmovtuc:
129: arguw(1,r0) # (1) source length == r0
130: argl(2,r1) # (2) source address == r1
131: argub(3,r11) # (3) escape character == r11
132: argl(4,r3) # (4) table address == r3
133: argl(6,r5) # (6) destination address == r5
134: arguw(5,r4) # (5) destination length == r4
135: jeql Lmovtuc_out
136: Lmovtuc_loop:
137: tstl r0
138: jeql Lmovtuc_out
139: movzbl (r1),r2
140: movzbl (r3)[r2],r2
141: cmpl r2,r11
142: jeql Lmovtuc_out
143: movzbl (r1)+,r2
144: movb (r3)[r2],(r5)+
145: decl r0
146: sobgtr r4,Lmovtuc_loop
147: Lmovtuc_out:
148: cmpl r4,r0
149: savepsl
150: clrl r2
151: return
152:
153:
154: .align 1
155: .globl _EMmatchc
156: _EMmatchc:
157: argl(2,r10) # (2) substring address == r10
158: arguw(3,r2) # (3) source length == r2
159: argl(4,r3) # (4) source address == r3
160: arguw(1,r11) # (1) substring length == r11
161: jeql Lmatchc_out # temp source address == r1
162: addl2 r10,r11 # temp substring address == r0
163: tstl r2
164: jeql Lmatchc_out
165: Lmatchc_loop:
166: cmpb (r10),(r3)
167: jneq Lmatchc_fail
168: movl r3,r1
169: movl r10,r0
170: Lmatchc_2loop:
171: cmpl r0,r11
172: jeql Lmatchc_succ
173: cmpb (r0)+,(r1)+
174: jeql Lmatchc_2loop
175: Lmatchc_fail:
176: incl r3
177: sobgtr r2,Lmatchc_loop
178: movl r10,r1
179: subl3 r10,r11,r0
180: jbr Lmatchc_out
181: Lmatchc_succ:
182: movl r1,r3
183: movl r11,r1
184: clrl r0
185: Lmatchc_out:
186: savepsl
187: return
188:
189:
190: .align 1
191: .globl _EMspanc
192: _EMspanc:
193: argl(2,r1) # (2) string address == r1
194: argub(4,r2) # (4) character-mask == r2
195: argl(3,r3) # (3) table address == r3
196: arguw(1,r0) # (1) string length == r0
197: jeql Lspanc_out
198: Lspanc_loop:
199: movzbl (r1),r11
200: mcomb (r3)[r11],r11
201: bicb3 r11,r2,r11
202: jeql Lspanc_out
203: incl r1
204: sobgtr r0,Lspanc_loop
205: Lspanc_out:
206: savepsl
207: clrl r2
208: return
209:
210:
211: .align 1
212: .globl _EMscanc
213: _EMscanc:
214: argl(2,r1) # (2) string address == r1
215: argub(4,r2) # (4) character-mask == r2
216: argl(3,r3) # (3) table address == r3
217: arguw(1,r0) # (1) string length == r0
218: jeql Lscanc_out
219: Lscanc_loop:
220: movzbl (r1),r11
221: mcomb (r3)[r11],r11
222: bicb3 r11,r2,r11
223: jneq Lscanc_out
224: incl r1
225: sobgtr r0,Lscanc_loop
226: Lscanc_out:
227: savepsl
228: clrl r2
229: return
230:
231:
232: .align 1
233: .globl _EMskpc
234: _EMskpc:
235: argub(1,r11) # (1) character == r11
236: argl(3,r1) # (3) string address == r1
237: arguw(2,r0) # (2) string length == r0
238: jeql Lskpc_out # forget zero length strings
239: Lskpc_loop:
240: cmpb (r1),r11
241: jneq Lskpc_out
242: incl r1
243: sobgtr r0,Lskpc_loop
244: Lskpc_out:
245: tstl r0 # be sure of condition codes
246: savepsl
247: return
248:
249:
250: .align 1
251: .globl _EMlocc
252: _EMlocc:
253: argub(1,r11) # (1) character == r11
254: argl(3,r1) # (3) string address == r1
255: arguw(2,r0) # (2) string length == r0
256: jeql Lskpc_out # forget zero length strings
257: Llocc_loop:
258: cmpb (r1),r11
259: jeql Llocc_out
260: incl r1
261: sobgtr r0,Llocc_loop
262: Llocc_out:
263: tstl r0 # be sure of condition codes
264: savepsl
265: return
266:
267:
268: .align 1
269: .globl _EMcmpc3
270: _EMcmpc3:
271: argl(2,r1) # (2) string1 address == r1
272: argl(3,r3) # (3) string2 address == r3
273: arguw(1,r0) # (1) strings' length == r0
274: jeql Lcmpc3_out
275: Lcmpc3_loop:
276: cmpb (r1),(r3)
277: jneq Lcmpc3_out
278: incl r1
279: incl r3
280: sobgtr r0,Lcmpc3_loop
281: Lcmpc3_out:
282: savepsl
283: movl r0,r2
284: return
285:
286:
287: .align 1
288: .globl _EMcmpc5
289: _EMcmpc5:
290: argl(2,r1) # (2) string1 address == r1
291: argub(3,r11) # (1) fill character == r11
292: arguw(4,r2) # (1) string2 length == r2
293: argl(5,r3) # (3) string2 address == r3
294: arguw(1,r0) # (1) string1 length == r0
295: jeql Lcmpc5_str2
296: Lcmpc5_loop:
297: tstl r2
298: jeql Lcmpc5_str1loop
299: cmpb (r1),(r3)
300: jneq Lcmpc5_out
301: incl r1
302: incl r3
303: decl r2
304: sobgtr r0,Lcmpc5_loop
305: Lcmpc5_str2:
306: tstl r2
307: jeql Lcmpc5_out
308: Lcmpc5_str2loop:
309: cmpb r11,(r3)
310: jneq Lcmpc5_out
311: incl r3
312: sobgtr r2,Lcmpc5_str2loop
313: jbr Lcmpc5_out
314: Lcmpc5_str1loop:
315: cmpb (r1),r11
316: jneq Lcmpc5_out
317: incl r1
318: sobgtr r0,Lcmpc5_str1loop
319: Lcmpc5_out:
320: savepsl
321: return
322:
323:
324: /*
325: * Packed Decimal string operations
326: */
327:
328: #define POSITIVE $12
329: #define NEGATIVE $13
330: #define NEGATIVEalt $11
331:
332:
333: .align 1
334: .globl _EMaddp4
335: _EMaddp4:
336: toarg(r9,6) # save register r9 in arg6 spot
337: arguw(1,r11) # (1) source length == r11
338: argl(2,r10) # (2) source address == r10
339: arguw(3,r9) # (3) destination length == r9
340: argl(4,r3) # (4) destination address == r3
341: # arg4 will be needed later
342: # arg5 holds destination address of LSNibble temporarily
343: ashl $-1,r11,r11
344: addl2 r11,r10 # source address of LSNibble
345: incl r11 # source length is in bytes
346: ashl $-1,r9,r9
347: addl2 r9,r3 # r3 = destination address of LSNibble
348: incl r9 # destination length is in bytes
349: toarg(r3,5) # stored in arg5 spot
350: extzv $0,$4,(r3),r2 # set standard +/- indicators in destination
351: cmpl r2,NEGATIVE
352: jeql L112
353: cmpl r2,NEGATIVEalt
354: jeql L111
355: insv POSITIVE,$0,$4,(r3)
356: jbr L112
357: L111:
358: insv NEGATIVE,$0,$4,(r3)
359: L112:
360: extzv $0,$4,(r10),r2 # r2 = standard +/- of source
361: cmpl r2,NEGATIVE
362: jeql L114
363: cmpl r2,NEGATIVEalt
364: jeql L113
365: movl POSITIVE,r2
366: jbr L114
367: L113:
368: movl NEGATIVE,r2
369: L114:
370: cmpl r11,r9 # if source is longer than destination
371: jleq L115
372: movl r9,r11 # set source length == destination length
373: L115:
374: extzv $4,$4,(r3),r9 # r9 = LSDigit of destination
375: extzv $4,$4,(r10),r1 # r1 = LSDigit of source
376: extzv $0,$4,(r3),r0
377: cmpl r0,r2 # if signs of operands are not equal
378: jeql Laddp4_same # do a subtraction
379: clrl r2 # r2 is non-zero if result is non-zero
380: subl2 r1,r9 # r9 = "addition" of operands' high nibble
381: jbr L119 # jump into addition loop
382: Laddp4_diff_loop:
383: decl r3
384: extzv $0,$4,(r3),r0
385: addl2 r0,r1 # r1 = carry + next (low) nibble of source
386: decl r10
387: extzv $0,$4,(r10),r0
388: subl2 r0,r1 # r1 -= next (low) nibble of destination
389: jgeq L121 # if negative result
390: mnegl $1,r9 # r9 == carry = -1
391: addl2 $10,r1 # r1 == result += 10
392: jbr L122 # else
393: L121:
394: clrl r9 # r9 == carry = 0
395: L122:
396: insv r1,$0,$4,(r3) # store result low nibble
397: bisl2 r1,r2
398: extzv $4,$4,(r3),r0
399: addl2 r0,r9 # r9 = carry + next (high) nibble of source
400: extzv $4,$4,(r10),r0
401: subl2 r0,r9 # r9 -= next (high) nibble of destination
402: L119:
403: jgeq L117 # if negative result
404: mnegl $1,r1 # r1 == carry = -1
405: addl2 $10,r9 # r9 == result += 10
406: jbr L118 # else
407: L117:
408: clrl r1 # r1 == carry = 0
409: L118:
410: insv r9,$4,$4,(r3) # store result high nibble
411: bisl2 r9,r2 # r2 is non-zero if result is non-zero
412: decl r11 # while (--source length)
413: jneq Laddp4_diff_loop
414: argl(4,r10) # r10 = address of destination MSNibble
415: jbr Laddp4_diff_carry
416: Laddp4_diff_carlop:
417: decl r3
418: extzv $0,$4,(r3),r0
419: addl2 r0,r1 # r1 == carry += next (low) nibble
420: jgeq L127 # if less than zero
421: movl r1,r9 # r9 == carry (must be -1)
422: movl $9,r1 # r1 == result = 9
423: jbr L128
424: L127: # else
425: clrl r9 # r9 == carry = 0
426: L128:
427: insv r1,$0,$4,(r3) # store result
428: bisl2 r1,r2
429: extzv $4,$4,(r3),r0
430: addl2 r0,r9 # r9 == carry += next (high) nibble
431: jgeq L129 # if less than zero
432: movl r9,r1 # r1 == carry (must be -1)
433: movl $9,r9 # r9 == result = 9
434: jbr L130
435: L129:
436: clrl r1
437: L130:
438: insv r9,$4,$4,(r3) # store result
439: bisl2 r9,r2
440: Laddp4_diff_carry:
441: cmpl r3,r10
442: jneq Laddp4_diff_carlop
443: tstl r1 # if carry out of MSN then fix up result
444: jeql Laddp4_add_done
445: argl(5,r3) # r3 == address of LSN of destination
446: extzv $0,$4,(r3),r0
447: cmpl r0,NEGATIVE # switch sign of result
448: jneq L132
449: insv POSITIVE,$0,$4,(r3)
450: jbr L133
451: L132:
452: insv NEGATIVE,$0,$4,(r3)
453: L133:
454: extzv $4,$4,(r3),r0 # normalize result (carry out of MSN into LSN)
455: subl3 r0,$10,r9 # r9 = 10 - destination LSNibble
456: jbr L134
457: L137:
458: movl $9,r1
459: Laddp4_diff_norm:
460: insv r9,$4,$4,(r3)
461: cmpl r3,r10 # while (not at MSNibble)
462: jeql Laddp4_add_done
463: decl r3
464: extzv $0,$4,(r3),r0 # low nibble = (9 + carry) - low nibble
465: subl2 r0,r1
466: cmpl r1,$9
467: jleq L135
468: clrl r1
469: movl $10,r9
470: jbr L136
471: L135:
472: movl $9,r9
473: L136:
474: insv r1,$0,$4,(r3)
475: extzv $4,$4,(r3),r0 # high nibble = (9 + carry) - high nibble
476: subl2 r0,r9
477: L134:
478: cmpl r9,$9
479: jleq L137
480: clrl r9
481: movl $10,r1
482: jbr Laddp4_diff_norm
483:
484: Laddp4_same: # operands are of the same sign
485: clrl r2
486: addl2 r1,r9
487: jbr L139
488: Laddp4_same_loop:
489: decl r3
490: extzv $0,$4,(r3),r0
491: addl2 r0,r1 # r1 == carry += next (low) nibble of dest
492: decl r10
493: extzv $0,$4,(r10),r0
494: addl2 r0,r1 # r1 += next (low) nibble of source
495: cmpl r1,$9 # if result > 9
496: jleq L141
497: movl $1,r9 # r9 == carry = 1
498: subl2 $10,r1 # r1 == result -= 10
499: jbr L142
500: L141: # else
501: clrl r9 # r9 == carry = 0
502: L142:
503: insv r1,$0,$4,(r3) # store result
504: bisl2 r1,r2
505: extzv $4,$4,(r10),r0
506: addl2 r0,r9 # ditto for high nibble
507: extzv $4,$4,(r3),r0
508: addl2 r0,r9
509: L139:
510: cmpl r9,$9
511: jleq L143
512: movl $1,r1
513: subl2 $10,r9
514: jbr L144
515: L143:
516: clrl r1
517: L144:
518: insv r9,$4,$4,(r3)
519: bisl2 r9,r2
520: sobgtr r11,Laddp4_same_loop # while (--source length)
521: argl(4,r10) # r10 = destination address of MSNibble
522: jbr Laddp4_same_carry
523: Laddp4_same_cloop:
524: decl r3
525: extzv $0,$4,(r3),r0 # propagate carry up to MSNibble of destination
526: addl2 r0,r1
527: cmpl r1,$10
528: jneq L147
529: movl $1,r9
530: clrl r1
531: jbr L148
532: L147:
533: clrl r9
534: L148:
535: insv r1,$0,$4,(r3)
536: bisl2 r1,r2
537: extzv $4,$4,(r3),r0
538: addl2 r0,r9
539: cmpl r9,$10
540: jneq L149
541: movl $1,r1
542: clrl r9
543: jbr L150
544: L149:
545: clrl r1
546: L150:
547: insv r9,$4,$4,(r3)
548: bisl2 r9,r2
549: Laddp4_same_carry:
550: cmpl r3,r10
551: jneq Laddp4_same_cloop
552:
553: Laddp4_add_done:
554: argl(5,r3) # r3 = destination address of LSNibble
555: tstl r2 # if zero result
556: jneq L151
557: savepsl # remember that for condition codes
558: insv POSITIVE,$0,$4,(r3) # make sure sign of result is positive
559: jbr Laddp4_out
560: L151: # else
561: extzv $0,$4,(r3),r0
562: cmpl r0,NEGATIVE # if result is negative
563: jneq Laddp4_out
564: mnegl r2,r2 # remember THAT in Cond Codes
565: savepsl
566: Laddp4_out:
567: argl(4,r3)
568: argl(2,r1)
569: clrl r0
570: clrl r2
571: argl(6,r9) # restore r9 from stack
572: return
573:
574:
575: .align 1
576: .globl _EMmovp
577: _EMmovp:
578: arguw(1,r11) # (1) string length == r11
579: argl(2,r10) # (1) source address == r10
580: argl(3,r3) # (1) destination address == r3
581: # we will need arg2 and arg3 later
582: clrl r2 # r2 == non-zero if source is non-zero
583: ashl $-1,r11,r11 # length is number of bytes, not nibbles
584: jeql Lmovp_zlen
585: Lmovp_copy:
586: bisb2 (r10),r2 # keep track of non-zero source
587: movb (r10)+,(r3)+ # move two nibbles
588: sobgtr r11,Lmovp_copy # loop for length of source
589: Lmovp_zlen:
590: extzv $4,$4,(r10),r0 # look at least significant nibble
591: bisl2 r0,r2
592: extzv $0,$4,(r10),r0 # check sign nibble
593: cmpl r0,NEGATIVEalt
594: jeql Lmovp_neg
595: cmpl r0,NEGATIVE
596: jneq Lmovp_pos
597: Lmovp_neg: # source was negative
598: mnegl r2,r2
599: Lmovp_pos:
600: tstl r2 # set condition codes
601: savepsl
602: jeql Lmovp_zero
603: movb (r10),(r3) # move last byte if non-zero result
604: jbr Lmovp_out
605: Lmovp_zero:
606: movb POSITIVE,(r3) # otherwise, make result zero and positive
607: Lmovp_out:
608: clrl r0
609: argl(2,r1)
610: clrl r2
611: argl(3,r3)
612: return
613:
614:
615: /*
616: * Definitions for Editpc instruction
617: *
618: * Here are the commands and their corresponding hex values:
619: *
620: * EPend 0x00
621: * EPend_float 0x01
622: * EPclear_signif 0x02
623: * EPset_signif 0x03
624: * EPstore_sign 0x04
625: * EPload_fill 0x40
626: * EPload_sign 0x41
627: * EPload_plus 0x42
628: * EPload_minus 0x43
629: * EPinsert 0x44
630: * EPblank_zero 0x45
631: * EPreplace_sign 0x46
632: * EPadjust_input 0x47
633: * EPfill 0x80
634: * EPmove 0x90
635: * EPfloat 0xa0
636: *
637: *
638: * r4 is carved up as follows:
639: *
640: * -------------------------------------------
641: * | N Z V C |
642: * -------------------------------------------
643: *
644: * fill character is stuffed into arg5 space
645: * sign character is stuffed into arg6 space
646: */
647:
648: #define SIGNIFBIT $0
649: #define setsignif bisl2 $1,r4
650: #define clsignif bicl2 $1,r4
651: #define OVERFLOWBIT $1
652: #define setoverflow bisl2 $2,r4
653: #define cloverflow bicl2 $2,r4
654: #define ZEROBIT $2
655: #define setzero bisl2 $4,r4
656: #define clzero bicl2 $4,r4
657: #define NEGATIVEBIT $3
658: #define setnegative bisl2 $8,r4
659: #define clnegative bicl2 $8,r4
660: #define putfill movb arg5,(r5)+
661: #define setfill(reg) movb reg,arg5
662: #define putsign movb arg6,(r5)+
663: #define setsign(reg) movb reg,arg6
664:
665:
666: .align 1
667: .globl _EMeditpc
668: _EMeditpc:
669: arguw(1,r11) # (1) source length == r11
670: argl(2,r10) # (2) source address == r10
671: argl(3,r3) # (3) pattern address == r3
672: argl(4,r5) # (4) destination address == r5
673: # we will need arg1 and arg2 later
674: # arg5 and arg6 are used for fill and sign - r0 is free
675: setfill($32) # fill character is ' '
676: setsign($32) # sign character is ' '
677: clrl r4 # clear flags
678: ashl $-1,r11,r11 # source length / 2
679: addl3 r11,r10,r2
680: extzv $4,$4,(r2),r1 # r1 == least significant nibble of source
681: L169:
682: cmpl r2,r10
683: jeql L170
684: tstb -(r2) # loop over source packed decimal number
685: jeql L169
686: incl r1 # r1 is non-zero if source is non-zero
687: L170:
688: addl3 r11,r10,r2
689: tstl r1
690: jeql L172 # source is zero - set flags
691: extzv $0,$4,(r2),r11
692: cmpl r11,NEGATIVEalt
693: jeql L9998 # source is negative - set sign and flags
694: cmpl r11,NEGATIVE
695: jneq L175
696: L9998:
697: setnegative
698: setsign($45) # sign character is '-'
699: jbr L175
700: L172:
701: setzero
702: L175:
703: arguw(1,r2) # (1) source length == r2
704: Ledit_case:
705: movzbl (r3)+,r11 # get next edit command (pattern)
706: cmpl r11,$128
707: jlss L180
708: extzv $0,$4,r11,r1 # command has a "count" arg - into r1
709: ashl $-4,r11,r11 # and shift over
710: L180:
711: jbc $6,r11,L181 # "shift" those commands > 64 to 16 and up
712: subl2 $48,r11
713: L181:
714: caseb r11,$0,$0x18 # "do" the command
715: # r11 is available for use, r1 has "count" in it
716: Lcaseb_label:
717: .word Le_end - Lcaseb_label # 00
718: .word Le_end_float - Lcaseb_label # 01
719: .word Le_clear_signif - Lcaseb_label # 02
720: .word Le_set_signif - Lcaseb_label # 03
721: .word Le_store_sign - Lcaseb_label # 04
722: .word Le_end - Lcaseb_label # 05
723: .word Le_end - Lcaseb_label # 06
724: .word Le_end - Lcaseb_label # 07
725: .word Le_fill - Lcaseb_label # 80
726: .word Le_move - Lcaseb_label # 90
727: .word Le_float - Lcaseb_label # a0
728: .word Le_end - Lcaseb_label # b0
729: .word Le_end - Lcaseb_label # c0
730: .word Le_end - Lcaseb_label # d0
731: .word Le_end - Lcaseb_label # e0
732: .word Le_end - Lcaseb_label # f0
733: .word Le_load_fill - Lcaseb_label # 40
734: .word Le_load_sign - Lcaseb_label # 41
735: .word Le_load_plus - Lcaseb_label # 42
736: .word Le_load_minus - Lcaseb_label # 43
737: .word Le_insert - Lcaseb_label # 44
738: .word Le_blank_zero - Lcaseb_label # 45
739: .word Le_replace_sign - Lcaseb_label # 46
740: .word Le_adjust_input - Lcaseb_label # 47
741: Le_end:
742: arguw(1,r0)
743: argl(2,r1)
744: clrl r2
745: decl r3
746: setpsl(r4)
747: clrl r4
748: return
749:
750: Le_end_float:
751: jbs SIGNIFBIT,r4,Ledit_case # if significance not set
752: putsign # drop in the sign
753: # fall into...
754: Le_set_signif:
755: setsignif
756: jbr Ledit_case
757:
758: Le_clear_signif:
759: clsignif
760: jbr Ledit_case
761:
762: Le_store_sign:
763: putsign
764: jbr Ledit_case
765:
766: Le_load_fill:
767: setfill((r3)+)
768: jbr Ledit_case
769:
770: Le_load_plus:
771: jbs NEGATIVEBIT,r4,Lpattern_inc # if non-negative
772: # fall into...
773: Le_load_sign:
774: setsign((r3)+)
775: jbr Ledit_case
776:
777: Le_load_minus:
778: jbs NEGATIVEBIT,r4,Le_load_sign # if negative load the sign
779: incl r3 # else increment pattern
780: jbr Ledit_case
781:
782: Le_insert:
783: jbc SIGNIFBIT,r4,L196 # if significance set, put next byte
784: movb (r3)+,(r5)+
785: jbr Ledit_case
786: L196: # else put in fill character
787: putfill
788: # and throw away character in pattern
789: Le_replace_sign: # we don't do anything with
790: Lpattern_inc: # replace sign `cause we don't
791: incl r3 # get negative zero
792: jbr Ledit_case
793:
794: Le_blank_zero:
795: jbc ZEROBIT,r4,Lpattern_inc # if zero
796: movzbl (r3)+,r11 # next byte is a count
797: jeql Ledit_case
798: subl2 r11,r5 # to back up over output and replace
799: L200:
800: putfill # with fill character
801: sobgtr r11,L200
802: jbr Ledit_case
803:
804: Le_adjust_input:
805: movzbl (r3)+,r0 # get count of nibbles from pattern
806: subl3 r2,r0,r11
807: jgeq Ledit_case # if length of source is > this number
808: L204: # discard digits in source
809: jlbc r2,L206 # use low bit of length to choose nibble
810: bitb $0xf0,(r10) # high nibble
811: jeql L208
812: setsignif # set significance and overflow if
813: setoverflow # wasted digit is non-zero
814: jbr L208
815: L206:
816: bitb $0xf,(r10) # low nibble
817: jeql L209
818: setsignif
819: setoverflow
820: L209:
821: incl r10 # increment to next byte
822: L208:
823: decl r2 # decrement source length
824: incl r11 # continue `till we're out of excess
825: jlss L204
826: jbr Ledit_case
827:
828: Le_fill:
829: tstl r1 # put (count in r1) fill characters
830: jeql Ledit_case
831: Le_fill_loop:
832: putfill
833: sobgtr r1,Le_fill_loop
834: jbr Ledit_case
835:
836: Le_move:
837: tstl r1 # move (count in r1) characters
838: jeql Ledit_case # from source to destination
839: L214:
840: jlbc r2,L215 # read a nibble
841: extzv $4,$4,(r10),r11
842: jbr L216
843: L215:
844: extzv $0,$4,(r10),r11
845: incl r10
846: L216:
847: decl r2 # source length CAN go negative here...
848: tstl r11
849: jeql L218 # if non-zero
850: setsignif # set significance
851: L218:
852: jbc SIGNIFBIT,r4,L219 # if significance set
853: addb3 $48,r11,(r5)+ # put '0' + digit into destination
854: jbr L220
855: L219: # else put fill character
856: putfill
857: L220:
858: sobgtr r1,L214
859: jbr Ledit_case
860:
861: Le_float: # move with floating sign character
862: tstl r1
863: jeql Ledit_case
864: L221:
865: jlbc r2,L222
866: extzv $4,$4,(r10),r11
867: jbr L223
868: L222:
869: extzv $0,$4,(r10),r11
870: incl r10
871: L223:
872: decl r2 # source length CAN go negative here...
873: tstl r11
874: jeql L225
875: jbs SIGNIFBIT,r4,L226
876: putsign
877: L226:
878: setsignif
879: L225:
880: jbc SIGNIFBIT,r4,L227
881: addb3 $48,r11,(r5)+
882: jbr L228
883: L227:
884: putfill
885: L228:
886: sobgtr r1,L221
887: jbr Ledit_case
888:
889:
890: .align 1
891: .globl _EMashp
892: _EMashp:
893: argb(1,r11) # (1) scale (number to shift) == r11
894: arguw(2,r10) # (2) source length == r10
895: argl(3,r1) # (3) source address == r1
896: argub(4,r2) # (4) rounding factor == r2
897: arguw(5,r3) # (5) destination length == r3
898: toarg(r6,3) # arg3 holds register 6 from caller
899: argl(6,r6) # (6) destination address == r6
900: # we need arg6 for later
901: # arg1 is used for temporary storage
902: # arg2 holds "even or odd" destination length
903: # arg4 is used as general storage
904: # arg5 is used as general storage
905: ashl $-1,r3,r0 # destination length is number of bytes
906: addl2 r0,r6 # destination address == least sig nibble
907: toarg(r6,1) # save in arg1 spot for later
908: ashl $-1,r10,r0
909: addl2 r0,r1 # source address == least sig nibble
910: extzv $0,$4,(r1),r0 # determine sign of source
911: cmpl r0,NEGATIVEalt
912: jeql Lashp_neg
913: cmpl r0,NEGATIVE
914: jeql Lashp_neg
915: movb POSITIVE,(r6)
916: jbr L245
917: Lashp_neg:
918: movb NEGATIVE,(r6)
919: L245:
920: clrl arg2 # arg2 is 1 if dstlen is even, 0 if odd
921: blbs r3,L246
922: incl arg2
923: bisl2 $1,r3 # r3<0> counts digits going into destination
924: L246: # and is flip-flop for which nibble to
925: tstl r11 # write in destination (1 = high, 0 = low)
926: jgeq Lashp_left # (it must start out odd)
927: addl2 r11,r10 # scale is negative (right shift)
928: jgeq Lashp_right
929: clrl r10 # test for shifting whole number out
930: jbr Lashp_setround
931: Lashp_right:
932: divl3 $2,r11,r0
933: addl2 r0,r1 # source address == MSNibble to be shifted off
934: jlbc r11,L249
935: extzv $4,$4,(r1),r0
936: addl2 r0,r2 # round = last nibble to be shifted off + round
937: jbr Lashp_setround
938: L249:
939: extzv $0,$4,(r1),r0
940: addl2 r0,r2 # round = last nibble to be shifted off + round
941: Lashp_setround: # r11<0> now is flip-flop for which nibble to
942: incl r11 # read from source (1 == high, 0 == low)
943: cmpl r2,$9 # set rounding factor to one if nibble shifted
944: jleq Lashp_noround # off + round argument was 10 or greater
945: movl $1,r2
946: jbr Lashp_shift
947: Lashp_zloop:
948: jlbs r3,L257 # don't need to clear high nibble twice
949: clrb -(r6) # clear low (and high) nib of next byte in dest
950: L257:
951: sobgtr r3,L258 # move to next nibble in destination, but
952: incl r3 # don't go beyond the end.
953: L258:
954: decl r11
955: Lashp_left: # while scale is positive
956: jneq Lashp_zloop
957: incl r11 # r11<0> is flip-plop ... (incl sets it to one)
958: Lashp_noround:
959: clrl r2 # no more rounding
960: Lashp_shift:
961: clrl arg4 # arg4 will be used for result condition codes
962: tstl r10
963: jeql Lashp_round
964: Lashp_shloop:
965: jlbc r11,L260
966: extzv $4,$4,(r1),r0
967: jbr L261
968: L260:
969: decl r1
970: extzv $0,$4,(r1),r0
971: L261:
972: incl r11 # flip the source nibble flip/flop
973: addl2 r0,r2 # round += next nibble
974: cmpl r2,$10 # if round == 10
975: jneq L262
976: clrl arg5 # then result = 0 and round = 1
977: movl $1,r2
978: jbr L263
979: L262: # else
980: movl r2,arg5 # store result and round = 0
981: clrl r2
982: L263:
983: bisl2 arg5,arg4 # remember if result was nonzero in arg4
984: decl r3 # move to next nibble early to check
985: cmpl r3,arg2 # if we've moved passed destination limits
986: jgeq Lashp_noovfl # test the result for possible overflow
987: movl arg2,r3 # ignore zero nibbles
988: tstl arg5 # if the nibble was non-zero, overflow
989: jeql L265
990: jbr Lashp_overfl
991: Lashp_noovfl: # else
992: jlbs r3,L264
993: insv arg5,$4,$4,(r6) # put the result into destination (high or low)
994: jbr L265
995: L264:
996: movb arg5,-(r6)
997: L265:
998: sobgtr r10,Lashp_shloop # loop for length of source
999:
1000: Lashp_round:
1001: tstl r2 # take care of round out of high nibble
1002: jeql Lashp_zeroround
1003: decl r3
1004: cmpl r3,arg2 # if we've moved passed destination limits
1005: jlss Lashp_overfl # then overflow
1006: jlbs r3,L266
1007: insv arg5,$4,$4,(r6) # put the round into destination (high or low)
1008: jbr Lashp_zeroround
1009: L266:
1010: movb arg5,-(r6)
1011:
1012: Lashp_zeroround:
1013: argl(1,r10) # r10 = address of destination LSNibble
1014: argl(6,r3) # r3 = address of destination MSNibble
1015: movl arg4,r11 # r11 = non-zero if destination == non-zero
1016: savepsl
1017: jbr L267
1018: Lashp_zerofill:
1019: clrb -(r6) # fill up MSNs of destination with zeros
1020: L267:
1021: cmpl r3,r6
1022: jneq Lashp_zerofill
1023: extzv $0,$4,(r10),r0 # test for negative result
1024: cmpl r0,NEGATIVE
1025: jneq Lashp_out
1026: mnegl r11,r11
1027: savepsl
1028: jneq Lashp_out # turn -0 into 0
1029: insv POSITIVE,$0,$4,(r10)
1030: Lashp_out:
1031: clrl r0
1032: argl(3,r6) # restore r6 from stack
1033: return
1034: Lashp_overfl: # do overflow
1035: clrl r2
1036: overflowpsl
1037: jbr Lashp_out
1038:
1039:
1040: .align 1
1041: .globl _EMcvtlp
1042: _EMcvtlp:
1043: arguw(2,r10) # (2) destination length == r10
1044: argl(3,r3) # (3) destination address == r3
1045: ashl $-1,r10,r10
1046: addl2 r10,r3 # destination address points to Least Sig byte
1047: incl r10 # length is # of bytes, not nibbles
1048: argl(1,r11) # (1) source == r11
1049: savepsl
1050: jgeq Lcvtlp_pos
1051: movb NEGATIVE,(r3) # source is negative
1052: divl3 $10,r11,r0
1053: mull3 $10,r0,r1
1054: subl3 r11,r1,r2 # r2 = source mod 10
1055: mnegl r0,r11 # source = -(source / 10)
1056: jbr Lcvtlp_cvt
1057: Lcvtlp_pos:
1058: movb POSITIVE,(r3) # source is non-negative
1059: divl3 $10,r11,r0
1060: mull3 $10,r0,r1
1061: subl3 r1,r11,r2 # r2 = source mod 10
1062: movl r0,r11 # source = source / 10
1063: Lcvtlp_cvt:
1064: insv r2,$4,$4,(r3) # store least significant digit
1065: tstl r11
1066: jeql Lcvtlp_zloop
1067: Lcvtlp_loop: # while source is non-zero
1068: decl r10 # and for length of destination ...
1069: jeql Lcvtlp_over
1070: divl3 $10,r11,r1 # r1 = source / 10
1071: mull3 $10,r1,r0
1072: subl2 r0,r11 # source = source mod 10
1073: movb r11,-(r3) # store low "nibble" in next significant byte
1074: divl3 $10,r1,r11 # source = r1 / 10
1075: mull3 $10,r11,r0
1076: subl2 r0,r1 # r1 = source mod 10
1077: insv r1,$4,$4,(r3) # store high nibble
1078: tstl r11
1079: jneq Lcvtlp_loop # quit if source becomes zero
1080: Lcvtlp_zloop: # fill any remaining bytes with zeros
1081: decl r10
1082: jeql Lcvtlp_out
1083: clrb -(r3)
1084: jbr Lcvtlp_zloop
1085: Lcvtlp_over:
1086: overflowpsl
1087: Lcvtlp_out:
1088: clrl r1 # r0 is already zero
1089: clrl r2
1090: return
1091:
1092:
1093: .align 1
1094: .globl _EMcvtpl
1095: _EMcvtpl:
1096: arguw(1,r11) # (1) source length == r11
1097: argl(2,r10) # (2) source address == r10
1098: clrl r3 # r3 == destination
1099: movl r10,r1 # r1 set up now for return
1100: ashl $-1,r11,r11 # source length is number of bytes
1101: jeql Lcvtpl_zero
1102: Lcvtpl_loop: # for source length
1103: mull2 $10,r3 # destination *= 10
1104: extzv $4,$4,(r10),r0
1105: addl2 r0,r3 # destination += high nibble
1106: mull2 $10,r3 # destination *= 10
1107: extzv $0,$4,(r10),r0
1108: addl2 r0,r3 # destination += low nibble
1109: incl r10
1110: sobgtr r11,Lcvtpl_loop
1111: Lcvtpl_zero: # least significant byte
1112: mull2 $10,r3
1113: extzv $4,$4,(r10),r0
1114: addl2 r0,r3 # dest = 10 * dest + high nibble
1115: savepsl
1116: extzv $0,$4,(r10),r2 # test sign nibble
1117: cmpl r2,NEGATIVE
1118: jeql Lcvtpl_neg
1119: cmpl r2,NEGATIVEalt
1120: jneq Lcvtpl_out
1121: Lcvtpl_neg: # source was negative - negate destination
1122: mnegl r3,r3
1123: savepsl
1124: Lcvtpl_out:
1125: toarg(r3,3)
1126: clrl r0
1127: clrl r2
1128: clrl r3
1129: return
1130:
1131:
1132: .align 1
1133: .globl _EMcvtps
1134: _EMcvtps:
1135: return
1136:
1137:
1138: .align 1
1139: .globl _EMcvtsp
1140: _EMcvtsp:
1141: return
1142:
1143:
1144: .align 1
1145: .globl _EMaddp6
1146: _EMaddp6:
1147: return
1148:
1149:
1150: .align 1
1151: .globl _EMsubp4
1152: _EMsubp4:
1153: return
1154:
1155:
1156: .align 1
1157: .globl _EMsubp6
1158: _EMsubp6:
1159: return
1160:
1161:
1162: .align 1
1163: .globl _EMcvtpt
1164: _EMcvtpt:
1165: return
1166:
1167:
1168: .align 1
1169: .globl _EMmulp
1170: _EMmulp:
1171: return
1172:
1173:
1174: .align 1
1175: .globl _EMcvttp
1176: _EMcvttp:
1177: return
1178:
1179:
1180: .align 1
1181: .globl _EMdivp
1182: _EMdivp:
1183: return
1184:
1185:
1186: .align 1
1187: .globl _EMcmpp3
1188: _EMcmpp3:
1189: return
1190:
1191:
1192: .align 1
1193: .globl _EMcmpp4
1194: _EMcmpp4:
1195: return
1196:
1197:
1198: #endif UVAXII
1199:
1200:
1201: #ifdef notdef
1202: /*
1203: * Emulation OpCode jump table:
1204: * ONLY GOES FROM 0xf8 (-8) TO 0x3B (59)
1205: */
1206: #define EMUTABLE 0x43
1207: #define NOEMULATE .long noemulate
1208: #define EMULATE(a) .long _EM/**/a
1209: .globl _emJUMPtable
1210: _emJUMPtable:
1211: /* f8 */ EMULATE(ashp); EMULATE(cvtlp); NOEMULATE; NOEMULATE
1212: /* fc */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1213: /* 00 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1214: /* 04 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1215: /* 08 */ EMULATE(cvtps); EMULATE(cvtsp); NOEMULATE; EMULATE(crc)
1216: /* 0c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1217: /* 10 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1218: /* 14 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1219: /* 18 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1220: /* 1c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1221: /* 20 */ EMULATE(addp4); EMULATE(addp6); EMULATE(subp4); EMULATE(subp6)
1222: /* 24 */ EMULATE(cvtpt); EMULATE(mulp); EMULATE(cvttp); EMULATE(divp)
1223: /* 28 */ NOEMULATE; EMULATE(cmpc3); EMULATE(scanc); EMULATE(spanc)
1224: /* 2c */ NOEMULATE; EMULATE(cmpc5); EMULATE(movtc); EMULATE(movtuc)
1225: /* 30 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
1226: /* 34 */ EMULATE(movp); EMULATE(cmpp3); EMULATE(cvtpl); EMULATE(cmpp4)
1227: /* 38 */ EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc)
1228:
1229: /*
1230: * The following is called with the stack set up as follows:
1231: *
1232: * (sp): Opcode
1233: * 4(sp): Instruction PC
1234: * 8(sp): Operand 1
1235: * 12(sp): Operand 2
1236: * 16(sp): Operand 3
1237: * 20(sp): Operand 4
1238: * 24(sp): Operand 5
1239: * 28(sp): Operand 6
1240: * 32(sp): Operand 7 (unused)
1241: * 36(sp): Operand 8 (unused)
1242: * 40(sp): Return PC
1243: * 44(sp): Return PSL
1244: * 48(sp): TOS before instruction
1245: *
1246: * Each individual routine is called with the stack set up as follows:
1247: *
1248: * (sp): Return address of trap handler
1249: * 4(sp): Opcode (will get return PSL)
1250: * 8(sp): Instruction PC
1251: * 12(sp): Operand 1
1252: * 16(sp): Operand 2
1253: * 20(sp): Operand 3
1254: * 24(sp): Operand 4
1255: * 28(sp): Operand 5
1256: * 32(sp): Operand 6
1257: * 36(sp): saved register 11
1258: * 40(sp): saved register 10
1259: * 44(sp): Return PC
1260: * 48(sp): Return PSL
1261: * 52(sp): TOS before instruction
1262: */
1263:
1264: SCBVEC(emulate):
1265: movl r11,32(sp) # save register r11 in unused operand
1266: movl r10,36(sp) # save register r10 in unused operand
1267: cvtbl (sp),r10 # get opcode
1268: addl2 $8,r10 # shift negative opcodes
1269: subl3 r10,$EMUTABLE,r11 # forget it if opcode is out of range
1270: bcs noemulate
1271: movl _emJUMPtable[r10],r10 # call appropriate emulation routine
1272: jsb (r10) # routines put return values into regs 0-5
1273: movl 32(sp),r11 # restore register r11
1274: movl 36(sp),r10 # restore register r10
1275: insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot
1276: addl2 $40,sp # adjust stack for return
1277: rei
1278: noemulate:
1279: addl2 $48,sp # adjust stack for
1280: .word 0xffff # "reserved instruction fault"
1281: SCBVEC(emulateFPD):
1282: .word 0xffff # "reserved instruction fault"
1283: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.