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