2 / (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 / See the copyright notice in the ACK home directory, in the file "Copyright".
4 /------------------------------------------------------------------------------
6 / This is an interpreter for EM programs with no virtual memory
7 / which is adapted from an EM1 interpreter by Hans van Staveren
14 / interpreter em-text pd global tables heap unused stack
15 / __________________________________________________________________
18 / | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8|
20 / |____________|_______|____|_______|_______|_____|______|______|__|
22 / 1: Interpreter text+data+bss
24 / 3: EM procedure descriptors
25 / 4: EM global data area
26 / 5: flow, count and profile tables
28 / 7: EM local data and stack
29 / 8: Arguments to interpreter
31 / Assembly time flags:
32 / .test : controls checking for undefined variables,nil pointers,
33 / array indices, etc....
34 / .prof : controls generation of a runtime profile
35 / .opfreq: controls runtime frequency count per opcode
36 / .flow : controls generation of a flow bitmap
37 / .count : controls generation of a flow count
38 / .last : controls generation of file with last 16
39 / consecutive blocks of lines executed
42 / pcx = EM programcounter
43 / lb = EM base-address
44 / nxt = address of start of interpreter loop
46 / The general structure of this interpreter is as follows:
47 / The opcode byte of the instruction is placed in r0
48 / with sign-extension and multiplied by 2.
49 / If .opfreq is nonzero each occurence of each opcode is counted.
50 / Then, if .prof is nonzero an estimation of the time required
51 / to execute the instruction is added to a counter associated
52 / with the source-line number. This estimation is roughly the
53 / number of memory-cycles needed. At the end of this accounting
54 / loprof points to the loword of the double precision counter.
55 / This can be used by individual execution routines to add some
56 / more to the counter depending on their operand.
58 / NOTE: This interpreter can be loaded in separate I and D space
61 /------------------------------------------------------------------------------
62 / Declaring of some constants
63 /------------------------------------------------------------------------------
71 unixextra= 1280. / extra memory asked by heap overflow
72 und = 100000 / undefined memory pattern
73 signext = 177400 / high bits for signextension
74 EINVAL = 22. / UNIX error code for bad signal
84 /------------------------------------------------------------------------------
85 / EM1 machine errors (in the range 0-63)
86 /------------------------------------------------------------------------------
112 /------------------------------------------------------------------------------
113 / Declaring of some instructions unknown to the assembler
114 /------------------------------------------------------------------------------
116 next = 10407 / = mov nxt,pc; jump to decode loop
117 rti = 2 / return from interrupt
118 iot = 4 / force core dump
119 stst = 170300^tst / store floating point status
120 indir = 0 / for sys indir
134 /------------------------------------------------------------------------------
135 / External references
136 /------------------------------------------------------------------------------
141 /------------------------------------------------------------------------------
142 / Now the real program starts
143 /------------------------------------------------------------------------------
149 add $2,filb / pointer to argv in filb for error message
151 mov (r0)+,argc / pass to userprogram later
152 bgt 0f / go for argument
153 mov $emfile,forward+2 / e.out is load file default
157 tst (r0)+ / skip interpreter name
158 mov r0,argv / pass to userprogram later
159 mov (r0),forward+2 / argv filename to open call
162 tst (r0)+ / increment r0 look for last arg
168 forward: sys open;0;0
173 mov r0,saver0 / save filedescriptor
174 mov r0,r5 / duplicate filedescriptor
175 sys read;header;16. / skip first header
177 mov r5,r0 / recall fildes
178 sys read;header;16. / read second header
180 cmp r0,$16. / long enough ?
182 mov $_end,r0 / Bottom em-text
183 mov r0,pb / program base
184 add txtsiz,r0 / reserve space for text
185 mov r0,pd / set up proc.descr base
186 mov nprocs, r3 / number of procs
187 ash $2,r3 / proc. descr is 4 bytes
188 .if .count +.prof + .flow
189 mul $3,r3 / or 12 bytes
191 add r3,r0 / reserve space
192 mov r0,hp / top of pd space, temporarily in hp
193 mov r0,r3 / base for data fill
195 mov $retsize,eb / address of value containing 0, temporarily
196 add szdata,r0 / size of external data
197 jcs toolarge / too much text and data
198 mov r0,globmax / maximum global
199 add $1280.,r0 / bit extra core for setup
200 mov r0,sybreak+2 / set up for core claim
201 sys indir;sybreak / ask for the core
202 jes toolarge / too much, sorry
204 mov hp,eb / top of pd space
205 mov txtsiz,leescal+4 / set up for text read
206 mov pb,leescal+2 / start address text read
207 mov r5,r0 / file descriptor input
208 sys indir;leescal / read!!
211 1: sys read;0;0 / read call
216 / hier is nu dus de tekst ingelezen. De sybreak voor de
217 / tabellen en de data moet opnieuw gebeuren.
231 sys signal;8.;sig8 / catch floating exception
233 movf $50200,fr3 / load 2^32 in fr3 for conversion
238 sys signal;11.;sig11 / catch segmentation violation
239 sys signal;12.;sig12 / catch bad system calls
241 / We make a 1024 buffer for reading in
242 / data descriptors. When the number of
243 / bytes in the buffer is less than 512
244 / we read another block. Descriptors of
245 / more than 512 bytes are not allowed.
246 / This is no restriction since they do
247 / not fit in the descriptor format.
250 sub $02000,sp / new buffer bottom
251 tst (sp) / ask for core
252 mov sp,r4 / pointer in descriptor
253 mov saver0,r0 / recall fildes
254 clr r1 / clear registers for byte
255 clr r2 / format instruction and data
257 mov r5,leescal+2 / set up for read
258 mov $02000,leescal+4 / idem
259 sys indir;leescal / read
260 jes badarg / read failed
261 cmp $02000,r0 / not yet eof?
262 bgt 0f / eof encountered
264 add $01000,r5 / buffer middle
265 mov r5,saver1 / save buffermiddle to compare
266 br datloop / start data initialization
267 0: add r0,r5 / now pointer at top of file
268 mov r5,saver1 / still set up for compare
274 cmp r4,saver1 / descriptor over middle?
275 blt 9f / no? go ahead
276 jsr pc,blshift / yes? shift block down, read next
278 9: dec ndatad / still data to initialize?
279 blt finito / no? go on
280 movb (r4)+,r1 / opcode descriptor
281 beq 0f / if 0 then go there
282 mov r3,r5 / copy data pointer
283 clr r2 / unsigned integer byte
284 bisb (r4)+,r2 / "ored" in for data size
285 asl r1 / make opcode even
286 mov datswi(r1),pc / main data swich
289 datswi: 0; dat1; dat2; dat3; dat4; dat5; dat6; dat6; dofloat
291 dat3: asl r2 / multiply with 2
292 dat2: 2: movb (r4)+,(r3)+ / copy byte from buffer to data
293 sob r2,2b / until r2 is 0
294 br datloop / next datadescriptor
297 dat4: mov eb,r0 / external base should be added
298 br 2f / for data pointers
300 dat5: mov pb,r0 / and program base for procedures
302 2: movb (r4)+,(r3) / move in first byte of pointer
303 movb (r4)+,1(r3) / move in second byte of pointer
304 add r0,(r3)+ / add pointer base
305 sob r2,2b / jump back if there is more
306 br datloop / next data descriptor
308 dat1: mov $und,(r3)+ / reserve words with undefineds
309 sob r2,dat1 / jump back if more
310 br datloop / next data descriptor
312 0: mov r3,r1 / copy data pointer (odd register)
313 sub r5,r1 / subtract previous pointer
314 movb (r4)+,(r3) / copy first byte of operand
315 movb (r4)+,1(r3) / copy second byte
316 mul (r3),r1 / the number of bytes to copy
317 1: movb (r5)+,(r3)+ / is the product of the operand
318 sob r1,1b / and the number of bytes in the
319 br datloop / previous operation
321 dat6: add r2,r3 / new data pointer, the old is
322 mov r3,r0 / still in r5
324 beq 6f / case 1 byte is special
325 sub $2,r0 / this is the least significant
326 / byte in PDP11-standard
327 2: movb (r4)+,(r0)+ / copy low byte
328 movb (r4)+,(r0) / copy high byte
329 sub $3,r0 / next lowest byte
330 sob r2,2b / jump if not ready
331 br datloop / next descriptor
332 6: movb (r4)+,(r5) / copy one byte
333 br datloop / next descriptor
336 mov saver1,r1 / bottom of top half
337 mov r1,r2 / set up bottom
339 mov $1000,r0 / number to copy
340 mov r0,leescal+4 / amount to read
341 sub r0,r4 / decrease pointer
342 asr r0 / 512 bytes is 256 words
343 3: mov (r1)+,(r2)+ / copy top half in bottom half
345 mov saver1,leescal+2 / set up for read
347 mov saver0,r0 / filedescriptor
350 clr r1 / clear registers which contain
351 clr r2 / descriptor bytes later
352 cmp $01000,r0 / look if eof is encountered
354 add r0,saver1 / no extra read necessary
358 cmp globmax,r3 / test if data size ok
359 jne badarg / load file error
364 mov nprocs,r5 / set up for procdesc read
365 mov pd,r3 / proc descriptor base
366 asl r5 / multiply with 4 because
367 asl r5 / procdes is 4 bytes
368 1: mov saver1,r1 / look what is available
369 sub r4,r1 / in buffer to be read
370 add $3,r1 / let it be a multiple
372 sub r1,r5 / subtract what can be read
373 asr r1; asr r1; / divide by four
375 movb (r4)+,(r3)+ / copy byte
376 movb (r4)+,(r3)+ / copy byte
377 movb (r4)+,(r3)+ / copy byte
378 movb (r4)+,(r3)+ / copy byte
379 add pb,-2(r3) / change em-address in pdp-address
380 .if .count + .prof + .flow
386 sob r1,0b / look if there is more
387 tst r5 / is there still a descriptor
389 jsr pc,blshift / yes? read again
393 cmp eb,r3 / test if procdes is ok
394 jne badarg / load file error
395 mov saver0,r0 / fildes in r0
396 sys close / close input load file
397 mov ml,sp / fresh stack
399 .if .flow + .count + .prof
400 / |==================|
401 / Here we fill the fields in the procedure | bytes for locals |
402 / descriptor with table information. The |------------------|
403 / procedure descriptor has six fields, | start address |
404 / like described in this picture. We |------------------|
405 / construct a linked list of the proc. | count pointer |
406 / descriptors, such that the defined |------------------|
407 / order of procedures is compatible | first line nr |
408 / with the text order. Thereafter we |------------------|
409 / scan the text for line information to | link next proc |
410 / fill the countpointer and startline |------------------|
411 / field. The link to the first proc. | current file name|
412 / is in firstp, links are descriptor |==================|
413 / start addresses. The last procedure
414 / links to the external base. All lines in the text get a count
415 / number, lines of a procedure get consecutive count numbers,
416 / the procedure count pointer gives the number of the first line.
417 / Count pointer zero is reserved for the case that no line number
421 mov pd,r0 / first descriptor
422 mov r0,r3 / points to first proc
423 mov r0,r4 / pd in register
424 mov eb,r5 / eb in register
426 0: mov r0,r1 / copy old descriptor bottom
427 add $12.,r0 / next descriptor
428 cmp r0,r5 / top of descriptor space
429 bhis 4f / ready? continue
430 1: cmp 2(r0),2(r1) / compare start addresses
431 bhis 2f / 2(r0) large? follow link
432 sub $12.,r1 / 2(r0) small? previous descriptor
433 cmp r1,r4 / is r1 smaller than pd?
434 bhis 1b / no? try again
435 mov r3,8.(r0) / yes? then r0 has small text address
436 mov r0,r3 / now r3 again points to first proc
437 br 0b / next descriptor
439 2: mov 8.(r1),r2 / follow link to compare with 2(r0)
440 beq 3f / if 0 then no link defined
441 cmp 2(r0),2(r2) / compare start addresses
442 blo 3f / r0 between r1 and r2
443 mov r2,r1 / r0 above r2,
446 3: mov r0,8.(r1) / link of r1 points to r0
447 mov r2,8.(r0) / link of r0 points to r2
448 br 0b / next descriptor
450 4: mov r3,firstp / firstp links to first procedure
453 mov $1,maxcount / countptr for first proc
454 mov r3,r4 / points to first proc
456 0: mov r3,-(sp) / stack current procedure
457 mov $-1,r1 / minimal line number 0177777
458 clr r5 / maximum line number on 0
459 mov 8.(r3),r4 / bottom address next descriptor
460 beq 6f / if 0 last procedure
461 mov 2(r4),r4 / top of current procedure
462 br 2f / start looking for lines
463 6: mov pd,r4 / top of last procedure
465 mov 2(r3),r3 / start text address procedure
466 8: movb (r3)+,r2 / first opcode for scanning
467 cmp $-2,r2 / case escape
468 beq 1f / escape treated at label 1
469 cmp $-106.,r2 / case lni
470 blt 7f / ordinary skip at label 7
471 beq 2f / lni treated at label 2
472 cmp $-108.,r2 / case lin.l
473 bgt 7f / ordinary skip at label 7
474 beq 3f / lin.l at label 3
475 clr r0 / lin.s0 treated here
476 bisb (r3)+,r0 / line number in r0
477 br 4f / compares at label 4
478 2: inc r0 / lni increases line number
479 br 4f / compares at label 4
480 3: jsr pc,wrdoff / get 2 byte number
482 cmp r1,r0 / look if r0 less than minimum
483 blo 5f / nothing to declare
484 mov r0,r1 / r0 new minimum
485 5: cmp r0,r5 / look if r0 more than maximum
486 blo 9f / nothing spectacular
487 mov r0,r5 / r0 new maximum
488 br 9f / line processed
491 bisb (r3)+,r2 / escaped instruction opcode
492 add $128.,r2 / ready for table entry
493 7: movb skipdisp(r2),r2 / skip the required number of bytes
496 9: cmp r3,r4 / still more text in this proc?
499 mov (sp)+,r3 / get bottom descriptor back
500 sub r1,r5 / number of lines encountered
501 bcs 9f / no lines then no file information
502 mov maxcount,4(r3) / this is the count pointer
503 mov r1,6(r3) / minimum line in descriptor
505 add r5,maxcount / this is the new maximum
506 9: mov 8.(r3),r3 / follow link to next procedure
509 .byte 2; .byte 2; .byte 0; .byte 0; .byte 1; .byte 1; .byte 1; .byte 0;
510 .byte 0; .byte 2; .byte 1; .byte 0; .byte 1; .byte 0; .byte 0; .byte 1;
511 .byte 1; .byte 1; .byte 0; .byte 0; .byte 2; .byte 1; .byte 0; .byte 2;
512 .byte 0; .byte 1; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
513 .byte 1; .byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 2;
514 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 2; .byte 2;
515 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
516 .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 1; .byte 0; .byte 0;
518 .byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1;
519 .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 1; .byte 1; .byte 1;
520 .byte 1; .byte 0; .byte 2; .byte 1; .byte 1; .byte 1; .byte 2; .byte 0;
521 .byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 1;
522 .byte 2; .byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
523 .byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 2; .byte 1;
524 .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1;
525 .byte 2; .byte 1; .byte 0; .byte 0; .byte 1; .byte 2; .byte 7; .byte 5;
528 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
529 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
530 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
531 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
532 .byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 2; .byte 0;
533 .byte 0; .byte 1; .byte 1; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
534 .byte 0; .byte 0; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
535 .byte 1; .byte 1; .byte 1; .byte 2; .byte 1; .byte 1; .byte 1; .byte 1;
537 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
538 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
539 .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0; .byte 0;
540 .byte 0; .byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0;
541 .byte 1; .byte 0; .byte 0; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0;
542 .byte 1; .byte 1; .byte 0; .byte 1; .byte 0; .byte 2; .byte 0; .byte 2;
543 .byte 1; .byte 0; .byte 0; .byte 0; .byte 1; .byte 1; .byte 0; .byte 1;
544 .byte 2; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1; .byte 1;
548 .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
549 .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 0; .byte 2;
550 .byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 2; .byte 0;
551 .byte 2; .byte 0; .byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
552 .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
553 .byte 2; .byte 0; .byte 0; .byte 0; .byte 0; .byte 2; .byte 2; .byte 2;
554 .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
555 .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
557 .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
558 .byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 1;
559 .byte 2; .byte 2; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
560 .byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 0; .byte 2;
561 .byte 0; .byte 2; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0;
562 .byte 2; .byte 0; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
563 .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 2; .byte 2;
564 .byte 2; .byte 2; .byte 0; .byte 0; .byte 2; .byte 2; .byte 0; .byte 2;
566 .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2; .byte 0; .byte 2;
567 .byte 2; .byte 0; .byte 1; .byte 0; .byte 0; .byte 0; .byte 2; .byte 0;
568 .byte 2; .byte 0; .byte 2; .byte 2; .byte 2; .byte 2; .byte 2; .byte 2;
569 .byte 0; .byte 2; .byte 0; .byte 1; .byte 2; .byte 0; .byte 0; .byte 2;
571 mov globmax,r3 / bottom of table space
574 mov r3,ltime / set up pointer to base
578 mov maxcount,r0 / number of lines
580 asl r0 / four byter per prof count
586 mov r3,lflow / set up pointer to base
588 ash $-3,r0 / divide by 8
590 bic $1,r0 / Rounded up to an integral number of words
595 mov r3,lcount / set up pointer
598 ash $2,r0 / multiply by 4
603 cmp r3,sybreak+2 / core available for tables?
606 sys indir;sybreak / ask for core
607 2: sub r5,r3 / this amount of space required
609 2: clr (r5)+ / clear table space
612 .if [1 - .count] * [1 - .flow] * [1 - .prof]
616 / start calling sequence here
619 mov pd,r3 / top of em-text and top of stack
620 clr r2 / are dummy return values
621 mov environ,-(sp) / setup environment pointer
622 mov argv,-(sp) / setup argument pointer
623 mov *argv,*filb / setup first file message
624 mov argc,-(sp) / setup argument count
625 mov entry.,-(sp) / start procedure to call
627 mov $loop,r4 / main loop address in r4
628 jbr cai.z / according to the cai
631 mov $0f,r0; jbr rude_error
632 badarg: mov $1f,r0; jbr rude_error
633 toolarge:mov $2f,r0; jbr rude_error
638 1: <load file error\0>
639 2: <program too large\0>
646 mov r5,r3 / restore r3
647 / Assumed that the result is 8
648 / bytes Recall r2 and move the
649 / amount of bytes asked for
650 clr r1 / restore for opcode
651 sub $8.,r2 / 8 bytes?
652 beq 1f / yes! later, 4 bytes next
653 movfo fr0,-(sp) / push result
654 mov (sp)+,(r3)+ / write result in data
655 mov (sp)+,(r3)+ / idem
656 jbr datloop / next loop
657 1: movf fr0,-(sp) / push result
658 mov (sp)+,(r3)+ / write result in data
659 mov (sp)+,(r3)+ / write result in data
660 mov (sp)+,(r3)+ / write result in data
661 mov (sp)+,(r3)+ / write result in data
664 mov r2,-(sp) / save byte count
669 movb (r4)+,r0 / get byte
678 movb (r4)+,r0 / get next byte
691 movb (r4)+,r0 / get next byte
706 movb (r4)+,r0 / get next byte
713 movb (r4)+,r0 / get next byte
776 /------------------------------------------------------------------------------
777 /------------------------------------------------------------------------------
778 / Main loop of interpreter starts here
779 /------------------------------------------------------------------------------
782 movb (pcx)+,r0 / pickup opcode + sign extend
783 9: asl r0 / opcode now -256 .. 254 & even
787 asl r1 / multiply by two again
788 add $1,counttab+514.(r1) / cannot be inc
789 adc counttab+512.(r1) / double precision counters
792 add timeinf(r0),*loprof
793 adc *hiprof / double precision
795 mov dispat(r0),pc / fast dispatch
797 /------------------------------------------------------------------------------
798 / Two byte opcodes come here for decoding of second byte
799 /------------------------------------------------------------------------------
803 bisb (pcx)+,r0 / fetch second byte no sign extend
804 asl r0 / 0 to 512 & even
805 cmp $0500,r0 / look for righ range
810 asl r1 / multiply by two again
811 add $1,counttab+1026.(r1) / cannot be inc
812 adc counttab+1024.(r1) / double precision counters
815 add time2inf(r0),*loprof
816 adc *hiprof / double precision
818 mov dispae1(r0),pc / fast dispatch
820 /----------------------------------------------------------------------------
822 movb (pcx)+,r0 / fetch second byte and sign extend
826 add $1,counttab+1666. / cannot be inc
827 adc counttab+1664. / double precision counters
829 jbr loc.f / fast dispatch
830 /------------------------------------------------------------------------------
831 / dispatch tables, first the unescaped opcodes
833 / name convention is as follows:
834 / each execution routine has as a name the name of the instruction
835 / followed by a dot and a suffix.
836 / suffix can be an integer (sometimes followed by a W),
837 / an 's'or a 'w', followed by an integer, an 'l' ,a 'p' ,
838 / a 'n', sometimes followed by a 'w', or a 'z'.
839 / loc.1 routine to execute loc 1
840 / zge.s0 routine to execute zge 0 thru 255
841 / lae.w1 routine to execute lae 1024 thru lae 2046
842 / lof.2W routine to execute lof 2*the word size
843 / lol.pw routine to execute positive lol instructions
844 / loe.l routine to execute all loe instructions
845 / add.z routine to execute instruction without operand
846 / or with operand on the stack.
847 /------------------------------------------------------------------------------
852 lal.p; lal.n; lal.0; lal._1; lal.w0; lal.w_1; lal.w_2; lar.1W
853 ldc.0; lde.lw; lde.w0; ldl.0; ldl.w_1; lfr.1W; lfr.2W; lfr.s0
854 lil.w_1; lil.w0; lil.0; lil.1W; lin.l; lin.s0; lni.z; loc.l
855 loc._1; loc.s0; loc.s_1; loe.lw; loe.w0; loe.w1; loe.w2; loe.w3
856 loe.w4; lof.l; lof.1W; lof.2W; lof.3W; lof.4W; lof.s0; loi.l
857 loi.1; loi.1W; loi.2W; loi.3W; loi.4W; loi.s0; lol.pw; lol.nw
858 lol.0; lol.1W; lol.2W; lol.3W; lol._1W; lol._2W; lol._3W; lol._4W
859 lol._5W; lol._6W; lol._7W; lol._8W; lol.w0; lol.w_1; lxa.1; lxl.1
860 lxl.2; mlf.s0; mli.1W; mli.2W; rck.1W; ret.0; ret.1W; ret.s0
861 rmi.1W; sar.1W; sbf.s0; sbi.1W; sbi.2W; sdl.w_1; set.s0; sil.w_1
862 sil.w0; sli.1W; ste.lw; ste.w0; ste.w1; ste.w2; stf.l; stf.1W
863 stf.2W; stf.s0; sti.1; sti.1W; sti.2W; sti.3W; sti.4W; sti.s0
864 stl.pw; stl.nw; stl.0; stl.1W; stl._1W; stl._2W; stl._3W; stl._4W
865 stl._5W; stl.w_1; teq.z; tgt.z; tlt.z; tne.z; zeq.l; zeq.s0
866 zeq.s1; zer.s0; zge.s0; zgt.s0; zle.s0; zlt.s0; zne.s0; zne.s_1
867 zre.lw; zre.w0; zrl._1W; zrl._2W; zrl.w_1; zrl.nw; escape1; escape2
870 dispat: / dispatch table for unescaped opcodes
873 loc.0; loc.1; loc.2; loc.3; loc.4; loc.5; loc.6; loc.7
874 loc.8; loc.9; loc.10; loc.11; loc.12; loc.13; loc.14; loc.15
875 loc.16; loc.17; loc.18; loc.19; loc.20; loc.21; loc.22; loc.23
876 loc.24; loc.25; loc.26; loc.27; loc.28; loc.29; loc.30; loc.31
877 loc.32; loc.33; aar.1W; adf.s0; adi.1W; adi.2W; adp.l ; adp.1
878 adp.2; adp.s0; adp.s_1; ads.1W; and.1W; asp.1W; asp.2W; asp.3W
879 asp.4W; asp.5W; asp.w0; beq.l; beq.s0; bge.s0; bgt.s0; ble.s0
880 blm.s0; blt.s0; bne.s0; bra.l; bra.s_1; bra.s_2; bra.s0; bra.s1
881 cal.1; cal.2; cal.3; cal.4; cal.5; cal.6; cal.7; cal.8
882 cal.9; cal.10; cal.11; cal.12; cal.13; cal.14; cal.15; cal.16
883 cal.17; cal.18; cal.19; cal.20; cal.21; cal.22; cal.23; cal.24
884 cal.25; cal.26; cal.27; cal.28; cal.s0; cff.z; cif.z; cii.z
885 cmf.s0; cmi.1W; cmi.2W; cmp.z; cms.s0; csa.1W; csb.1W; dec.z
886 dee.w0; del.w_1; dup.1W; dvf.s0; dvi.1W; fil.l; inc.z; ine.lw
887 ine.w0; inl._1W; inl._2W; inl._3W; inl.w_1; inn.s0; ior.1W; ior.s0
888 lae.l; lae.w0; lae.w1; lae.w2; lae.w3; lae.w4; lae.w5; lae.w6
892 /------------------------------------------------------------------------------
893 / now dispatch table for escaped opcodes
894 /------------------------------------------------------------------------------
896 dispae1: /dispatch escaped opcodes 1
898 aar.l; aar.z; adf.l; adf.z; adi.l; adi.z; ads.l; ads.z
899 adu.l; adu.z; and.l; and.z; asp.lw; ass.l; ass.z; bge.l
900 bgt.l; ble.l; blm.l; bls.l; bls.z; blt.l; bne.l; cai.z
901 cal.l; cfi.z; cfu.z; ciu.z; cmf.l; cmf.z; cmi.l; cmi.z
902 cms.l; cms.z; cmu.l; cmu.z; com.l; com.z; csa.l; csa.z
903 csb.l; csb.z; cuf.z; cui.z; cuu.z; dee.lw; del.pw; del.nw
904 dup.l; dus.l; dus.z; dvf.l; dvf.z; dvi.l; dvi.z; dvu.l
905 dvu.z; fef.l; fef.z; fif.l; fif.z; inl.pw; inl.nw; inn.l
906 inn.z; ior.l; ior.z; lar.l; lar.z; ldc.l; ldf.l; ldl.pw
907 ldl.nw; lfr.l; lil.pw; lil.nw; lim.z; los.l; los.z; lor.s0
908 lpi.l; lxa.l; lxl.l; mlf.l; mlf.z; mli.l; mli.z; mlu.l
909 mlu.z; mon.z; ngf.l; ngf.z; ngi.l; ngi.z; nop.z; rck.l
910 rck.z; ret.l; rmi.l; rmi.z; rmu.l; rmu.z; rol.l; rol.z
911 ror.l; ror.z; rtt.z; sar.l; sar.z; sbf.l; sbf.z; sbi.l
912 sbi.z; sbs.l; sbs.z; sbu.l; sbu.z; sde.l; sdf.l; sdl.pw
913 sdl.nw; set.l; set.z; sig.z; sil.pw; sil.nw; sim.z; sli.l
920 sli.z; slu.l; slu.z; sri.l; sri.z; sru.l; sru.z; sti.l
921 sts.l; sts.z; str.s0; tge.z; tle.z; trp.z; xor.l; xor.z
922 zer.l; zer.z; zge.l; zgt.l; zle.l; zlt.l; zne.l; zrf.l
923 zrf.z; zrl.pw; dch.z; exg.s0; exg.l; exg.z; lpb.z; gto.l
925 /------------------------------------------------------------------------------
926 / timeinf tables, first the unescaped opcodes
927 / these tables are parallel to the tables dispat and dispae1
928 / Each entry contains a reasonable estimate of
929 / the number of memory-cycles needed to
930 / execute that instruction. The exact amount cannot be
931 / supplied, since this can depend rather heavily on the
932 / size of the object in set, array case instructions etc.
933 / The table timeinf also contains, added to each entry,
934 / the number of memory-cycles needed to decode the instruction.
935 / This number is currently 6. The number is computed for
936 / the case that all check and runinf options are off.
937 /------------------------------------------------------------------------------
939 23.; 23.; 12.; 12.; 18.; 17.; 19.; 61.
940 11.; 31.; 21.; 15.; 20.; 30.; 30.; 31.
941 20.; 18.; 18.; 19.; 29.; 18.; 13.; 20.
942 10.; 14.; 13.; 27.; 20.; 20.; 20.; 20.
943 20.; 23.; 16.; 16.; 16.; 16.; 17.; 38.
944 14.; 26.; 26.; 26.; 26.; 28.; 26.; 25.
945 11.; 11.; 11.; 11.; 11.; 11.; 11.; 11.
946 11.; 11.; 11.; 11.; 16.; 16.; 26.; 24.
948 24.; 53.; 25.; 25.; 18.; 27.; 44.; 54.
949 30.; 59.; 53.; 21.; 28.; 19.; 51.; 18.
950 18.; 21.; 27.; 19.; 20.; 18.; 25.; 16.
951 16.; 15.; 12.; 24.; 24.; 24.; 24.; 25.
952 26.; 25.; 15.; 13.; 11.; 11.; 11.; 11.
953 11.; 16.; 14.; 14.; 14.; 14.; 20.; 16.
954 16.; 21.; 16.; 16.; 16.; 16.; 16.; 16.
955 26.; 16.; 10.; 10.; 15.; 24.; 10.; 40.
959 9.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
960 10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
961 10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
962 10.; 10.; 10.; 10.; 10.; 10.; 10.; 10.
963 10.; 10.; 48.; 53.; 21.; 28.; 20.; 10.
964 10.; 12.; 13.; 11.; 44.; 11.; 11.; 11.
965 11.; 11.; 27.; 21.; 17.; 17.; 17.; 17.
966 81.; 17.; 17.; 21.; 12.; 12.; 11.; 12.
968 54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
969 54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
970 54.; 54.; 54.; 54.; 54.; 54.; 54.; 54.
971 54.; 54.; 54.; 54.; 54.; 41.; 49.; 37.
972 40.; 53.; 53.; 51.; 60.; 24.; 41.; 11.
973 20.; 19.; 10.; 53.; 30.; 29.; 11.; 30.
974 20.; 15.; 15.; 15.; 19.; 44.; 37.; 36.
975 25.; 19.; 19.; 19.; 19.; 19.; 19.; 19.
977 /------------------------------------------------------------------------------
978 / time2inf table for escaped opcodes
979 / cycles necessary for decoding is already accounted for in timeinf
980 /------------------------------------------------------------------------------
984 57.; 46.; 61.; 50.; 37.; 26.; 30.; 19.
985 45.; 34.; 52.; 41.; 37.; 42.; 31.; 21.
986 21.; 21.; 91.; 108.; 97.; 21.; 21.; 53.
987 60.; 56.; 55.; 26.; 53.; 42.; 62.; 51.
988 72.; 61.; 72.; 61.; 38.; 27.; 40.; 29.
989 53.; 46.; 54.; 38.; 23.; 30.; 30.; 28.
990 36.; 45.; 34.; 61.; 50.; 39.; 28.; 44.
991 33.; 68.; 57.; 68.; 57.; 30.; 28.; 54.
993 45.; 44.; 33.; 70.; 59.; 22.; 27.; 28.
994 29.; 37.; 28.; 27.; 11.; 47.; 40.; 21.
995 20.; 35.; 33.; 61.; 50.; 34.; 23.; 39.
996 28.; 500.; 47.; 36.; 41.; 30.; 100.; 38.
997 27.; 62.; 39.; 28.; 44.; 33.; 88.; 77.
998 92.; 81.; 32.; 68.; 57.; 61.; 50.; 37.
999 26.; 33.; 22.; 45.; 34.; 29.; 28.; 30.
1000 28.; 61.; 52.; 16.; 28.; 27.; 11.; 30.
1002 19.; 36.; 25.; 32.; 21.; 36.; 25.; 31.
1003 39.; 32.; 32.; 14.; 14.; 117.; 45.; 34.
1004 31.; 22.; 20.; 20.; 20.; 20.; 20.; 27.
1005 16.; 26.; 17.; 39.; 47.; 36.; 10.; 29.
1008 /------------------------------------------------------------------------------
1009 / LOAD CONSTANT, LOAD LOCAL, STORE LOCAL
1010 /------------------------------------------------------------------------------
1014 loc.1: loc.2: loc.3: loc.4: loc.5: loc.6: loc.7: loc.8:
1015 loc.9: loc.10: loc.11: loc.12: loc.13: loc.14: loc.15: loc.16:
1016 loc.17: loc.18: loc.19: loc.20: loc.21: loc.22: loc.23: loc.24:
1017 loc.25: loc.26: loc.27: loc.28: loc.29: loc.30: loc.31: loc.32:
1019 asr r0 / make multiplication undone
1033 lpi.l: / let op, dit is een pointer
1034 / zonder offset op het moment!
1049 loc.f: jsr pc,wrdoff; mov r0,r1
1050 jsr pc,wrdoff; mov r0,-(sp)
1053 /__________________________________________________________________________
1055 lol.0: mov 010(r2),-(sp); next
1056 lol.1W: mov 012(r2),-(sp); next
1057 lol.2W: mov 014(r2),-(sp); next
1058 lol.3W: mov 016(r2),-(sp); next
1059 lol._1W: mov -02(r2),-(sp); next
1060 lol._2W: mov -04(r2),-(sp); next
1061 lol._3W: mov -06(r2),-(sp); next
1062 lol._4W: mov -010(r2),-(sp); next
1063 lol._5W: mov -012(r2),-(sp); next
1064 lol._6W: mov -014(r2),-(sp); next
1065 lol._7W: mov -016(r2),-(sp); next
1066 lol._8W: mov -020(r2),-(sp); next
1068 lol.w0: clr r0; bisb (pcx)+,r0
1069 5: asl r0; add r2,r0
1070 mov 010(r0),-(sp); next
1071 lol.w_1: mov $-400,r0; bisb (pcx)+,r0
1072 2: asl r0; add r2,r0
1073 mov (r0),-(sp); next
1074 lol.pw: jsr pc,wrdoff; br 5b
1075 lol.nw: jsr pc,wrdoff; br 2b
1077 /------------------------------------------------------------------------------
1079 ldl.0: mov 10.(r2),-(sp); mov 8.(r2),-(sp); next
1080 ldl.w_1: mov $-400,r0; bisb (pcx)+,r0
1081 2: asl r0; add r2,r0
1082 mov 2(r0),-(sp); mov (r0),-(sp); next
1083 ldl.pw: jsr pc,wrdoff; asl r0
1084 add r2,r0; mov 10.(r0),-(sp)
1085 mov 8.(r0),-(sp); next
1086 ldl.nw: jsr pc,wrdoff; br 2b
1088 /------------------------------------------------------------------------------
1089 loe.lw: jsr pc,wrdoff; br 2f
1090 loe.w0: loe.w1: loe.w2: loe.w3: loe.w4:
1091 asr r0; add $0144,r0
1092 swab r0; bisb (pcx)+,r0
1093 2: asl r0; add eb,r0
1094 mov (r0),-(sp); next
1095 lde.lw: jsr pc,wrdoff; br 2f
1096 lde.w0: clr r0; bisb (pcx)+,r0
1097 2: asl r0; add eb,r0
1098 mov 2(r0),-(sp); mov (r0),-(sp); next
1101 /------------------------------------------------------------------------------
1102 lil.0: clr r0; br 1f
1103 lil.1W: mov $1,r0; br 1f
1104 lil.pw: jsr pc,wrdoff; br 1f
1105 lil.w0: clr r0; bisb (pcx)+,r0
1107 2: asl r0; add r2,r0
1108 mov (r0),-(sp); jsr pc,chckptr
1109 mov *(sp),(sp); next
1110 lil.w_1: mov $-400,r0; bisb (pcx)+,r0; br 2b
1111 lil.nw: jsr pc,wrdoff; br 2b
1112 /------------------------------------------------------------------------------
1113 lof.l: jsr pc,wrdoff
1114 1: jsr pc,chckptr; add (sp)+,r0;
1115 mov (r0),-(sp); next
1117 lof.1W: lof.2W: lof.3W: lof.4W:
1120 lof.s0: clr r0; bisb (pcx)+,r0; br 1b
1121 ldf.l: jsr pc,wrdoff; add (sp)+,r0
1122 mov 2(r0),-(sp); mov (r0),-(sp); next
1123 /------------------------------------------------------------------------------
1124 lal.p: jsr pc,wrdoff
1125 5: add r2,r0; add $8.,r0
1127 lal.0: mov r2,-(sp); add $8.,(sp); next
1128 lal.w0: clr r0; bisb (pcx)+,r0
1130 lal.n: jsr pc,wrdoff; br 2f
1132 2: add r2,r0; mov r0,-(sp); next
1133 lal.w_1: mov $-400,r0
1134 3: bisb (pcx)+,r0; asl r0; br 2b
1135 lal.w_2: mov $-1000,r0; br 3b
1137 lae.l: jsr pc,wrdoff; br 1f
1138 lae.w0: lae.w1: lae.w2: lae.w3: lae.w4: lae.w5: lae.w6:
1140 sub $0171,r0; swab r0
1141 bisb (pcx)+,r0; asl r0
1145 bhi 1f; jsr pc,e.badlae;
1147 1: mov r0,-(sp); next
1148 /------------------------------------------------------------------------------
1149 lxl.1: mov $1,r0; br 1f
1150 lxl.2: mov $2,r0; br 1f
1151 lxl.l: jsr pc,wrdoff
1155 2: mov 8(r1),r1; sob r0,2b
1158 lxa.1: mov $1,r0; br 1f
1159 lxa.l: jsr pc,wrdoff; bgt 1f
1160 jlt e.oddz; mov r2,-(sp)
1163 2: mov 8(r1),r1; sob r0,2b
1164 add $10,r1; mov r1,-(sp); next
1166 /------------------------------------------------------------------------------
1167 loi.l: jsr pc,wrdoff; br 2f
1168 loi.1W: loi.2W: loi.3W: loi.4W:
1170 loi.s0: clr r0; bisb (pcx)+,r0
1171 2: cmp $1,r0; beq loi.1
1172 1: jsr pc,chckptr; mov (sp)+,r1; add r0,r1
1174 1: mov -(r1),-(sp); sob r0,1b; next
1175 loi.1: jsr pc,chckptb; mov (sp),r1; clr r0
1176 bisb (r1),r0; mov r0,(sp); next
1189 3: mov (sp)+,r0; br 2b
1191 /------------------------------------------------------------------------------
1193 /------------------------------------------------------------------------------
1194 stl.pw: jsr pc,wrdoff; asl r0; br 0f
1195 stl.0: clr r0; br 0f
1197 0: add r2,r0; mov(sp)+,8.(r0); next
1199 stl.nw: jsr pc,wrdoff; br 0f
1200 stl.w_1: mov $-400,r0; bisb (pcx)+,r0
1201 0: asl r0; add r2,r0
1202 mov (sp)+,(r0); next
1203 stl._1W: mov (sp)+,-2(r2); next
1204 stl._2W: mov (sp)+,-4(r2); next
1205 stl._3W: mov (sp)+,-6(r2); next
1206 stl._4W: mov (sp)+,-10(r2); next
1207 stl._5W: mov (sp)+,-12(r2); next
1209 sdl.w_1: mov $-400,r0; bisb (pcx)+,r0
1210 0: asl r0; add r2,r0
1211 2: mov (sp)+,(r0)+; mov (sp)+,(r0); next
1212 sdl.nw: jsr pc,wrdoff; br 0b
1213 sdl.pw: jsr pc,wrdoff; asl r0
1214 add r2,r0; add $8.,r0; br 2b
1216 /------------------------------------------------------------------------------
1218 sde.l: jsr pc,wrdoff; add eb,r0
1220 ste.lw: jsr pc,wrdoff; br 1f
1221 ste.w0: clr r0; br 0f
1222 ste.w1: mov $400,r0; br 0f
1223 ste.w2: mov $1000,r0
1225 1: asl r0; add eb,r0
1226 mov (sp)+,(r0); next
1229 /------------------------------------------------------------------------------
1231 stf.l: jsr pc,wrdoff; br 6f
1232 stf.1W: mov $2,r0; br 6f
1233 stf.2W: mov $4,r0; br 6f
1234 stf.s0: clr r0; bisb (pcx)+,r0
1235 6: add (sp)+,r0; br 7f
1236 sdf.l: jsr pc,wrdoff; add (sp)+,r0
1240 /------------------------------------------------------------------------------
1241 sil.w0: clr r0; bisb (pcx)+,r0
1242 5: asl r0; add r2,r0
1243 mov 8.(r0),r0; br 7f
1244 sil.w_1: mov $-400,r0; bisb (pcx)+,r0
1245 2: asl r0; add r2,r0
1247 7: mov (sp),r1; mov r0,(sp);
1248 jsr pc,chckptr; mov r1,*(sp)+; next
1249 sil.pw: jsr pc,wrdoff; br 5b
1250 sil.nw: jsr pc,wrdoff; br 2b
1251 /------------------------------------------------------------------------------
1252 sti.1: jsr pc,chckptb; mov (sp)+,r1;
1253 movb (sp)+,(r1); next
1254 sti.1W: sti.2W: sti.3W: sti.4W:
1256 sti.s0: clr r0; bisb (pcx)+,r0; br 1f
1257 sti.l: jsr pc,wrdoff
1259 jcs e.oddz; jsr pc,chckptr;
1261 2: mov (sp)+,(r1)+; sob r0,2b; next
1262 3: jcs sti.1; jbr e.oddz
1263 sts.l: jsr pc,wrdoff
1264 0: cmp $2,r0; beq 2f
1265 cmp $4,r0; beq 4f; jbr e.oddz
1267 2: mov (sp)+,r0; br 1b
1268 sts.z: mov (sp)+,r0; br 0b
1270 /------------------------------------------------------------------------------
1271 / POINTER ARITHMETIC
1272 /------------------------------------------------------------------------------
1273 adp.l: jsr pc,wrdoff; add r0,(sp); next
1274 adp.1: add $1,(sp); next
1275 adp.2: add $2,(sp); next
1276 adp.s0: clr r0; bisb (pcx)+,r0
1278 adp.s_1: mov $-400,r0; bisb (pcx)+,r0
1280 ads.l: jsr pc,wrdoff; br 0f
1282 0: cmp $1,r0; beq 1f
1284 2: mov (sp)+,r1; sob r0,2b
1286 ads.1W: mov (sp)+,r1; add r1,(sp); next
1289 sbs.l: jsr pc,wrdoff; br 0f
1291 0: mov (sp)+,r1; sub r1,(sp)
1298 4: mov r1,-(sp); sob r0,4b
1303 /------------------------------------------------------------------------------
1304 /------------------------------------------------------------------------------
1305 / Clears, increments and decrements
1306 /------------------------------------------------------------------------------
1310 cmp (r1),$und; jne 3f;
1313 inc (r1); bvs 9f; next
1314 inl._1W: mov r2,r1; sub $2,r1; br 4b
1315 inl._2W: mov r2,r1; sub $4,r1; br 4b
1316 inl._3W: mov r2,r1; sub $6,r1; br 4b
1317 inl.w_1: mov $-400,r0; bisb (pcx)+,r0;
1318 1: asl r0; mov r2,r1;
1320 inl.pw: jsr pc,wrdoff; add $4,r0;
1321 br 1b; / !! proc frame 4 words
1322 inl.nw: jsr pc,wrdoff; br 1b
1323 ine.lw: jsr pc,wrdoff; br 1f
1324 ine.w0: clr r0; bisb (pcx)+,r0;
1325 1: asl r0; add eb,r0;
1330 cmp (r1),$und; jne 3f;
1333 dec (r1); bvs 9f; next
1334 del.w_1: mov $-400,r0; bisb (pcx)+,r0;
1335 1: asl r0; mov r0,r1;
1337 del.pw: jsr pc,wrdoff; add $4,r0;
1338 br 1b; / !proc frame 4 words
1339 del.nw: jsr pc,wrdoff; br 1b
1340 dee.w0: clr r0; bisb (pcx)+,r0;
1341 1: asl r0; add eb,r0;
1343 dee.lw: jsr pc,wrdoff; br 1b;
1344 9: jsr pc,e.iovfl; next
1345 / jump to an error routine for integer overflow
1346 zrl._1W: clr -2(r2); next
1347 zrl._2W: clr -4(r2); next
1348 zrl.w_1: mov $-400,r0; bisb (pcx)+,r0;
1349 1: asl r0; add r2,r0;
1351 zrl.nw: jsr pc,wrdoff; br 1b
1352 zrl.pw: jsr pc,wrdoff; add $4,r0;
1354 zre.lw: jsr pc,wrdoff; br 1f
1355 zre.w0: clr r0; bisb (pcx)+,r0;
1356 1: asl r0; add eb,r0;
1358 zrf.l: jsr pc,wrdoff; br 1f
1359 zrf.z: mov (sp)+,r0;
1361 2: clr -(sp); sob r0,2b; next
1362 zer.s0: clr r0; bisb (pcx)+,r0;
1363 3: bit $1,r0; jne e.illins
1364 / test if number of bytes is even
1366 zer.l: jsr pc,wrdoff; br 3b
1367 zer.z: mov (sp)+,r0; br 3b
1368 /------------------------------------------------------------------------------
1370 /------------------------------------------------------------------------------
1372 and.1W: mov $1,r1; mov $2,r0;
1374 and.l: jsr pc,wrdoff; br 0f
1375 and.z: mov (sp)+,r0;
1376 0: ble 9f; mov r0,r1;
1379 1: mov (sp)+,r5; com r5;
1380 bic r5,(r0)+; sob r1,1b;
1382 ior.1W: mov $1,r1; mov $2,r0;
1384 ior.s0: clr r0; bisb (pcx)+,r0;
1386 ior.l: jsr pc,wrdoff; br 0f
1387 ior.z: mov (sp)+,r0;
1390 0: ble 9f; bit $1,r0;
1392 mov sp,r5; add r0,r5; asr r1;
1393 1: bis (sp)+,(r5)+; sob r1,1b; next
1394 xor.l: jsr pc,wrdoff; br 0f;
1395 xor.z: mov (sp)+,r0;
1396 0: ble 9f; bit $1,r0;
1398 mov sp,r5; add r0,r5; asr r1
1400 xor r0,(r5)+; sob r1,1b; next
1401 com.l: jsr pc,wrdoff; br 1f
1402 com.z: mov (sp)+,r0;
1403 1: bit $1,r0; bne 9f
1406 2: com -(r0); sob r1,2b
1408 rol.l: jsr pc,wrdoff; br 3f
1409 rol.z: mov (sp)+,r0;
1411 mov (sp)+,r5; ash $3,r0;
1412 div r0,r4; mov r5,r4;
1414 1: ash $-3,r0; mov sp,r1;
1416 add r0,r1; mov r1,r5;
1418 mov r3,saver0; mov r0,r3;
1419 4: mov r3,r0; mov r5,r1;
1420 2: rol -(r1); sob r0,2b;
1421 adc -2(r5); sob r4,4b;
1422 mov saver0,r3; mov $loop,r4; next
1423 1: rolb (r1)+; adc (r1);
1424 sob r4,1b; mov saver1,r4; next
1425 ror.l: jsr pc,wrdoff; neg (sp); br 3b
1426 ror.z: mov (sp)+,r0; neg (sp); br 3b
1427 9: jsr pc,e.oddz /error codes for odd or
1428 /negative number of bytes
1430 /------------------------------------------------------------------------------
1432 /------------------------------------------------------------------------------
1434 set.s0: clr r0; bisb (pcx)+,r0
1437 bgt 9f; jsr pc,e.set
1441 jsr pc,settest; inc r0
1442 asr r0; / if r0 odd choose next even
1443 2: clr -(sp); sob r0,2b; / empty set
1444 mov r1,r0; ash $-3,r0;
1445 add sp,r0; bic $177770,r1;
1446 bisb bits(r1),(r0); next
1447 set.l: jsr pc,wrdoff; br 1b
1448 set.z: mov (sp)+,r0; br 1b
1449 inn.s0: clr r0; bisb (pcx)+,r0
1452 bgt 9f; jsr pc,e.set
1456 add r0,r5; mov (sp)+,r1;
1457 jsr pc,settest; mov r1,r0
1458 ash $-3,r0; add sp,r0;
1460 bic $177770,r1; bitb bits(r1),(r0)
1463 2: mov r5,sp; clr (sp); next
1464 inn.l: jsr pc,wrdoff; br 1b
1465 inn.z: mov (sp)+,r0; br 1b
1477 settest: mov r0,-(sp); clc
1478 ash $3,r0; sub r1,r0;
1480 bgt 3f; jsr pc,e.set
1482 3: mov (sp)+,r0; rts pc
1483 /------------------------------------------------------------------------------
1485 /------------------------------------------------------------------------------
1489 lar.1W: mov $2,r0; br 1f
1490 lar.l: jsr pc,wrdoff; br 1f
1491 lar.z: mov (sp)+,r0;
1492 1: jsr pc,calcarr; clr -2(sp);
1493 sub r5,sp; bic $1,sp;
1495 2: movb (r1)+,(r0)+; sob r5,2b; next
1496 sar.1W: mov $2,r0; br 1f
1497 sar.l: jsr pc,wrdoff; br 1f
1498 sar.z: mov (sp)+,r0;
1499 1: jsr pc,calcarr; mov sp,r0;
1502 2: movb (r0)+,(r1)+; sob r5,2b; next
1503 aar.1W: mov $2,r0; br 1f
1504 aar.l: jsr pc,wrdoff; br 1f
1505 aar.z: mov (sp)+,r0;
1506 1: jsr pc,calcarr; mov r1,-(sp); next
1508 calcarr: sub $02,r0; beq 0f;
1511 mov (sp)+,r0; mov (sp)+,r1;
1512 sub (r0)+,r1; bge 9f
1515 cmp (r0)+,r1; bge 9f
1519 mul r5,r1; add (sp)+,r1;
1520 mov -010(sp),-(sp); rts pc;
1524 /------------------------------------------------------------------------------
1525 /--------------------------------------------------------------
1527 /--------------------------------------------------------------
1530 / convert int to int
1531 / 1 byte -> ? : sign extension
1533 inc r0 / dest 1 byte = dest 1 word
1536 cmp (sp),$2 / if size 2 then trap for undefined
1540 jsr pc,e.iund / this is the trap
1582 cmp r0,$2 / trap if size 2 undefined integer
1586 jsr pc,e.iund / trap for undefined integer
1620 cmp (sp),$2 / trap undefined of size 2
1624 jsr pc,e.iund / this is the trap
1638 9: jsr pc,e.conv; next
1657 / unfortunately, this does not work for numbers >= 2^31
1675 /--------------------------------------------------------------
1676 / INTEGER ARITHMETIC
1677 /--------------------------------------------------------------
1679 adi.l: jsr pc,wrdoff; br 0f
1688 cmp (sp),$und / trap undefineds of size 2
1692 6: jsr pc,e.iund / this is the trap
1700 adi.2W: 2: add (sp)+,02(sp)
1714 jsr pc,e.oddz ; next
1716 sbi.l: jsr pc,wrdoff; br 0f
1725 cmp (sp),$und / trap for size 2 undefineds
1729 6: jsr pc,e.iund / this is the trap
1737 sbi.2W: 2: sub (sp)+,02(sp)
1752 mli.l: jsr pc,wrdoff; br 0f
1760 mli.1W: mov (sp)+,r1
1762 cmp r1,$und / trap for undefineds of size 2
1766 6: jsr pc,e.iund / this is the trap
1834 jsr pc,regretu; next
1838 dvi.l: jsr pc,wrdoff; br 0f
1845 dvi.1W: mov 02(sp),r1
1848 cmp r1,$und / trap for undifined of size 2
1852 6: jsr pc,e.iund / this is the trap
1951 jsr pc,regretu; next
1953 rmi.l: jsr pc,wrdoff; br 0f
1960 rmi.1W: mov 02(sp),r1
1963 cmp r1,$und / trap for undefineds of size 2
1967 6: jsr pc,e.iund / this is the trap
2061 jsr pc,regretu; next
2063 ngi.l: jsr pc,wrdoff; br 1f
2070 cmp (sp),$und / trap for undefineds of size 2
2093 sli.l: jsr pc,wrdoff; br 0f
2097 sli.1W: mov (sp)+,r1
2100 cmp r0,$und / trap for undefined size 2
2128 sri.l: jsr pc,wrdoff; br 0f
2135 cmp r0,$und / trap for undefined size 2
2154 /--------------------------------------------------------------
2155 adu.l: jsr pc,wrdoff; br 0f
2157 0: jsr pc,tstr0; add r0,sp
2158 mov sp,r1; add r0,sp; asr r0
2159 2: adc -(sp); add -(r1),(sp); sob r0,2b
2161 sbu.l: jsr pc,wrdoff; br 0f
2163 0: jsr pc,tstr0; add r0,sp
2164 mov sp,r1; add r0,sp; asr r0;
2165 2: sbc -(sp); sub -(r1),(sp); sob r0,2b
2167 mlu.l: jsr pc,wrdoff; br 0f
2202 jsr pc,regretu; next
2205 dvu.l: jsr pc,wrdoff; br 0f
2296 rmu.l: jsr pc,wrdoff; br 0f
2377 slu.l: jsr pc,wrdoff; br 0f
2397 sru.l: jsr pc,wrdoff; br 0f
2425 /--------------------------------------------------------------
2426 / FLOATING POINT INSTRUCTIONS
2427 /--------------------------------------------------------------
2429 adf.s0: clr r0; bisb (pcx)+,r0; br 0f
2430 adf.l: jsr pc,wrdoff; br 0f
2440 sbf.s0: clr r0; bisb (pcx)+,r0; br 0f
2441 sbf.l: jsr pc,wrdoff; br 0f
2452 mlf.s0: clr r0; bisb (pcx)+,r0; br 0f
2453 mlf.l: jsr pc,wrdoff; br 0f
2463 dvf.s0: clr r0; bisb (pcx)+,r0; br 0f
2464 dvf.l: jsr pc,wrdoff; br 0f
2475 ngf.l: jsr pc,wrdoff; br 0f
2483 fif.l: jsr pc,wrdoff; br 0f
2494 fef.l: jsr pc,wrdoff; br 0f
2503 /----------------------------------------------------------------------------
2504 / TEST AND BRANCH GROUP
2505 /----------------------------------------------------------------------------
2506 tlt.z: tst (sp)+; blt true; clr -(sp); next
2507 tle.z: tst (sp)+; ble true; clr -(sp); next
2508 teq.z: tst (sp)+; beq true; clr -(sp); next
2509 tne.z: tst (sp)+; bne true; clr -(sp); next
2510 tge.z: tst (sp)+; bge true; clr -(sp); next
2511 tgt.z: tst (sp)+; bgt true; clr -(sp); next
2512 /----------------------------------------------------------------------------
2513 zlt.s0: tst (sp)+; blt yesbr2; br nobr2
2514 zlt.l: tst (sp)+; blt yesbr3; br nobr3
2515 zle.s0: tst (sp)+; ble yesbr2; br nobr2
2516 zle.l: tst (sp)+; ble yesbr3; br nobr3
2517 zeq.s0: tst (sp)+; beq yesbr2; br nobr2
2518 zeq.s1: tst (sp)+; beq yesbr4; br nobr2
2519 zeq.l: tst (sp)+; beq yesbr3; br nobr3
2520 zne.s0: tst (sp)+; bne yesbr2; br nobr2
2521 zne.l: tst (sp)+; bne yesbr3; br nobr3
2522 zne.s_1: tst (sp)+; bne yesbr5; br nobr2
2523 zge.s0: tst (sp)+; bge yesbr2; br nobr2
2524 zge.l: tst (sp)+; bge yesbr3; br nobr3
2525 zgt.s0: tst (sp)+; bgt yesbr2; br nobr2
2526 zgt.l: tst (sp)+; bgt yesbr3; br nobr3
2531 /------------------------------------------------------------------------------
2533 blt.s0: cmp (sp)+,(sp)+; bgt yesbr2; br nobr2
2534 blt.l: cmp (sp)+,(sp)+; bgt yesbr3; br nobr3
2535 ble.s0: cmp (sp)+,(sp)+; bge yesbr2; br nobr2
2536 ble.l: cmp (sp)+,(sp)+; bge yesbr3; br nobr3
2537 beq.l: cmp (sp)+,(sp)+; beq yesbr3; br nobr3
2538 beq.s0: cmp (sp)+,(sp)+; beq yesbr2; br nobr2
2539 bne.s0: cmp (sp)+,(sp)+; bne yesbr2; br nobr2
2540 bne.l: cmp (sp)+,(sp)+; bne yesbr3; br nobr3
2541 bge.s0: cmp (sp)+,(sp)+; ble yesbr2; br nobr2
2542 bge.l: cmp (sp)+,(sp)+; ble yesbr3; br nobr3
2543 bgt.s0: cmp (sp)+,(sp)+; blt yesbr2; br nobr2
2544 bgt.l: cmp (sp)+,(sp)+; blt yesbr3; br nobr3
2554 bra.s1: yesbr4: mov $400,r0; br 5b
2555 bra.s_1: yesbr5: mov $-400,r0; br 5b
2556 bra.s_2: mov $-800,r0; br 5b
2559 nobr3: cmpb (pcx)+,(pcx)+
2562 /------------------------------------------------------------------------------
2564 /------------------------------------------------------------------------------
2566 calccomp: mov (sp)+,saver1; / old pc
2568 add r0,r1; mov r1,r5;
2569 add r0,r1; mov r1,saver0; / new sp
2571 2: cmp (r5)+,(sp)+; blt 3f;
2574 2: cmp (r5)+,(sp)+; blo 3f;
2576 5: mov saver0,sp; clr -(sp);
2578 4: mov saver0,sp; mov $1,-(sp);
2580 3: mov saver0,sp; mov $-1,-(sp);
2582 5: mov saver1,-(sp); rts pc
2584 cmi.1W: mov $2,r0; br 1f
2585 cmi.2W: mov $4,r0; br 1f
2586 cmi.l: jsr pc,wrdoff; br 1f
2587 cmi.z: mov (sp)+,r0;
2588 1: jsr pc,calccomp; next
2589 cms.s0: clr r0; bisb (pcx)+,r0
2590 1: jsr pc,calccomp; tst (sp)+;
2591 bne great; clr -(sp); next
2592 cms.l: jsr pc,wrdoff; br 1b
2593 cms.z: mov (sp)+,r0; br 1b
2594 cmu.l: jsr pc,wrdoff; br 1f
2595 cmu.z: mov (sp)+,r0; br 1f
2597 1: jsr pc,calccomp; mov (sp)+,r1;
2598 jlo less; jhi great;
2600 cmf.s0: clr r0; bisb (pcx)+,r0;
2601 1: cmp $4,r0; beq 3f
2605 movf (sp)+,fr0; cmpf (sp)+,fr0;
2606 4: cfcc; jlt less; jgt great;
2608 cmf.l: jsr pc,wrdoff; br 1b
2609 cmf.z: mov (sp)+,r0; br 1b
2610 less: mov $-1,-(sp); next
2612 /------------------------------------------------------------------------------
2613 /------------------------------------------------------------------------------
2614 /------------------------------------------------------------------------------
2615 / call and return group
2616 /------------------------------------------------------------------------------
2618 / Frame format on the stack is:
2621 / | - - - - - - - - - - - - |
2622 / | Static link = param 0 | < AB
2623 / |_________________________| ____
2624 / |-------------------------| | P
2625 / | Saved line number | | R
2626 / |-------------------------| | O
2627 / | Saved file address | | C
2628 / |-------------------------| | F
2629 / | Return address | | R
2630 / |-------------------------| | A
2631 / | Dynamic link | < LB | M
2632 / |_________________________| ____| E
2633 / |-------------------------|
2635 / | local variable -1 |
2636 / |-------------------------|
2640 / The static link and the parameters are set by the
2641 / calling procedure; the frame is set by cal which reserves
2642 / also the space for local variables.
2643 /------------------------------------------------------------------------------
2645 cal.1: cal.2: cal.3: cal.4: cal.5: cal.6: cal.7: cal.8:
2646 cal.9: cal.10: cal.11: cal.12: cal.13: cal.14: cal.15: cal.16:
2647 cal.17: cal.18: cal.19: cal.20: cal.21: cal.22: cal.23: cal.24:
2648 cal.25: cal.26: cal.27: cal.28:
2650 asr r0; sub $077,r0; br 1f
2651 cal.s0: clr r0; bisb (pcx)+,r0; br 1f
2652 cai.z: mov (sp)+,r0; br 1f
2653 cal.l: jsr pc,wrdoff
2659 .if .flow + .count + .prof
2662 add r5,r0 / procdes 12 bytes in this case
2664 add pd,r0; / now r0 points to the bottom
2665 / of the proc descriptor
2666 mov *eb,-(sp) / save line number
2667 mov *filb,-(sp) / save file address
2669 .if .prof + .count + .flow
2670 tst 10.(r0) / yet a filename defined in this proc?
2671 bne 4f / yes? continue
2672 mov (sp),10.(r0) / no? Then take the old filename
2673 4: mov curproc,(sp) / save old procdescriptor
2674 mov r0,curproc / continue with the new one
2675 mov 4(r0),countfld / count pointer minus line number
2676 sub 6(r0),countfld / to add at line numbers
2678 mov pcx,-(sp) / return address
2679 mov r2,-(sp) / old local base
2680 mov sp,r2 / new local base
2681 mov (r0)+,r1 / number of bytes for locals
2683 inc r1; asr r1 / make even
2684 2: mov $und,-(sp) / make undefined
2685 sob r1,2b / for r1 words local
2686 3: mov (r0),pcx / em start address
2688 /------------------------------------------------------------------------------
2690 ret.l: jsr pc,wrdoff; br 1f
2691 ret.1W: mov $2,r0; br 1f
2692 ret.s0: clr r0; bisb (pcx)+,r0;
2693 jlt e.oddz / bad result size
2694 beq ret.0 / no result
2695 cmp $32.,r0; bge 1f; jsr pc,e.badlfr
2696 1: inc r0; asr r0 / make even
2697 mov r0,retsize / result size
2698 mov $retarea,r1 / must point to retarea
2699 2: mov (sp)+,(r1)+ / load result
2700 sob r0,2b / continue when there is more
2703 ret.0: clr retsize / no function result
2704 3: mov r2,sp / set sp to bottom frame
2705 mov (sp)+,r2 / restore (dynamic) local base
2706 jeq lblhalt; / if zero then main procedure returns
2707 mov (sp)+,pcx / return address in program counter
2708 mov eb,r1 / must point to external base
2709 mov (sp)+,r0 / file or procdesbase in r0
2710 .if .count + .flow + .prof
2711 mov r0,curproc / save procdesbase current proc
2712 mov 4(r0),countfld / restore pointer to
2713 beq 5f / countfield 0 non interesting
2714 sub 6(r0),countfld / table entries
2715 mov countfld,countptr
2729 mov 10.(r0),r0 / pointer to file name in r0
2733 tst 4(r1) / file 0 not stacked
2735 cmp r0,4(r1) / same file name?
2736 beq 4f / yes continue
2737 jsr pc,nexttab / next line table entry in r5
2738 clr (r5) / 0 indicates file pointer follows
2739 jsr pc,nexttab / next entry in r5
2740 mov 4(r1),(r5) / store pointer to file name
2741 5: mov (sp),(r1) / restored line number in *eb
2742 beq 4f / do not put 0 in last table
2743 jsr pc,nexttab / next entry in r5
2744 mov (sp),(r5) / line number in table
2745 4: cmp (sp),(r1) / line number different?
2746 bne 5b / yes? put it in table
2748 mov r0,4(r1) / old file address
2749 mov (sp)+,(r1) / reset line number
2750 next / main loop again
2752 lfr.l: jsr pc,wrdoff;
2753 8: bit $1,r0; jne e.illins
2754 cmp r0,retsize; jeq 7f; jsr pc,e.badlfr
2755 7: asr r0; / number of words
2757 mov $retarea,r1; / must point to retarea
2759 add r0,r1; / top of result
2760 2: mov -(r1),-(sp); / move word of result
2761 sob r0,2b; / look for more
2763 lfr.1W: mov $2,r0; br 8b
2764 lfr.2W: mov $4,r0; br 8b
2765 lfr.s0: clr r0; bisb (pcx)+,r0; br 8b
2767 /------------------------------------------------------------------------------
2770 /------------------------------------------------------------------------------
2771 exg.s0: clr r0; bisb (pcx)+,r0; br 1f
2772 exg.l: jsr pc,wrdoff; br 1f
2773 exg.z: mov (sp)+,r0;
2774 1: cmp r0,$1; beq 0f;
2780 2: mov -(sp),r5; mov -(r0),(sp);
2781 mov r5,(r0); sob r1,2b;
2784 9: jsr pc,e.oddz; next
2789 /------------------------------------------------------------------------------
2791 dup.1W: mov (sp),-(sp); next
2792 dup.l: jsr pc,wrdoff; br 1f;
2793 dus.l: jsr pc,wrdoff; br 0f;
2794 dus.z: mov (sp)+,r0;
2795 0: ble 9b; bit $1,r0;
2797 tst -(sp); mov (sp)+,r0;
2799 bic $1,r0; mov r0,r1;
2800 mov sp,r5; add r0,r5;
2802 2: mov -(r5),-(sp); sob r1,2b; next
2807 /------------------------------------------------------------------------------
2808 fil.l: jsr pc,wrdoff; add eb,r0
2809 cmp r0,*filb; beq 1f;
2811 clr *eb / new file asks for new line
2812 jsr pc,nexttab; clr (r5);
2813 jsr pc,nexttab; mov *filb,(r5);
2815 .if .flow + .count + .prof
2816 mov curproc,r1 / current proc descriptor
2818 sub 6(r1),countfld / start countptr for this proc
2819 mov r0,10.(r1) / file pointer in procdes
2824 .if .count + .flow + .prof
2832 lin.l: jsr pc,wrdoff; br 1f
2833 lin.s0: clr r0; bisb (pcx)+,r0
2834 1: cmp *eb,r0; beq 9f;
2836 .if .count + .flow + .prof
2838 add r0,r5 / this is the right countptr
2851 jsr pc,nexttab / next entry in lasttab
2852 mov *eb,(r5) / set endline
2855 mov countptr,r1 / line number in r1
2857 asl r1 / multiply by 4
2858 add lcount,r1 / r1 is pointer to long integer now
2859 add $1,2(r1) / cannot be inc
2860 adc (r1) / that was all
2863 mov countptr,r1 / line number in r1
2864 clr r0 / get ready for divide
2865 div $8.,r0 / r0 = byte offset; r1 = bit offset
2866 add lflow,r0 / r0 is byte pointer now
2867 bisb bits(r1),(r0) / set bit
2871 /------------------------------------------------------------------------------
2873 bls.l: jsr pc,wrdoff; br 0f;
2874 bls.z: mov (sp)+,r0;
2878 1: mov (sp)+,r1; sob r0,1b;
2880 blm.l: jsr pc,wrdoff
2883 blm.s0: clr r0; bisb (pcx)+,r0
2884 1: jsr pc,regsave; jsr pc,chckptr
2885 mov (sp)+,r2; jsr pc,chckptr
2889 beq 2f / Now avoid wrong copy. The pieces may overlap !
2895 2: jsr pc,regretu; next
2896 3: add r1,r3; add r1,r2;
2897 1: mov -(r3),-(r2); sob r0,1b; br 2b
2898 /------------------------------------------------------------------------------
2899 / Range check and case instructions
2900 /------------------------------------------------------------------------------
2901 csa.l: jsr pc,wrdoff; br 1f;
2902 csa.z: mov (sp)+,r0;
2903 1: sub $2,r0; jne e.illins;
2904 csa.1W: mov (sp)+,r0;
2905 mov (sp)+,r1; sub 2(r0),r1;
2906 blt 6f; cmp 4(r0),r1;
2908 add $6,r1; add r0,r1;
2911 6: mov r0,r1; br 5b;
2913 csb.z: mov (sp)+,r0; br 1f;
2914 csb.l: jsr pc,wrdoff;
2915 1: sub $2,r0; jne e.illins;
2916 csb.1W: mov (sp)+,r0; mov (sp)+,r1;
2917 mov r0,pcx; mov 2(r0),r5
2918 /use pcx as ordinary register
2920 2: add $4,r0; cmp (r0),r1;
2922 3: mov (pcx),pcx; jeq e.case; next
2923 4: mov 2(r0),pcx; jeq e.case; next
2925 rck.l: jsr pc,wrdoff; br 1f;
2926 rck.z: mov (sp)+,r0;
2927 1: sub $2,r0; beq rck.1W;
2928 sub $2,r0; jne e.oddz;
2929 mov (sp)+,r1; cmp (sp),(r1);
2930 blt 9f; cmp (sp),4(r1);
2932 rck.1W: mov (sp)+,r1; cmp (sp),(r1);
2933 blt 9f; cmp (sp),2(r1);
2935 9: mov $ERANGE,-(sp); jmp trp.z;
2937 /------------------------------------------------------------------------------
2938 / Load and store register
2939 /------------------------------------------------------------------------------
2941 lor.s0: clr r0; bisb (pcx)+,r0
2942 cmp r0,$2; jhi e.illins
2944 1: br 2f; br 3f; br 4f
2945 2: mov lb,-(sp); next
2946 3: mov sp,r1; mov r1,-(sp); next
2947 4: mov hp,-(sp); next
2949 str.s0: clr r0; bisb (pcx)+,r0
2950 cmp r0,$2; jhi e.illins
2952 1: br 2f; br 3f; br 4f
2953 2: mov (sp)+,lb; next
2954 3: mov (sp)+,r1; mov r1,sp; next
2956 5: cmp r1,sybreak+2;
2957 blos 5f; add $unixextra,sybreak+2;
2958 sys indir;sybreak / ask for more core
2961 jsr pc,e.heap; / core claim failed
2963 5: cmp r1,globmax; jlo 1b
2966 /------------------------------------------------------------------------------
2968 ass.l: jsr pc,wrdoff; br 1f
2969 ass.z: mov (sp)+,r0;
2970 1: cmp $2,r0; beq 2f
2971 cmp $4,r0; jne e.oddz
2973 2: mov (sp)+,r0; br 3f
2974 asp.lw: jsr pc,wrdoff; br 2f
2975 asp.w0: clr r0; bisb (pcx)+,r0;
2977 asp.1W: asp.2W: asp.3W: asp.4W: asp.5W:
2979 3: blt 4f; add r0,sp; next
2981 2: mov $und,-(sp); sob r0,2b; next
2984 /------------------------------------------------------------------------------
2986 dch.z: mov (sp)+,r1; mov (r1),-(sp);
2987 cmp (sp),ml; jge e.badptr;
2988 next / dch adjusts local base to
2989 / dynamically previous local base
2991 lpb.z: add $8.,(sp); next / static link 8 bytes from lb
2993 /------------------------------------------------------------------------------
2995 gto.l: jsr pc,wrdoff; / get descriptor address
2996 add eb,r0 / descriptor is in external address space
2997 mov 4(r0),r2; / new local base after jump
2998 mov 2(r0),sp; / new stack pointer after jump
2999 mov (r0),pcx; / new program counter
3000 .if .prof + .flow + .count
3007 2: mov r0,curproc / procdesbase current proc
3008 mov 4(r0),countfld / restore pointer to
3009 sub 6(r0),countfld / table entries
3010 mov 10.(r0),*filb / file name restored
3013 /------------------------------------------------------------------------------
3015 /------------------------------------------------------------------------------
3017 lim.z: mov ignmask,-(sp); next / load ignore mask
3018 sim.z: mov (sp)+,ignmask; next / store ignore mask
3021 sig.z: mov (sp),r1; / exchange previous
3022 mov uerrorp,(sp); / and stacked error
3023 mov r1,uerrorp; / procedure pointer
3025 /------------------------------------------------------------------------------
3026 / Signals generated by UNIX
3027 /------------------------------------------------------------------------------
3030 mov $sig.trp+0.,-(sp); br 1f
3032 mov $sig.trp+2.,-(sp); br 1f
3034 mov $sig.trp+4.,-(sp); br 1f
3036 mov $sig.trp+24.,-(sp); br 1f
3038 mov $sig.trp+26.,-(sp); br 1f
3040 mov $sig.trp+28.,-(sp); br 1f
3042 mov $sig.trp+30.,-(sp) / push address trap number
3043 1: mov *(sp),-2(sp); / save trap number
3044 mov $-2,*(sp) / set defold trap number
3045 mov $retutrap,(sp) / set return address to rti
3046 tst -(sp) / trap number position on stack
3050 mov $2,r0; / fildes standard error
3051 sys 0; 9b / call write message
3052 sys signal;12.;sig12 / this is a mon-error
3057 sig11: mov r0,saver1 /save r0
3060 jgt e.memflt /real trap
3062 mov argv,sp /setup a new stack
3066 7: <stack overflow\n\0>
3068 sybreak:sys break;_end /For indirect calling of break
3070 sig8: mov r0,saver1;
3079 mov fpperr(r0),-(sp)
3084 fpperr: EILLINS; EILLINS; EFDIVZ; ECONV; EFOVFL; EFUNFL; EFUND; EILLINS
3086 /------------------------------------------------------------------------------
3087 / Errors,traps and all their friends
3089 /------------------------------------------------------------------------------
3091 savereg: mov r1,-(sp) / stack r1 so r1 scratch register
3092 mov 2(sp),r1 / now r1 contains return address
3093 mov r0,2(sp) / save r0
3094 mov r2,-(sp) / save r2
3095 mov r3,-(sp) / save r3
3096 mov r4,-(sp) / save r4
3097 mov r5,-(sp) / save r5
3098 mov 12.(sp),r0 / copy error number or param 0
3099 movf fr0,-(sp) / save float registers
3100 movf fr1,-(sp) / fr0 and fr1
3101 stfps -(sp) / and status
3104 8: mov -(r5),-(sp); sob r2,8b
3105 mov r0,-(sp) / extra errno (param 0) on stack
3106 mov r1,-(sp) / set return address
3109 restoreg: mov (sp)+,r1 / return address in r1
3110 add $2,sp / skip error number (param 0)
3113 8: mov (sp)+,(r5)+; sob r2,8b
3114 ldfps (sp)+ / restore floating point status
3115 movf (sp)+,fr1 / restore float registers
3116 movf (sp)+,fr0 / fr0 and fr1
3117 mov (sp)+,r5 / restore r5
3118 mov (sp)+,r4 / restore r4
3119 mov (sp)+,r3 / restore r3
3120 mov (sp)+,r2 / restore r2
3121 mov 2(sp),r0 / restore r0
3122 mov r1,2(sp) / reset return address
3123 mov (sp)+,r1 / restore r1
3126 /------------------------------------------------------------------------------
3127 / Various error entries
3128 /------------------------------------------------------------------------------
3130 e.badlfr: mov r0,r5; mov $2,r0; mov $blfr,9f+2
3139 e.iund: mov $EIUND,-(sp); br error
3140 e.iovfl: mov $EIOVFL,-(sp); br error
3141 e.idivz: mov $EIDIVZ,-(sp); br error
3142 e.range: mov $ERANGE,-(sp); br error
3143 e.set: mov $ESET,-(sp); br error
3144 e.badptr: mov $EBADPTR,-(sp); br fatal
3145 e.fovfl: mov $EFOVFL,-(sp); br error
3146 e.funfl: mov $EFUNFL,-(sp); br error
3147 e.fdivz: mov $EFDIVZ,-(sp); br error
3148 e.fund: mov $EFUND,-(sp); br error
3149 e.conv: mov $ECONV,-(sp); br error
3150 e.stack: mov $ESTACK,-(sp); br fatal
3151 e.badpc: mov $EBADPC,-(sp); br fatal
3152 e.badlin: mov $EBADLIN,-(sp); br error
3153 e.badlae: mov $EBADLAE,-(sp); br error
3154 e.array: mov $EARRAY,-(sp); br error
3155 e.badmon: mov $EBADMON,-(sp); br error
3156 e.case: mov $ECASE,-(sp); br fatal
3157 e.oddz: mov $EODDZ,-(sp); br fatal
3158 e.illins: mov $EILLINS,-(sp); br fatal
3159 e.heap: mov $EHEAP,-(sp); br error
3160 e.memflt: mov $EMEMFLT,-(sp); br fatal
3161 e.badgto: mov $EBADGTO,-(sp); br error
3162 /------------------------------------------------------------------------------
3164 fatal: mov $hlt.z,-(sp) / return from fatal halts
3165 mov 2(sp),-(sp) / dup error number
3167 jsr pc,savereg / save old register contents
3175 add $2,sp / remove error number from stack
3178 cmp uerrorp,$-1 / has the user defined a trapprocedure ?
3179 beq notrap / if not kill it off fast
3180 mov uerrorp,-(sp) / go for cal
3181 mov $-1,uerrorp / user must set trap again
3182 jbr precal / call trap routine
3184 /------------------------------------------------------------------------------
3186 rtt.z: mov r2,sp / sp to bottom frame
3187 add $8,sp / set to top frame
3188 jsr pc,restoreg / restore status and registers
3189 add $2,sp / skip error number
3191 /------------------------------------------------------------------------------
3192 trp.z: mov (sp),-(sp); / error number one down
3193 mov r4,2(sp); / set return address to main loop
3194 jbr error / call error routine
3196 /------------------------------------------------------------------------------
3198 notrap: mov (sp),r1 / error number
3200 mov r1,retarea / set error number for exit status
3201 jsr pc,itoa / make string
3205 mov *filb,8f / pointer to file name
3206 mov *eb,r1 / line number
3207 mov $line,8f+6 / line message
3209 jsr pc,itoa / convert to string
3211 2: mov (r4)+,r0 / next string
3214 4: tstb (r0)+ / find zero byte
3217 sub 9f+2,r0 / string length
3219 mov $2,r0 / diagnostic output
3239 uerrorp: -1 / undefined trap procedure
3241 line: < on source line \n\0>
3244 8: 0 / name of text file
3247 line+21. / line number if present
3252 /------------------------------------------------------------------------------
3253 / Exit instruction, with all it's crud
3254 /------------------------------------------------------------------------------
3258 .if .count + .flow + .prof
3269 2: <runinf file failed\n\0>
3318 mov retarea,r0 / set exit status
3321 /------------------------------------------------------------------------------
3322 / System call interface routine
3323 /------------------------------------------------------------------------------
3332 mov (sp)+,r0; / call number from stack
3333 cmp r0,$1 / sys exit ?
3334 jeq hlt.z / go there
3335 bit $177700,r0; / range 0-63?
3336 bne mon.bad; / no? bad call
3337 movb r0,call; / move call number in system call
3338 movb tab(r0),r5; / table lookup call conditions
3339 cmp r5,$-1; / compare for special context
3340 beq mon.special; / yes? jump to special context
3341 monmon: mov r5,r4; / save call conditions
3343 bcc 1f / check if bit 7 is on
3344 mov (sp)+,r0; / call argument in r0
3346 bcc 1f / check if bit 6 is on
3347 mov (sp)+,r1; / argument in r1
3348 1: bic $177770,r4 / clear all exept bits 2,1,0
3349 beq 2f / if 0 forget about args
3350 mov r3,saver1 / save r3
3351 mov $call+2,r3 / base of args for call
3352 1: mov (sp)+,(r3)+ / move argument
3353 sob r4,1b / look for more
3354 mov saver1,r3 / restore r3
3355 2: sys indir;call / this is it folks
3356 bcc 1f / no error set? forward
3357 mov r0,r4 / copy error in r4
3359 bcc 1f / check original bit 5
3360 mov r0,-(sp) / stack r0 from errno
3362 bcc 1f / check original bit 4
3363 mov r1,-(sp) / stack r1
3365 bcc mon.end / no c-bit then ready
3367 mov r4,-(sp) / stack errno
3368 beq mon.end / only once if no error
3369 mov r4,-(sp) / stack errno twice when error
3371 mov $loop,r4 / restore r4
3374 mon.special: / special calls decoded here
3375 cmp r0,$fork / fork?
3377 cmp r0,$signal / signal?
3379 mon.bad: / otherwise undecodable
3380 mov saver0,r4 / restore r4
3381 jsr pc,e.badmon / mon call error routine
3396 mov (sp)+,r1 / trap number
3397 mov (sp)+,r0 / signal number
3398 cmp r0,$16. / only 1 - 16 legal
3400 mov r0,call+2 / move signal number into call
3401 beq sig.bad / 0 illegal
3402 asl r0 / make 2-32 and even
3403 mov sig.trp-2(r0),r5 / previous trap number
3404 cmp r1,$256. / values -1 and -2 special
3406 mov sig.adr-2(r0),r4 / zero label means illegal signal
3409 mov $EINVAL,r4 / bad signal
3410 jbr mon.cbit / and continue
3411 1: cmp r1,$-3 / -2: reset default, -3: ignore
3413 mov r1,r4 / trap number in r4
3415 inc r4 / -2 -> 0, -3 -> -1
3416 2: mov r1,sig.trp-2(r0) / new trap number
3417 / -3 if ignored; -2 if default action
3418 mov r4,call+4 / translated trap number in call
3421 bcs sig.bad / unlikely to happen
3422 asr r0 / special if old label odd
3424 mov $-3,r5 / set ignore signal
3425 1: mov r5,-(sp) / push trap number
3431 call: sys 0; 0; 0; 0; 0
3433 -2; -2; -2; -2; -2; -2; -2; -2
3434 -2; -2; 21.; 25.; -2; -2; -2; -2
3436 sig1; sig2; sig3; 0; 0; 0; 0; sig8
3437 0; 0; sig11; sig12; sig13; sig14; sig15; sig16
3441 .byte -1 / 0 = indir
3444 .byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
3445 .byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
3446 .byte 2 +R0_OUT +CBIT / 5 = open
3447 .byte 0 +R0_IN +CBIT / 6 = close
3448 .byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
3449 .byte 2 +R0_OUT +CBIT / 8 = creat
3450 .byte 2 +CBIT / 9 = link
3451 .byte 1 +CBIT / 10 = unlink
3452 .byte 2 +CBIT / 11 = exec
3453 .byte 1 +CBIT / 12 = chdir
3454 .byte 0 +R0_OUT +R1_OUT / 13 = time
3455 .byte 3 +CBIT / 14 = mknod
3456 .byte 2 +CBIT / 15 = chmod
3457 .byte 2 +CBIT / 16 = chown
3458 .byte -1 / 17 = break
3459 .byte 2 +CBIT / 18 = stat
3460 .byte 2 +R0_IN +CBIT / 19 = seek
3461 .byte 0 +R0_OUT / 20 = getpid
3462 .byte 3 +CBIT / 21 = mount
3463 .byte 1 +CBIT / 22 = umount
3464 .byte 0 +R0_IN +CBIT / 23 = setuid
3465 .byte 0 +R0_OUT / 24 = getuid
3466 .byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
3467 .byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
3469 .byte 1 +R0_IN +CBIT / 28 = fstat
3472 .byte 1 +R0_IN +CBIT / 31 = stty
3473 .byte 1 +R0_IN +CBIT / 32 = gtty
3475 .byte 0 +R0_IN +CBIT / 34 = nice
3476 .byte 0 +R0_IN / 35 = sleep
3478 .byte 1 +R0_IN +CBIT / 37 = kill
3479 .byte 0 +R0_OUT / 38 = csw
3482 .byte 0 +R0_IN +R0_OUT +CBIT / 41 = dup
3483 .byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
3484 .byte 1 / 43 = times
3487 .byte 0 +R0_IN +CBIT / 46 = setgid
3488 .byte 0 +R0_OUT / 47 = getgid
3489 .byte -1 / 48 = signal
3490 .byte -1 / 49 = reserved for USG
3491 .byte -1 / 50 = reserved for USG
3508 .byte -1 / 0 = indir
3511 .byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
3512 .byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
3513 .byte 2 +R0_OUT +CBIT / 5 = open
3514 .byte 0 +R0_IN +CBIT / 6 = close
3515 .byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
3516 .byte 2 +R0_OUT +CBIT / 8 = creat
3517 .byte 2 +CBIT / 9 = link
3518 .byte 1 +CBIT / 10 = unlink
3519 .byte 2 +CBIT / 11 = exec
3520 .byte 1 +CBIT / 12 = chdir
3521 .byte 0 +R0_OUT +R1_OUT / 13 = time
3522 .byte 3 +CBIT / 14 = mknod
3523 .byte 2 +CBIT / 15 = chmod
3524 .byte 2 +CBIT / 16 = chown
3525 .byte -1 / 17 = break
3526 .byte 2 +CBIT / 18 = stat
3527 .byte 2 +R0_IN +CBIT / 19 = seek
3528 .byte 0 +R0_OUT / 20 = getpid
3529 .byte 3 +CBIT / 21 = mount
3530 .byte 1 +CBIT / 22 = umount
3531 .byte 0 +R0_IN +CBIT / 23 = setuid
3532 .byte 0 +R0_OUT / 24 = getuid
3533 .byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
3534 .byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
3535 .byte 0 +R0_IN +R0_OUT / 27 = alarm
3536 .byte 1 +R0_IN +CBIT / 28 = fstat
3537 .byte 0 / 29 = pause
3539 .byte 1 +R0_IN +CBIT / 31 = stty
3540 .byte 1 +R0_IN +CBIT / 32 = gtty
3541 .byte 2 +CBIT / 33 = access
3542 .byte 0 +R0_IN +CBIT / 34 = nice
3543 .byte 0 +R0_IN / 35 = sleep
3545 .byte 1 +R0_IN +CBIT / 37 = kill
3546 .byte 0 +R0_OUT / 38 = csw
3548 .byte 0 +R0_IN +R0_OUT +R1_OUT +CBIT / 40 = tell
3549 .byte 0 +R0_IN +R0_OUT +CBIT / 41 = dup
3550 .byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
3551 .byte 1 / 43 = times
3554 .byte 0 +R0_IN +CBIT / 46 = setgid
3555 .byte 0 +R0_OUT / 47 = getgid
3556 .byte -1 / 48 = signal
3557 .byte -1 / 49 = reserved for USG
3558 .byte -1 / 50 = reserved for USG
3559 .byte 1 +CBIT / 51 = acct
3575 .byte -1 / 0 = indir
3578 .byte 2 +R0_IN +R0_OUT +CBIT / 3 = read
3579 .byte 2 +R0_IN +R0_OUT +CBIT / 4 = write
3580 .byte 2 +R0_OUT +CBIT / 5 = open
3581 .byte 0 +R0_IN +CBIT / 6 = close
3582 .byte 0 +R0_OUT +R1_OUT +CBIT / 7 = wait
3583 .byte 2 +R0_OUT +CBIT / 8 = creat
3584 .byte 2 +CBIT / 9 = link
3585 .byte 1 +CBIT / 10 = unlink
3586 .byte -1 / 11 = x no exec in em code
3587 .byte 1 +CBIT / 12 = chdir
3588 .byte -1 / 13 = x time is obsolete
3589 .byte 3 +CBIT / 14 = mknod
3590 .byte 2 +CBIT / 15 = chmod
3591 .byte 3 +CBIT / 16 = chown
3592 .byte -1 / 17 = break
3593 .byte 2 +CBIT / 18 = stat
3594 .byte 3 +R0_IN +R0_OUT +R1_OUT +CBIT / 19 = lseek
3595 .byte 0 +R0_OUT / 20 = getpid
3596 .byte 3 +CBIT / 21 = mount
3597 .byte 1 +CBIT / 22 = umount
3598 .byte 0 +R0_IN +CBIT / 23 = setuid
3599 .byte 0 +R0_OUT +R1_OUT / 24 = getuid
3600 .byte 0 +R1_IN +R0_IN +CBIT / 25 = stime
3601 .byte 3 +R0_IN +R0_OUT +CBIT / 26 = ptrace
3602 .byte 0 +R0_IN +R0_OUT / 27 = alarm
3603 .byte 1 +R0_IN +CBIT / 28 = fstat
3604 .byte 0 / 29 = pause
3605 .byte 2 +CBIT / 30 = utime
3608 .byte 2 +CBIT / 33 = access
3609 .byte 0 +R0_IN +CBIT / 34 = nice
3610 .byte 1 / 35 = ftime
3612 .byte 1 +R0_IN +CBIT / 37 = kill
3616 .byte 0 +R1_IN +R0_IN +R0_OUT +CBIT / 41 = dup
3617 .byte 0 +R0_OUT +R1_OUT +CBIT / 42 = pipe
3618 .byte 1 / 43 = times
3621 .byte 0 +R0_IN +CBIT / 46 = setgid
3622 .byte 0 +R0_OUT +R1_OUT / 47 = getgid
3623 .byte -1 / 48 = signal
3624 .byte -1 / 49 = reserved for USG
3625 .byte -1 / 50 = reserved for USG
3626 .byte 1 +CBIT / 51 = acct
3627 .byte 3 +CBIT / 52 = phys
3628 .byte 1 +CBIT / 53 = lock
3629 .byte 3 +CBIT / 54 = ioctl
3631 .byte 2 +CBIT / 56 = mpxcall
3634 .byte 3 +CBIT / 59 = exece
3635 .byte 1 +CBIT / 60 = umask
3636 .byte 1 +CBIT / 61 = chroot
3642 /------------------------------------------------------------------------------
3643 / General subroutines
3644 /------------------------------------------------------------------------------
3646 wrdoff: movb (pcx)+,r0 /get first byte
3647 swab r0 /put it in high byte
3648 clrb r0 /clear low byte of r0
3649 bisb (pcx)+,r0 /"or" second byte in
3652 /------------------------------------------------------------------------------
3654 tstr0: cmp r0,$04; jgt e.oddz;
3655 cmp r0,$02; jne e.oddz; rts pc
3657 chckptr: / this routine traps a pointer outside
3658 / the globals, the stack or the heap
3659 bit $1,2(sp); bne 8f
3664 .if .count + .prof + .flow
3665 cmp r5,tblmax; bhis 9f
3666 cmp r5,globmax; bhis 8f
3673 nexttab: mov linused,r5;
3674 add $2,r5 / increment lasttab
3675 cmp r5,$linused / top of table reached?
3683 mov $[savearea+2],r5
3689 mov $[savearea+6],r5
3718 /------------------------------------------------------------------------------
3720 /------------------------------------------------------------------------------
3733 ignmask:.=.+2 / ignore mask for trap
3734 retsize:.=.+2 / size of return value of function
3735 retarea:.=.+8 / return area for function value
3736 savearea: .=.+8 / save register area
3740 txtsiz: .=.+2 / program textsize in bytes
3741 ndatad: .=.+2 / number of loadfile descriptors
3742 nprocs: .=.+2 / number of entries in procedure descriptors
3743 option: entry.: .=.+2 / procedure number to start
3744 nlines: .=.+2 / maximum sorceline number
3745 szdata: .=.+2 / address of lowest uninitialized byte
3746 firstp: .=.+2 / descriptor address first basic block of text
3747 maxcount: .=.+2 / total number of processable source lines
3760 lasttab:.=.+96. / 16 descriptors of integers + index at the end