Add test for EM _rck_. Fix traps in PowerPC ncg.
The new test rck_e.e segfaults on PowerPC unless I make some changes. The inline code for _rck_ was wrong because it didn't allow the trap handler to return. _sig_ forgot to push the old trap handler. Move plat/linuxppc/libsys/trap.s to mach/powerpc/libem/trp.s and rewrite it with simplified/extended mnemonics. Remove .trap alias for .trp procedure. Add a missing `mtspr lr, r0` so we can return from the trap handler. Call write() and _exit() so trp.s works with both linuxppc and osxppc. Before, Mac OS X was wrongly using the trap.s for Linux. In powerpc/libem, simplify .aar4; teach .csa and .csb to raise the trap if the default target is zero. C programs don't need these changes. You may relink your C programs with the changed .csa and .csb, but C code doesn't raise the trap. Modula-2 code can raise traps, so you may want to relink your Modula-2 programs with the changed libem, but you might keep your old .o files from Modula-2. You may need to recompile your Pascal programs (delete old .o files from Pascal) because the Pascal compiler might use _rck_.
This commit is contained in:
parent
5f2a7b260f
commit
26de4c1ab1
|
@ -8,21 +8,17 @@
|
||||||
|
|
||||||
.define .aar4
|
.define .aar4
|
||||||
.aar4:
|
.aar4:
|
||||||
lis r0, hi16[.trap_earray]
|
|
||||||
ori r0, r0, lo16[.trap_earray]
|
|
||||||
mtspr ctr, r0 ! load CTR with trap address
|
|
||||||
|
|
||||||
lwz r4, 0(sp) ! r4 = address of descriptor
|
lwz r4, 0(sp) ! r4 = address of descriptor
|
||||||
lwz r5, 4(sp) ! r5 = index
|
lwz r5, 4(sp) ! r5 = index
|
||||||
lwz r6, 8(sp) ! r6 = address of array
|
lwz r6, 8(sp) ! r6 = address of array
|
||||||
|
|
||||||
lwz r0, 0(r4)
|
lwz r0, 0(r4)
|
||||||
subf. r5, r0, r5 ! subtract lower bound from index
|
subf. r5, r0, r5 ! subtract lower bound from index
|
||||||
bltctr ! check lower bound
|
blt .trap_earray ! check lower bound
|
||||||
|
|
||||||
lwz r0, 4(r4)
|
lwz r0, 4(r4)
|
||||||
cmplw r5, r0
|
cmplw r5, r0
|
||||||
bgtctr ! check upper bound
|
bgt .trap_earray ! check upper bound
|
||||||
|
|
||||||
lwz r3, 8(r4) ! r3 = size of element
|
lwz r3, 8(r4) ! r3 = size of element
|
||||||
mullw r5, r5, r3 ! scale index by size
|
mullw r5, r5, r3 ! scale index by size
|
||||||
|
@ -30,3 +26,7 @@
|
||||||
stw r6, 8(sp) ! push address of element
|
stw r6, 8(sp) ! push address of element
|
||||||
addi sp, sp, 8
|
addi sp, sp, 8
|
||||||
blr
|
blr
|
||||||
|
|
||||||
|
.trap_earray:
|
||||||
|
li r3, 0 ! EARRAY = 0 in h/em_abs.h
|
||||||
|
b .trp
|
||||||
|
|
|
@ -6,7 +6,7 @@ for _, plat in ipairs(vars.plats) do
|
||||||
acklibrary {
|
acklibrary {
|
||||||
name = "lib_"..plat,
|
name = "lib_"..plat,
|
||||||
srcs = {
|
srcs = {
|
||||||
"./*.s", -- exg.s
|
"./*.s", -- trp.s
|
||||||
},
|
},
|
||||||
vars = { plat = plat },
|
vars = { plat = plat },
|
||||||
deps = {
|
deps = {
|
||||||
|
@ -15,4 +15,3 @@ for _, plat in ipairs(vars.plats) do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -13,22 +13,21 @@
|
||||||
lwz r4, 4(sp)
|
lwz r4, 4(sp)
|
||||||
addi sp, sp, 8
|
addi sp, sp, 8
|
||||||
|
|
||||||
lwz r5, 0(r3) ! load default
|
lwz r5, 0(r3) ! r5 = default target
|
||||||
mtspr ctr, r5
|
|
||||||
|
|
||||||
lwz r5, 4(r3) ! fetch lower bound
|
|
||||||
subf. r4, r5, r4 ! adjust value
|
|
||||||
bltctr ! jump to default if out of range
|
|
||||||
|
|
||||||
lwz r5, 8(r3) ! fetch range
|
lwz r6, 4(r3) ! fetch lower bound
|
||||||
cmplw r4, r5
|
subf. r4, r6, r4 ! adjust value
|
||||||
bgtctr ! jump to default if out of range
|
blt 1f ! jump to default if out of range
|
||||||
|
|
||||||
|
lwz r6, 8(r3) ! fetch range
|
||||||
|
cmplw r4, r6
|
||||||
|
bgt 1f ! jump to default if out of range
|
||||||
|
|
||||||
addi r3, r3, 12 ! skip header
|
addi r3, r3, 12 ! skip header
|
||||||
slwi r4, r4, 2 ! scale value (<<2)
|
slwi r4, r4, 2 ! scale value (<<2)
|
||||||
lwzx r5, r3, r4 ! load target
|
lwzx r5, r3, r4 ! r5 = new target
|
||||||
mtspr ctr, r5
|
|
||||||
|
|
||||||
or. r5, r5, r5 ! test it
|
1: mtspr ctr, r5
|
||||||
|
mr. r5, r5 ! test it
|
||||||
bnectr ! jump to target if non-zero
|
bnectr ! jump to target if non-zero
|
||||||
b .trap_ecase ! otherwise trap
|
b .trap_ecase ! otherwise trap
|
||||||
|
|
|
@ -13,23 +13,20 @@
|
||||||
lwz r4, 4(sp)
|
lwz r4, 4(sp)
|
||||||
addi sp, sp, 8
|
addi sp, sp, 8
|
||||||
|
|
||||||
lwz r5, 0(r3) ! load default
|
lwz r5, 0(r3) ! r5 = default target
|
||||||
mtspr ctr, r5
|
|
||||||
|
|
||||||
lwz r6, 4(r3) ! fetch count
|
lwz r6, 4(r3) ! fetch count
|
||||||
|
mr. r6, r6 ! skip loop if count is zero
|
||||||
1:
|
beq 3f ! (needed by Modula-2 "CASE i OF END")
|
||||||
or. r6, r6, r6 ! test count
|
mtspr ctr, r6
|
||||||
beqctr ! exit if zero
|
1: lwzu r7, 8(r3) ! fetch target index, increment pointer
|
||||||
addi r6, r6, -1 ! otherwise decrement
|
|
||||||
|
|
||||||
lwzu r7, 8(r3) ! fetch target index, increment pointer
|
|
||||||
cmpw r4, r7 ! compare with value
|
cmpw r4, r7 ! compare with value
|
||||||
bne 1b ! if not equal, go again
|
beq 2f
|
||||||
|
bdnz 1b ! if not equal, go again
|
||||||
|
b 3f
|
||||||
|
|
||||||
lwz r7, 4(r3) ! fetch target address
|
2: lwz r5, 4(r3) ! r5 = new target
|
||||||
mtspr ctr, r7
|
3: mtspr ctr, r5
|
||||||
|
mr. r5, r5 ! test target
|
||||||
or. r7, r7, r7 ! test it
|
|
||||||
bnectr ! jump to target if non-zero
|
bnectr ! jump to target if non-zero
|
||||||
b .trap_ecase ! otherwise trap
|
b .trap_ecase ! otherwise trap
|
||||||
|
|
|
@ -18,3 +18,7 @@
|
||||||
bgt .trap_erange
|
bgt .trap_erange
|
||||||
|
|
||||||
blr
|
blr
|
||||||
|
|
||||||
|
.trap_erange:
|
||||||
|
li r3, 1 ! ERANGE = 1 in h/em_abs.h
|
||||||
|
b .trp
|
||||||
|
|
56
mach/powerpc/libem/trp.s
Normal file
56
mach/powerpc/libem/trp.s
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
.sect .text
|
||||||
|
|
||||||
|
.define .trap_ecase
|
||||||
|
.trap_ecase:
|
||||||
|
li r3, 20 ! ECASE = 20 in h/em_abs.h
|
||||||
|
! FALLTHROUGH to .trp
|
||||||
|
|
||||||
|
! Raises an EM trap.
|
||||||
|
! Expects r3 = trap number.
|
||||||
|
|
||||||
|
.define .trp
|
||||||
|
.trp:
|
||||||
|
cmplwi r3, 15 ! traps > 15 can't be ignored
|
||||||
|
bgt 1f
|
||||||
|
|
||||||
|
lis r4, ha16[.ignmask]
|
||||||
|
lwz r4, lo16[.ignmask](r4) ! load ignore mask
|
||||||
|
srw r4, r4, r3
|
||||||
|
andi. r4, r4, 1
|
||||||
|
bnelr ! return if ignoring trap
|
||||||
|
|
||||||
|
1: lis r4, ha16[.trppc]
|
||||||
|
lwz r5, lo16[.trppc](r4) ! r5 = user trap routine
|
||||||
|
mr. r5, r5
|
||||||
|
beq 2f ! if no user trap routine, bail out
|
||||||
|
|
||||||
|
mtspr ctr, r5
|
||||||
|
mfspr r6, lr
|
||||||
|
li r0, 0
|
||||||
|
stwu r3, -8(sp) ! push trap number
|
||||||
|
stw r0, lo16[.trppc](r4) ! reset trap routine
|
||||||
|
stw r6, 4(sp) ! save old lr
|
||||||
|
bctrl ! call trap routine
|
||||||
|
|
||||||
|
lwz r0, 4(sp)
|
||||||
|
mtspr lr, r0
|
||||||
|
addi sp, sp, 8 ! retract over stack usage
|
||||||
|
blr
|
||||||
|
|
||||||
|
2: ! No trap handler. Write error message, exit.
|
||||||
|
li r3, 2
|
||||||
|
stwu r3, -12(sp)
|
||||||
|
lis r4, ha16[message]
|
||||||
|
addi r4, r4, lo16[message]
|
||||||
|
li r5, 6
|
||||||
|
stw r4, 4(sp)
|
||||||
|
stw r5, 8(sp)
|
||||||
|
bl _write ! write(2, message, 6)
|
||||||
|
|
||||||
|
li r3, 1
|
||||||
|
stw r3, 0(sp)
|
||||||
|
bl __exit ! _exit(1)
|
||||||
|
|
||||||
|
.sect .rom
|
||||||
|
message:
|
||||||
|
.ascii "TRAP!\n"
|
|
@ -2168,10 +2168,13 @@ PATTERNS
|
||||||
pat trp /* Raise EM trap */
|
pat trp /* Raise EM trap */
|
||||||
with REG3
|
with REG3
|
||||||
kills ALL
|
kills ALL
|
||||||
gen bl {LABEL, ".trap"}
|
gen bl {LABEL, ".trp"}
|
||||||
|
|
||||||
pat sig /* Set trap handler */
|
pat sig /* Set trap handler, yield old */
|
||||||
leaving ste ".trppc"
|
leaving
|
||||||
|
loe ".trppc"
|
||||||
|
exg 4
|
||||||
|
ste ".trppc"
|
||||||
|
|
||||||
pat rtt /* Return from trap */
|
pat rtt /* Return from trap */
|
||||||
leaving ret 0
|
leaving ret 0
|
||||||
|
@ -2216,22 +2219,14 @@ PATTERNS
|
||||||
with REG
|
with REG
|
||||||
gen move %1, sp
|
gen move %1, sp
|
||||||
|
|
||||||
pat lae rck $2==4 /* Range check */
|
pat rck $1==4 /* Range check */
|
||||||
with REG
|
leaving cal ".rck"
|
||||||
kills ALL
|
|
||||||
gen
|
|
||||||
cmpwi %1, {C, rom($1, 1)}
|
|
||||||
blt {LABEL, ".trap_erange"}
|
|
||||||
cmpwi %1, {C, rom($1, 2)}
|
|
||||||
bgt {LABEL, ".trap_erange"}
|
|
||||||
yields %1
|
|
||||||
|
|
||||||
|
|
||||||
/* Single-precision floating-point */
|
/* Single-precision floating-point */
|
||||||
|
|
||||||
pat zrf $1==4 /* Push zero */
|
pat zrf $1==4 /* Push zero */
|
||||||
leaving
|
leaving loe ".fs_00000000"
|
||||||
loe ".fs_00000000"
|
|
||||||
|
|
||||||
pat adf $1==4 /* Add single */
|
pat adf $1==4 /* Add single */
|
||||||
with FSREG FSREG
|
with FSREG FSREG
|
||||||
|
|
|
@ -4,7 +4,6 @@ acklibrary {
|
||||||
"./_syscall.s",
|
"./_syscall.s",
|
||||||
"./sigaction.s",
|
"./sigaction.s",
|
||||||
"./signal.c",
|
"./signal.c",
|
||||||
"./trap.s",
|
|
||||||
"plat/linux/libsys/_exit.c",
|
"plat/linux/libsys/_exit.c",
|
||||||
"plat/linux/libsys/_hol0.s",
|
"plat/linux/libsys/_hol0.s",
|
||||||
"plat/linux/libsys/close.c",
|
"plat/linux/libsys/close.c",
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
#
|
|
||||||
! $Source: /cvsroot/tack/Ack/plat/linux386/libsys/_syscall.s,v $
|
|
||||||
! $State: Exp $
|
|
||||||
! $Revision: 1.1 $
|
|
||||||
|
|
||||||
! Declare segments (the order is important).
|
|
||||||
|
|
||||||
.sect .text
|
|
||||||
.sect .rom
|
|
||||||
.sect .data
|
|
||||||
.sect .bss
|
|
||||||
|
|
||||||
.sect .text
|
|
||||||
|
|
||||||
#define IFFALSE 4
|
|
||||||
#define IFTRUE 12
|
|
||||||
#define ALWAYS 20
|
|
||||||
|
|
||||||
#define LT 0
|
|
||||||
#define GT 1
|
|
||||||
#define EQ 2
|
|
||||||
#define OV 3
|
|
||||||
|
|
||||||
EARRAY = 0
|
|
||||||
ERANGE = 1
|
|
||||||
ESET = 2
|
|
||||||
EIOVFL = 3
|
|
||||||
EFOVFL = 4
|
|
||||||
EFUNFL = 5
|
|
||||||
EIDIVZ = 6
|
|
||||||
EFDIVZ = 7
|
|
||||||
EIUND = 8
|
|
||||||
EFUND = 9
|
|
||||||
ECONV = 10
|
|
||||||
ESTACK = 16
|
|
||||||
EHEAP = 17
|
|
||||||
EILLINS = 18
|
|
||||||
EODDZ = 19
|
|
||||||
ECASE = 20
|
|
||||||
EMEMFLT = 21
|
|
||||||
EBADPTR = 22
|
|
||||||
EBADPC = 23
|
|
||||||
EBADLAE = 24
|
|
||||||
EBADMON = 25
|
|
||||||
EBADLIN = 26
|
|
||||||
EBADGTO = 27
|
|
||||||
EUNIMPL = 63 ! unimplemented em-instruction called
|
|
||||||
|
|
||||||
! EM trap handling.
|
|
||||||
|
|
||||||
.define .trap_ecase
|
|
||||||
.trap_ecase:
|
|
||||||
addi r3, r0, ECASE
|
|
||||||
b .trap
|
|
||||||
|
|
||||||
.define .trap_earray
|
|
||||||
.trap_earray:
|
|
||||||
addi r3, r0, EARRAY
|
|
||||||
b .trap
|
|
||||||
|
|
||||||
.define .trap_erange
|
|
||||||
.trap_erange:
|
|
||||||
addi r3, r0, ERANGE
|
|
||||||
b .trap
|
|
||||||
|
|
||||||
.define .trp
|
|
||||||
.define .trap
|
|
||||||
.trp:
|
|
||||||
.trap:
|
|
||||||
cmpi cr0, 0, r3, 15 ! traps >15 can't be ignored
|
|
||||||
bc IFTRUE, LT, 1f
|
|
||||||
|
|
||||||
addi r4, r0, 1
|
|
||||||
rlwnm r4, r4, r3, 0, 31 ! calculate trap bit
|
|
||||||
li32 r5, .ignmask
|
|
||||||
lwz r5, 0(r5) ! load ignore mask
|
|
||||||
and. r4, r4, r5 ! compare
|
|
||||||
bclr IFFALSE, EQ, 0 ! return if non-zero
|
|
||||||
|
|
||||||
1:
|
|
||||||
li32 r4, .trppc
|
|
||||||
lwz r5, 0(r4) ! load user trap routine
|
|
||||||
or. r5, r5, r5 ! test
|
|
||||||
bc IFTRUE, EQ, fatal ! if no user trap routine, bail out
|
|
||||||
|
|
||||||
addi r0, r0, 0
|
|
||||||
stw r0, 0(r4) ! reset trap routine
|
|
||||||
|
|
||||||
mfspr r0, lr
|
|
||||||
stwu r0, -4(sp) ! save old lr
|
|
||||||
|
|
||||||
stwu r3, -4(sp)
|
|
||||||
mtspr ctr, r5
|
|
||||||
bcctrl ALWAYS, 0, 0 ! call trap routine
|
|
||||||
|
|
||||||
lwz r0, 4(sp) ! load old lr again
|
|
||||||
addi sp, sp, 8 ! retract over stack usage
|
|
||||||
bclr ALWAYS, 0, 0 ! return
|
|
||||||
|
|
||||||
fatal:
|
|
||||||
addi r3, r0, 1
|
|
||||||
li32 r4, message
|
|
||||||
addi r5, r0, 6
|
|
||||||
addi r0, r0, 4 ! write()
|
|
||||||
sc 0
|
|
||||||
|
|
||||||
addi r0, r0, 1 ! exit()
|
|
||||||
sc 0
|
|
||||||
|
|
||||||
.sect .rom
|
|
||||||
message:
|
|
||||||
.ascii "TRAP!\n"
|
|
|
@ -19,7 +19,6 @@ acklibrary {
|
||||||
"./sigaction.s",
|
"./sigaction.s",
|
||||||
"./stat.s",
|
"./stat.s",
|
||||||
"./write.s",
|
"./write.s",
|
||||||
"plat/linuxppc/libsys/trap.s",
|
|
||||||
"plat/osx/libsys/brk.c",
|
"plat/osx/libsys/brk.c",
|
||||||
"plat/osx/libsys/creat.c",
|
"plat/osx/libsys/creat.c",
|
||||||
"plat/osx/libsys/isatty.c",
|
"plat/osx/libsys/isatty.c",
|
||||||
|
|
|
@ -13,6 +13,7 @@ definerule("plat_testsuite",
|
||||||
"tests/plat/dup_e.e",
|
"tests/plat/dup_e.e",
|
||||||
"tests/plat/exg_e.e",
|
"tests/plat/exg_e.e",
|
||||||
"tests/plat/inn_e.e",
|
"tests/plat/inn_e.e",
|
||||||
|
"tests/plat/rck_e.e",
|
||||||
"tests/plat/rotate_e.e",
|
"tests/plat/rotate_e.e",
|
||||||
"tests/plat/*.p",
|
"tests/plat/*.p",
|
||||||
"tests/plat/b/*.b",
|
"tests/plat/b/*.b",
|
||||||
|
|
186
tests/plat/rck_e.e
Normal file
186
tests/plat/rck_e.e
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
#
|
||||||
|
mes 2, EM_WSIZE, EM_PSIZE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uses _rck_ for range checks. Catches the EM trap if a value is out
|
||||||
|
* of range, and continues with the next instruction after _rck_.
|
||||||
|
*
|
||||||
|
* Some back ends, like i80, ignore _rck_, so this test fails.
|
||||||
|
*/
|
||||||
|
|
||||||
|
testnr
|
||||||
|
con 1 ; test number
|
||||||
|
caught
|
||||||
|
con 0 ; number of caught traps
|
||||||
|
|
||||||
|
inp $next
|
||||||
|
inp $catch
|
||||||
|
inp $never
|
||||||
|
exp $_m_a_i_n
|
||||||
|
pro $_m_a_i_n,0
|
||||||
|
|
||||||
|
lim ; load ignore mask
|
||||||
|
loc 2
|
||||||
|
and EM_WSIZE ; check bit 1 << ERANGE
|
||||||
|
zeq *1 ; fail if ignoring ERANGE
|
||||||
|
.1
|
||||||
|
rom 1I4
|
||||||
|
lae .1
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
1
|
||||||
|
|
||||||
|
cal $next ; increment testnr, catch next trap
|
||||||
|
loc 10125
|
||||||
|
.2
|
||||||
|
rom 4283, 13644
|
||||||
|
lae .2
|
||||||
|
rck EM_WSIZE ; testnr 2 in range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc 4282
|
||||||
|
lae .2
|
||||||
|
rck EM_WSIZE ; testnr 3 out of range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc 4283
|
||||||
|
lae .2
|
||||||
|
rck EM_WSIZE ; testnr 4 in range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc 13644
|
||||||
|
lae .2
|
||||||
|
rck EM_WSIZE ; testnr 5 in range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc 13655
|
||||||
|
lae .2
|
||||||
|
rck EM_WSIZE ; testnr 6 out of range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc -13015
|
||||||
|
.7
|
||||||
|
rom -31344, -1898
|
||||||
|
lae .7
|
||||||
|
rck EM_WSIZE ; testnr 7 in range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
cal $next
|
||||||
|
loc 8580
|
||||||
|
.8
|
||||||
|
rom -26315, 4588
|
||||||
|
lae .8
|
||||||
|
rck EM_WSIZE ; testnr 8 out of range
|
||||||
|
asp EM_WSIZE
|
||||||
|
|
||||||
|
; The last test raised a trap, so now there is no trap handler.
|
||||||
|
lpi $never
|
||||||
|
sig ; push old trap handler
|
||||||
|
loc 0
|
||||||
|
loc EM_WSIZE
|
||||||
|
loc EM_PSIZE
|
||||||
|
cuu ; push NULL pointer
|
||||||
|
cmp
|
||||||
|
zeq *17 ; fail unless old handler is NULL
|
||||||
|
.17
|
||||||
|
rom 17I4
|
||||||
|
lae .17
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
17
|
||||||
|
; Change the trap handler from $never to $catch.
|
||||||
|
lpi $catch
|
||||||
|
sig
|
||||||
|
lpi $never
|
||||||
|
cmp
|
||||||
|
zeq *18
|
||||||
|
.18
|
||||||
|
rom 18I4
|
||||||
|
lae .18
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
18
|
||||||
|
; Begin ignoring range traps.
|
||||||
|
loc 2 ; 1 << ERANGE
|
||||||
|
sim
|
||||||
|
loc 18
|
||||||
|
ste testnr
|
||||||
|
loc 8580
|
||||||
|
lae .8
|
||||||
|
rck EM_WSIZE ; testnr 18 out of range but ignored
|
||||||
|
|
||||||
|
; Fail if we caught the wrong number of traps.
|
||||||
|
loe caught
|
||||||
|
loc 3
|
||||||
|
beq *20
|
||||||
|
.20
|
||||||
|
rom 20I4
|
||||||
|
lae .20
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
20
|
||||||
|
cal $finished
|
||||||
|
end
|
||||||
|
|
||||||
|
pro $next,0
|
||||||
|
ine testnr ; next test
|
||||||
|
lpi $catch
|
||||||
|
sig ; catch next EM trap (only one trap)
|
||||||
|
asp EM_PSIZE
|
||||||
|
ret 0
|
||||||
|
end
|
||||||
|
|
||||||
|
pro $catch,0
|
||||||
|
ine caught ; count this trap
|
||||||
|
|
||||||
|
lol 0 ; load trap number
|
||||||
|
loc 1
|
||||||
|
beq *1 ; fail if trap != ERANGE
|
||||||
|
.101
|
||||||
|
rom 257I4
|
||||||
|
lae .101
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
; Wrong type of trap. _rtt_ might not work, so exit now.
|
||||||
|
cal $finished
|
||||||
|
1
|
||||||
|
; Fail if the wrong test raised this trap.
|
||||||
|
loe testnr
|
||||||
|
loc 3
|
||||||
|
beq *2
|
||||||
|
loe testnr
|
||||||
|
loc 6
|
||||||
|
beq *2
|
||||||
|
loe testnr
|
||||||
|
loc 8
|
||||||
|
beq *2
|
||||||
|
loc 256
|
||||||
|
loe testnr
|
||||||
|
adi EM_WSIZE ; 0x100 + testnr
|
||||||
|
loc EM_WSIZE
|
||||||
|
loc 4
|
||||||
|
cuu
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
2
|
||||||
|
rtt ; return from trap handler
|
||||||
|
end
|
||||||
|
|
||||||
|
pro $never,0
|
||||||
|
.200
|
||||||
|
rom 200I4
|
||||||
|
lae .200
|
||||||
|
loi 4
|
||||||
|
cal $fail
|
||||||
|
asp 4
|
||||||
|
rtt
|
||||||
|
end
|
Loading…
Reference in a new issue