2.11BSD/sys/pdp/mch_backup.s
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)mch_backup.s 1.2 (2.11BSD GTE) 12/26/92
*/
#include "DEFS.h"
SPACE(GLOBAL, ssr, 3*2) / contents of MM registers SSR0-2
/ after trap
/*
* unwind(ar0::r0, mod::r1)
* caddr_t ar0;
* u_char mod;
*
* Unwind a register modification from a partially completed aborted
* instruction. Ar0 is the address of the user's register r0 as saved in
* the stack (_regloc contains the relative indexes of the the user's
* registers from ar0). Mod contains a register modification recorded as:
*
* 7 3 2 0
* +------------------------+
* | displacement | reg |
* +------------------------+
*
* where "reg" is the index of the modified register and displacement is
* the 2's complement displacement of the modification.
*/
unwind:
mov r1,-(sp) / grab displacement
asr (sp) / tmp = mod >> 3 { signed shift }
asr (sp)
asr (sp)
bic $!7,r1 / mod = _regloc[mod&7] * sizeof(int)
movb _regloc(r1),r1
asl r1
add r0,r1 / ar0[mod] -= tmp
sub (sp)+,(r1)
rts pc
/*
* backup(ar0)
* caddr_t ar0;
*
* Back up user CPU state after aborted instruction. Called from trap when
* attempting an automatic stack grow to restore the user's state prior to
* a stack fault. Returns zero if successful.
*/
#ifndef KERN_NONSEP
/*
* Backup routine for use with machines with SSR1 and SSR2 (saved in ssr+2
* and ssr+4 by trap). SSR1 records any auto-increments and/or decrements
* that were already performed for the aborted instruction. SSR2 holds
* the adddress of the instruction which faulted.
*/
ENTRY(backup)
mov 2(sp),r0 / r0 = ar0
movb ssr+2,r1 / undo first register modification from
jsr pc,unwind / saved SSR1
movb ssr+3,r1 / and second ...
jsr pc,unwind
movb _regloc+7,r1 / ar0[_regloc[PC] * sizeof(int)]
asl r1 / = saved SSR2
add r0,r1
mov ssr+4,(r1)
clr r0 / and return success
rts pc
#else KERN_NONSEP
/*
* 11/40 version of backup, for use with no SSR1 and SSR2. Actually SSR1
* usually exists for all processors except the '34 and '40 but always
* reads as zero on those without separate I&D ...
*/
.bss
bflg: .=.+1
jflg: .=.+1
fflg: .=.+1
.text
ENTRY(backup)
mov 2(sp),ssr+2 / pass ar0 to the real backup routine
mov r2,-(sp) / backup needs an extra register
jsr pc,backup
mov r2,ssr+2 / save computed register modification
mov (sp)+,r2 / mask and restore r2
movb jflg,r0 / if backup failed, return failure
bne 1f
mov 2(sp),r0 / r0 = ar0
movb ssr+2,r1 / undo register modifications
jsr pc,unwind
movb ssr+3,r1
jsr pc,unwind
movb _regloc+7,r1 / ar0[_regloc[PC] * sizeof(int)] =
asl r1 / computed fault pc
add r0,r1
mov ssr+4,(r1)
clr r0 / and indicate success
2:
rts pc
/*
* Hard part: simulate the ssr2 register missing on 11/40 and similar
* processors.
*/
backup:
clr r2 / backup register ssr1
mov $1,bflg / clrs jflg
clrb fflg
mov ssr+4,r0
jsr pc,fetch
mov r0,r1
ash $-11.,r0
bic $!36,r0
jmp *0f(r0)
0: t00; t01; t02; t03; t04; t05; t06; t07
t10; t11; t12; t13; t14; t15; t16; t17
t00:
clrb bflg
t10:
mov r1,r0
swab r0
bic $!16,r0
jmp *0f(r0)
0: u0; u1; u2; u3; u4; u5; u6; u7
u6: / single op, m[tf]pi, sxt, illegal
bit $400,r1
beq u5 / all but m[tf], sxt
bit $200,r1
beq 1f / mfpi
bit $100,r1
bne u5 / sxt
/ Simulate mtpi with double (sp)+,dd.
bic $4000,r1 / turn instr into (sp)+
br t01
/ Simulate mfpi with double ss,-(sp).
1:
ash $6,r1
bis $46,r1 / -(sp)
br t01
u4: / jsr
mov r1,r0
jsr pc,setreg / assume no fault
bis $173000,r2 / -2 from sp
rts pc
t07: / EIS
clrb bflg
u0: / jmp, swab
u5: / single op
f5: / movei, movfi
ff1: / ldfps
ff2: / stfps
ff3: / stst
mov r1,r0
br setreg
t01: / mov
t02: / cmp
t03: / bit
t04: / bic
t05: / bis
t06: / add
t16: / sub
clrb bflg
t11: / movb
t12: / cmpb
t13: / bitb
t14: / bicb
t15: / bisb
mov r1,r0
ash $-6,r0
jsr pc,setreg
swab r2
mov r1,r0
jsr pc,setreg
/ If delta(dest) is zero, no need to fetch source.
bit $370,r2
beq 1f
/ If mode(source) is R, no fault is possible.
bit $7000,r1
beq 1f
/ If reg(source) is reg(dest), too bad.
mov r2,-(sp)
bic $174370,(sp)
cmpb 1(sp),(sp)+
beq u7
/ Start source cycle. Pick up value of reg.
mov r1,r0
ash $-6,r0
bic $!7,r0
movb _regloc(r0),r0
asl r0
add ssr+2,r0
mov (r0),r0
/ If reg has been incremented, must decrement it before fetch.
bit $174000,r2
ble 2f
dec r0
bit $10000,r2
beq 2f
dec r0
2:
/ If mode is 6,7 fetch and add X(R) to R.
bit $4000,r1
beq 2f
bit $2000,r1
beq 2f
mov r0,-(sp)
mov ssr+4,r0
add $2,r0
jsr pc,fetch
add (sp)+,r0
2:
/ Fetch operand. If mode is 3, 5, or 7, fetch *.
jsr pc,fetch
bit $1000,r1
beq 1f
bit $6000,r1
bne fetch
1:
rts pc
t17: / floating point instructions
clrb bflg
mov r1,r0
swab r0
bic $!16,r0
jmp *0f(r0)
0: f0; f1; f2; f3; f4; f5; f6; f7
f0:
mov r1,r0
ash $-5,r0
bic $!16,r0
jmp *0f(r0)
0: ff0; ff1; ff2; ff3; ff4; ff5; ff6; ff7
f1: / mulf, modf
f2: / addf, movf
f3: / subf, cmpf
f4: / movf, divf
ff4: / clrf
ff5: / tstf
ff6: / absf
ff7: / negf
inc fflg
mov r1,r0
br setreg
f6:
bit $400,r1
beq f1 / movfo
br f5 / movie
f7:
bit $400,r1
beq f5 / movif
br f1 / movof
ff0: / cfcc, setf, setd, seti, setl
u1: / br
u2: / br
u3: / br
u7: / illegal
incb jflg
rts pc
setreg:
mov r0,-(sp)
bic $!7,r0
bis r0,r2
mov (sp)+,r0
ash $-3,r0
bic $!7,r0
movb 0f(r0),r0
tstb bflg
beq 1f
bit $2,r2
beq 2f
bit $4,r2
beq 2f
1:
cmp r0,$20
beq 2f
cmp r0,$-20
beq 2f
asl r0
2:
tstb fflg
beq 3f
asl r0
stfps r1
bit $200,r1
beq 3f
asl r0
3:
bisb r0,r2
rts pc
0: .byte 0,0,10,20,-10,-20,0,0
fetch:
bic $1,r0
mov nofault,-(sp)
mov $1f,nofault
mfpi (r0)
mov (sp)+,r0
mov (sp)+,nofault
rts pc
1:
mov (sp)+,nofault
clrb r2 / clear out dest on fault
mov $-1,r0
rts pc
#endif KERN_NONSEP