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