This is a simple test to show where the floating point behaviour is wrong on RISC OS.
We try to turn off signals and then calculate NaN by dividing by 0. This should work. Then we show the values of what we got back.
On the FPEmulator 4.18, with the Select Shared C library (5.62), running under Pyromaniac, the following results are given from the test:
pyrodev --common --command 'help FPEmulator' --command aif32.nantest
==> Help on keyword 'FPEmulator' (Module)
Module is: FPEmulator 4.18 (14 Sep 2006) (1.07)
NaN test
nan = nan
nan = 7ff80000/e0000000
same = 1, different = 0
INF test
inf = inf
inf = 7ff00000/00000000
same = 1, different = 0
Going through the lines.
- First we print the version of the FPEmulator.
- We start the 'NaN test'.
printf
is showing the NaN we got from a division of 0 by 0 asnan
.- We show the representation as two 32bit words, low word then high word, which are sane.
- We show the value of an equality and inequality check on the NaN. This says that it's equal to itself. That's wrong. NaN is never equal to itself.
- We start the 'INF test' (which checks the behaviour of infinity).
printf
is showing the infinity we got from a division of 1 by 0 isinf
.- We show the representation as two 32bit words, low word then high word, which looks reasonable.
- We show the value of an equality and an inequality check on the infinity. That's right.
So there's a bug there.
On Unix (specifically in this case I'm using macOS) we can trust that we probably get sane answers.
NaN test
nan = nan
nan = 00000000/7ff80000
same = 0, different = 1
INF test
inf = inf
inf = 00000000/7ff00000
same = 1, different = 0
These answers are the same, except that...
- The order of the words differs in the 32bit word representation. That's a difference in the representation that ARM used in the original reference implementation of the FPE.
- NaN does not compare to itself. That's correct.
So that's the behaviour you want.
I can test on RISC OS 5, 'cos that's easy - run it under Docker with RPCEmu:
docker run -it -v $PWD/:/home/riscos/rpcemu/hostfs/Shared/ --rm -p 5901:5901 gerph/rpcemu-5
This is running on RISC OS 5.27 (19 Mar 2020); the RPCEmu 'easy start' images.
*Help FPEmulator
==> Help on keyword 'FPEmulator'
Module is: FPEmulator 4.37 (12 Nov 2019) (1.13M)
*aif32.nantest
NaN test
Postmortem requested
fc1367f4 in function nantest
823c in function main
Arg2: 0x00008224 33316 -> [0xe1a0c00d 0xe92dd800 0xe24cb004 0xe15d000a]
Arg1: 0x0000b274 45684 -> [0x33666961 0x616e2e32 0x7365746e 0x79540074]
fc139b94 in shared library function
82c8 in anonymous function
So... that's not good. It's crashing somewhere in the ROM - and you probably guessed that it's in the FPEmulator at this point... but you (and I) got it wrong. It's actually in the SharedCLibrary.
We don't have any trace other information to say what's going wrong, so we just have to scrounge around for more information
*showregs
Register dump (stored at &2000D2D0) is:
R0 = FFFFFFFF R1 = FFFFFFFD R2 = 00000002 R3 = 00009DB8
R4 = 0000B282 R5 = FFFFFFFF R6 = 00000000 R7 = 00000000
R8 = 000099CC R9 = 00009BFC R10 = 0000A4B4 R11 = 0000B1F0
R12 = 0000B110 R13 = 0000B1CC R14 = 000080B8 R15 = 000080C0
Mode USR32 flags set: Nzcvqjggggeaift PSR = 80000010
This shows us that it thinks it's in user space at address &80C0
. We can show the code around
that point with a *MemoryI
:
*memoryi pc-20+40
000080A0 : .ÐMâ : E24DD008 : SUB R13,R13,#8
000080A4 : ..Xâ : E28F0F19 : ADR R0,&00008110
000080A8 : u..ë : EB000375 : BL &00008E84
000080AC : h.Ÿå : E59F1068 : LDR R1,&0000811C
000080B0 : .. ã : E3A00002 : MOV R0,#2
000080B4 : Ø..ë : EB0003D8 : BL &0000901C
000080B8 : ˆX.î : EE008188 : MVFD F0,#0
000080BC : ˆ.@î : EE400188 : DVFD F0,F0,#0
000080C0 < .XXí : ED8D8100 : STFD F0,[R13,#0]
000080C4 : ..Xâ : E28F0F15 : ADR R0,&00008120
000080C8 : ..Xè : E89D0006 : LDMIA R13,{R1,R2}
000080CC : X..ë : EB0003AD : BL &00008F88
000080D0 : ..Xè : E89D0006 : LDMIA R13,{R1,R2}
000080D4 : ..Xâ : E28F0F14 : ADR R0,&0000812C
000080D8 : i..ë : EB000369 : BL &00008E84
000080DC : .` ã : E3A06001 : MOV R6,#1
This implies that we were in the middle of the division (or possibly the store). Either way we've got an address which tells use where the exception was reported in the ROM. So let's dump the code around &fc1367f4
to see what it's trying to do:
*memoryi fc1367f4-20+40
FC1367D4 : .ÅŸå : E59FC518 : LDR R12,&FC136CF4
FC1367D8 : .".å : E51A221C : LDR R2,[R10,#-540]
FC1367DC : .ÀŒà : E08CC002 : ADD R12,R12,R2
FC1367E0 : . ã : E3A02001 : MOV R2,#1
FC1367E4 : X#Ìå : E5CC239D : STRB R2,[R12,#925]
FC1367E8 : ..-é : E92D000A : STMDB R13!,{R1,R3}
FC1367EC : þ.‘é : E99103FE : LDMIB R1,{R1-R9}
FC1367F0 : .>.ë : EB003E06 : BL &FC146010
FC1367F4 : ‘..ê : EA000091 : B &FC136A40
FC1367F8 : .@-é : E92D4001 : STMDB R13!,{R0,R14}
FC1367FC : .. á : E1A00002 : MOV R0,R2
FC136800 : ÍÇ.ë : EB00C7CD : BL &FC16873C
FC136804 : .P½è : E8BD5000 : LDMIA R13!,{R12,R14}
FC136808 : ..Ώ : E88C0003 : STMIA R12,{R0,R1}
FC13680C : .ð á : E1A0F00E : MOV PC,R14
FC136810 : .. á : E1A00000 : MOV R0,R0
Looking at the instruction 2 back from the address given (due to the pipeline), this is LDMIB R1,{R1-R9}
- load a set of registers from R1 incrementing before each. If we look up at the registers shown by *ShowRegs
we see that R1 is &FFFFFFFD. So something in the SharedCLibrary is breaking.
So how about running it on RISC OS 3.7. That's the common parent of both RISC OS 5 and RISC OS 4. Again, can do this with Docker:
docker run -it -v $PWD/:/home/riscos/rpcemu/hostfs/Shared/ --rm -p 5901:5901 gerph/rpcemu-3.7
The output was...
*help fpemulator
==> Help on keyword FPEmulator
Module is: FPEmulator 4.08 (17 Jan 1997) (1.07z)
*aif32.nantest
NaN test
Postmortem requested
21fefa8 in function nantest
823c in function main
22122f0 in unknown procedure
82c8 in anonymous function
That's the same sort of failure as the RISC OS 5 test. Doing the same tests, we see...
*showregs
Register dump (stored at &02104FAC) is:
R0 = 00000000 R1 = 00000000 R2 = 00000000 R3 = 00000000
R4 = 00000000 R5 = 00000000 R6 = 00000000 R7 = 00000000
R8 = 00000000 R9 = 00000000 R10 = 00000000 R11 = 00000000
R12 = 00000000 R13 = 00000000 R14 = 00000000 R15 = 00000000
Mode USR flags set: nzcvif
So no state from the application.
*memoryi 21fefa8-20+40
021FEF88 : (ÅŸå : E59FC528 : LDR R12,&021FF4B8
021FEF8C : .".å : E51A221C : LDR R2,[R10,#-540]
021FEF90 : .ÀŒà : E08CC002 : ADD R12,R12,R2
021FEF94 : . ã : E3A02001 : MOV R2,#1
021FEF98 : X#Ìå : E5CC239D : STRB R2,[R12,#925]
021FEF9C : ..-é : E92D000A : STMDB R13!,{R1,R3}
021FEFA0 : þ.‘é : E99103FE : LDMIB R1,{R1-R9}
021FEFA4 : .>.ë : EB003E0D : BL &0220E7E0
021FEFA8 : ‘..ê : EA000091 : B &021FF1F4
021FEFAC : .@-é : E92D4001 : STMDB R13!,{R0,R14}
021FEFB0 : .. á : E1A00002 : MOV R0,R2
021FEFB4 : .T.ë : EB005408 : BL &02213FDC
021FEFB8 : .P½è : E8BD5000 : LDMIA R13!,{R12,R14}
021FEFBC : ..Ώ : E88C0003 : STMIA R12,{R0,R1}
021FEFC0 : .ð°á : E1B0F00E : MOVS PC,R14
021FEFC4 : .. á : E1A00000 : MOV R0,R0
So the failure inside SharedCLibrary is the same as well.
What about RISC OS 4? Running the test on there...
*nantest
NaN test
nan = nan
nan = 7ff80000/e0000000
same = 1, different = 0
INF test
inf = inf
inf = 7ff00000/00000000
same = 1, different = 0
Which is unsurprising as it's using the same SharedCLibrary and FPEmulator module.
Pyromaniac is for debugging, isn't it? So let's use it.
I saved took the C Library out of harddisc bundle on the website, and tried loading it with Pyromaniac. This fails because it's compressed. So I loaded it on RISC OS Classic and *RMSave
'd it out.
pyrodev --common --command 'rmload clibRO5' --command 'pyromaniacdebug trace,traceregionfunc' --command aif32.nantest --config trace.stack_depth_indicator=yes 2> trace.txt
NaN test
C24
C22C28
C22C28
C25 -> [0xe1a0c00d 0xe92dd800 0xe24cb004 0xe15d000a]
C25 -> [0x69612e24 0x2e323366 0x746e616e 0x20747365]
C22C26
C22C27
There's no token expansion because there's no resources, and that version of the SCL assumes that there will be. It's not important though, because we've got a trace out of it. However when I trace this I find that the actual error being reported above is an error - 'Invalid Operation'. In the trace it looks like this:
S[||| : 383bcf4: MOV r0, sp ; R13 = &04107fc4
S[||| : 383bcf8: ADR r1, &0383BCBC ; -> "Resources:$.Resources.FPEmulator.Messages"
S[||| : 383bcfc: MOV r2, #0
S[||| : 383bd00: SWI XMessageTrans_OpenFile
S[||| : 383bd04: ADDVS sp, sp, #&10 ; R13 = &04107fc4
S[||| : 383bd08: MOVVC r0, r6 ; R6 = &0383bc2c
S[||| : 383bd0c: MOV pc, r7 ; R7 = &0383bc94
S[||| : 383bc94: POPVS {r2, r3, r4, r5, r6, r7, pc}
S[||| : 383bc98: MOV r1, sp ; R13 = &04107fc4
S[||| : 383bc9c: MOV r2, #0
S[||| : 383bca0: MOV r5, #0
S[||| : 383bca4: MOV r6, #0
S[||| : 383bca8: MOV r7, #0
S[||| : 383bcac: SWI XMessageTrans_ErrorLookup
S[||| : 383bcb0: MOV r1, r4 ; R4 = &00000000
S[||| : 383bcb4: BL &0383BD10
S[||| : 383bd10: STMDB sp!, {lr} ; R13 = &04107fc4
S[|||| : 383bd14: MRS r7, apsr
S[|||| : 383bd18: MOV r6, r0 ; R0 = &0410a4e4
S[|||| : 383bd1c: ADD r0, sp, #4 ; R13 = &04107fc0
S[|||| : 383bd20: SWI XMessageTrans_CloseFile
S[|||| : 383bd24: MSR apsr_nzcvq, r7 ; R7 = &10000013
S[|||| : 383bd28: LDMIA sp!, {r7} ; R13 = &04107fc0
S[||| : 383bd2c: ADD sp, sp, #&10 ; R13 = &04107fc4
S[|| : 383bd30: MOV r0, r6 ; R6 = &0410a4e4
S[|| : 383bd34: MOV pc, r7 ; R7 = &0383bcb8
S[|| : 383bcb8: POP {r2, r3, r4, r5, r6, r7, pc}
S[|| : 383bc70: {DA 'ROM', module 'FPEmulator'}
S[| : 383bc70: SWI OS_GenerateError
==== Begin error report ====
Error about to be reported to environment handler: [&80000200] Error 'InvalOp'
r0 = &0410a4e4, r1 = &00000000, r2 = &00000002, r3 = &00009d80
r4 = &0000b281, r5 = &ffffffff, r6 = &00000000, r7 = &00000000
r8 = &000099cc, r9 = &00009bc4, r10 = &0000a4b4, r11 = &0000b1ec
r12 = &0000b10c, sp = &04107ff0, lr = &0383bcb8, pc = &0383bc74
CPSR= &00000013 : SVC-32 ARM fi ae qvczn
SPSR= &20000013 : SVC-32 ARM fi ae qvCzn
Locations:
r0 -> [&80000200, &6f727245, &49272072, &6c61766e] in DA 'System heap'
r3 -> [&00000000, &ffffffff, &fffffffd, &ffffffff] in DA 'Application Space'
r8 -> "@@@@@@@@@AAAAA@@@@@@@@@@@@@@@@@@" in DA 'Application Space'
r9 -> [&0000b750, &0000b764, &00000000, &00000000] in DA 'Application Space'
r10 -> [&00000000, &00000000, &00000000, &00000000] in DA 'Application Space'
r11 -> [&00008098, &0000b258, &0000b200, &0381ff70] in DA 'Application Space'
r12 -> [&0000b52c, &00000001, &00009768, &0000b281] in DA 'Application Space'
pc is DA 'ROM', module 'FPEmulator'
lr is DA 'ROM', module 'FPEmulator'
==== End error report ====
3831474: {DA 'ROM', module 'SharedCLibrary'}
[ : 3831474: SWI XOS_EnterOS
[ : 3831478: {DA 'ROM', module 'SharedCLibrary'}
S[ : 3831478: LDR lr, [r0, #&120] ; R0 = &00009420
S[ : 383147c: TEQ lr, #&80000000 ; R14 = &80000200
S[ : 3831480: TEQNE lr, #&80000001 ; R14 = &80000200
S[ : 3831484: TEQNE lr, #&80000002 ; R14 = &80000200
S[ : 3831488: TEQNE lr, #&80000003 ; R14 = &80000200
S[ : 383148c: ADDNE lr, r0, #&78 ; R0 = &00009420
S[ : 3831490: STMNEIA lr!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12} ; R14 = &00009498
It's as if the C Library is ignoring the attempt to change the signal handling to get to that point. From the earlier output from *ShowRegs
we know that it's producing an invalid R1 value because the LDMIB instruction fails. So let's have a search for the LDMIB in the trace. It turns out there is only one with the right format:
[||||| : 382c480: LDR r2, [r10, #-&21c] ; R10 = &0000a4b4
[||||| : 382c484: ADD r3, r2, r1 ; R2 = &fc7d65c8, R1 = &038337b8
[||||| : 382c488: LDR r1, [r3, r0, LSL #2] ; R3 = &00009d80, R0 = &00000002
[||||| : 382c48c: LDR r2, &0382C468 ; = &ffffffff
[||||| : 382c490: CMP r1, r2 ; R1 = &fffffffd, R2 = &ffffffff
[||||| : 382c494: MOVNE r0, #1
[||||| : 382c498: MOVNE pc, lr ; R14 = &0381c934
[||||| : 381c934: CMP r0, #0 ; R0 = &00000001
[||||| : 381c938: POP {r0, r1, r3, lr}
[||| : 381c93c: MOVEQ r0, #0
[||| : 381c940: MOVEQ pc, lr ; R14 = &0383119c
[||| : 381c944: LDR r12, &0381CE7C ; = &03833174
[||| : 381c948: LDR r2, [r10, #-&21c] ; R10 = &0000a4b4
[||| : 381c94c: ADD r12, r12, r2 ; R12 = &03833174, R2 = &fc7d65c8
[||| : 381c950: MOV r2, #1
[||| : 381c954: STRB r2, [r12, #&39d] ; R2 = &00000001, R12 = &0000973c
[||| : 381c958: PUSH {r1, r3}
[|||| : 381c95c: LDMIB r1, {r1, r2, r3, r4, r5, r6, r7, r8, r9} ; R1 = &0000b184
[|||| : 381c960: BL &0382C3EC
[|||| : 382c3ec: MOV r12, sp ; R13 = &0000b118
[|||| : 382c3f0: PUSH {r11, r12, lr, pc}
So in Pyromaniac, it's getting r1 correct. The fact that higher up the code there's a comparison where R1 contained &FFFFFFFD
- the value that we failed with - is interesting. I don't see how it could have reached the LDMIB
, but that's the sequence of code when it's working.
Let's go back to the code that handled the signal.
Here's the signal
code when executed in the RISC OS 5 SCL:
[||||||| : 80b4: BL &0000901C
[||||||| : 901c: LDR pc, &00009300 ; = &0382c4a4
[||||||| : 382c4a4: {DA 'ROM', module 'SharedCLibrary'}
[||||||| : 382c4a4: MOV r2, r0 ; R0 = &00000002
[||||||| : 382c4a8: CMP r0, #0 ; R0 = &00000002
[||||||| : 382c4ac: BLE &0382C4CC
[||||||| : 382c4b0: CMP r2, #&b ; R2 = &00000002, #11
[||||||| : 382c4b4: LDRLT r0, &0382C464 ; = &038337b8
[||||||| : 382c4b8: LDRLT r3, [r10, #-&21c] ; R10 = &0000a4b4
[||||||| : 382c4bc: ADDLT r3, r3, r0 ; R3 = &fc7d65c8, R0 = &038337b8
[||||||| : 382c4c0: LDRLT r0, [r3, r2, LSL #2] ; R3 = &00009d80, R2 = &00000002
[||||||| : 382c4c4: STRLT r1, [r3, r2, LSL #2] ; R1 = &fffffffd, R3 = &00009d80, R2 = &00000002
[||||||| : 382c4c8: MOVLT pc, lr ; R14 = &000080b8
[||||||| : 80b8: {DA 'Application Space'}
And that same code on the RISC OS 4 SCL:
[||||||| : 80b4: BL &0000901C
[||||||| : 901c: LDR pc, &00009300 ; = &0382831c
[||||||| : 382831c: {DA 'ROM', module 'SharedCLibrary': Function signal}
[||||||| : Function: signal
[||||||| : r0 = &00000002, r1 = &fffffffd, r2 = &00000009, r3 = &00000001
[||||||| : r4 = &0000b281, r5 = &00000010, r6 = &ffffffff, r7 = &00000000
[||||||| : r8 = &00000000, r9 = &ffffffff, r10 = &0000a4b4, r11 = &0000b1fc
[||||||| : r12 = &fc7d755c, sp = &0000b1d8, lr = &000080b8, pc = &0382831c
[||||||| : CPSR= &60000010 : USR-32 ARM fi ae qvCZn
[||||||| : 382831c: MOV r12, sp ; Function: signal ; R13 = &0000b1d8
[||||||| : 3828320: PUSH {r0, r1, r4, r5, r11, r12, lr, pc}
[|||||||| : 3828324: SUB r11, r12, #4 ; R12 = &0000b1d8
[|||||||| : 3828328: CMP sp, r10 ; R13 = &0000b1b8, R10 = &0000a4b4
[|||||||| : 382832c: BLLT &0381D310
[|||||||| : 3828330: MOV r4, r1 ; R1 = &fffffffd
[|||||||| : 3828334: CMP r0, #0 ; R0 = &00000002
[|||||||| : 3828338: BLE &03828344
[|||||||| : 382833c: CMP r0, #&b ; R0 = &00000002, #11
[|||||||| : 3828340: BLT &03828350
[|||||||| : 3828350: LDR r1, &0382827C ; = &03832894
[|||||||| : 3828354: LDR r12, [r10, #-&21c] ; R10 = &0000a4b4
[|||||||| : 3828358: ADD r1, r12, r1 ; R12 = &fc7d755c, R1 = &03832894
[|||||||| : 382835c: LDR r5, [r1, r0, LSL #2] ; R1 = &00009df0, R0 = &00000002
[|||||||| : 3828360: STR r4, [r1, r0, LSL #2] ; R4 = &fffffffd, R1 = &00009df0, R0 = &00000002
[|||||||| : 3828364: TEQ r0, #2 ; R0 = &00000002
[|||||||| : 3828368: BNE &038283AC
[|||||||| : 382836c: BL &0382F408 ; -> Function: _kernel_fpavailable
[|||||||| : 382f408: {DA 'ROM', module 'SharedCLibrary': Function _kernel_fpavailable}
[|||||||| : Function: _kernel_fpavailable
[|||||||| : r0 = &00000002, r1 = &00009df0, r2 = &00000009, r3 = &00000001
[|||||||| : r4 = &fffffffd, r5 = &ffffffff, r6 = &ffffffff, r7 = &00000000
[|||||||| : r8 = &00000000, r9 = &ffffffff, r10 = &0000a4b4, r11 = &0000b1d4
[|||||||| : r12 = &fc7d755c, sp = &0000b1b8, lr = &03828370, pc = &0382f408
[|||||||| : CPSR= &40000010 : USR-32 ARM fi ae qvcZn
[|||||||| : 382f408: STR lr, [sp, #-4]! ; Function: _kernel_fpavailable ; R14 = &03828370, R13 = &0000b1b8
[||||||||| : 382f40c: MRS lr, apsr
[||||||||| : 382f410: STR lr, [sp, #-4]! ; R14 = &40000010, R13 = &0000b1b4
[|||||||||| : 382f414: LDR r12, &0382F110 ; = &03831ec4
[|||||||||| : 382f418: LDR r0, [r10, #-&21c] ; R10 = &0000a4b4
[|||||||||| : 382f41c: ADD r12, r12, r0 ; R12 = &03831ec4, R0 = &fc7d755c
[|||||||||| : 382f420: LDRB r0, [r12, #&118] ; R12 = &00009420 ([&00008080, &000093e4, &0000940c, &e92d5001])
[|||||||||| : 382f424: POP {lr}
[||||||||| : 382f428: MSR apsr_nzcvq, lr ; R14 = &40000010
[||||||||| : 382f42c: POP {pc}
[||||||||| : 3828370: {DA 'ROM', module 'SharedCLibrary'}
[|||||||| : 3828370: TEQ r0, #0 ; R0 = &00000001
[|||||||| : 3828374: BEQ &038283AC
[|||||||| : 3828378: LDR r0, &03827F3C ; = &fffffffd
[|||||||| : 382837c: TEQ r4, r0 ; R4 = &fffffffd, R0 = &fffffffd
[|||||||| : 3828380: BNE &03828398
[|||||||| : 3828384: TEQ r5, r0 ; R5 = &ffffffff, R0 = &fffffffd
[|||||||| : 3828388: MOVNE r1, #&70000 ; #458752
[|||||||| : 382838c: MOVNE r0, #0
[|||||||| : 3828390: BNE &038283A8
[|||||||| : 38283a8: BL &0382C1C0
[|||||||| : 382c1c0: MRC p1, #1, r2, c0, c0, #0
[|||||||| : 3834108: {DA 'ROM', module 'FPEmulator'}
U[ : 3834108: SUB sp, sp, #&40 ; R13 = &08404000
U[| : 383410c: STMIA sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12} ; R13 = &08403fc0
U[| : 3834110: STMIA sp, {sp, lr} ^ ; R13 = &08403ff4
U[| : 3834114: MOV r0, r0 ; R0 = &00000000
U[| : 3834118: SUB sp, sp, #&34 ; R13 = &08403ff4
U[)| : 383411c: STR lr, [sp, #&3c] ; R14 = &0382c1c4, R13 = &08403fc0
U[)| : 3834120: MOV r12, sp ; R13 = &08403fc0
U[)| : 3834124: MRS r10, apsr
U[)| : 3834128: MRS r9, spsr
U[)| : 383412c: PUSH {r9, r10}
U[)|| : 3834130: TST r9, #&f ; R9 = &00000010, #15
U[)|| : 3834134: SUB r9, lr, #4 ; R14 = &0382c1c4
U[)|| : 3834138: LDRTEQ r11, [r9], #0 ; R9 = &0382c1c0
U[)|| : 383413c: LDRNE r11, [r9] ; R9 = &0382c1c0
U[)|| : 3834140: MOV r10, #0
U[)|| : 3834144: LDR r10, [r10, #&ff4] ; R10 = &00000000
U[)|| : 3834148: TST r11, #&8000000 ; R11 = &ee302110, #134217728
U[)|| : 383414c: BEQ &03835830
U[)|| : 3834150: AND r9, r11, #&f00 ; R11 = &ee302110
U[)|| : 3834154: CMP r9, #&100 ; R9 = &00000100, #256
U[)|| : 3834158: BNE &03835444
U[)|| : 383415c: LDR r8, [r10, #&84] ; R10 = &07001814
U[)|| : 3834160: TEQ r8, #0 ; R8 = &00000000
U[)|| : 3834164: BNE &0383542C
U[)|| : 3834168: MRS r8, apsr
U[)|| : 383416c: BIC r8, r8, #&80 ; R8 = &6000009b
U[)|| : 3834170: MSR cpsr_fsxc, r8 ; R8 = &6000001b
U[)|| : 3834174: MOV r0, r0 ; R0 = &00000000
U[)|| : 3834178: LDR r7, [r10, #&80] ; R10 = &07001814
U[)|| : 383417c: TST r11, #&2000000 ; R11 = &ee302110, #33554432
U[)|| : 3834180: BNE &03835140
U[)|| : 3835140: TST r11, #&80000 ; R11 = &ee302110, #524288
U[)|| : 3835144: TSTNE r11, #&80 ; R11 = &ee302110, #128
U[)|| : 3835148: BNE &03835830
U[)|| : 383514c: TST r11, #&10 ; R11 = &ee302110, #16
U[)|| : 3835150: BNE &03835230
U[)|| : 3835230: AND r8, r11, #&f00000 ; R11 = &ee302110
U[)|| : 3835234: ADD pc, pc, r8, LSR #18 ; R15 = &03835234, R8 = &00300000
U[)|| : 3835248: B &038352E0
U[)|| : 38352e0: MOV r6, r7 ; R7 = &01070000
U[)|| : 38352e4: AND r3, r11, #&f000 ; R11 = &ee302110
U[)|| : 38352e8: CMP r3, #&d000 ; R3 = &00002000, #53248
U[)|| : 38352ec: BHS &038352F8
U[)|| : 38352f0: STR r6, [r12, r3, LSR #10] ; R6 = &01070000, R12 = &08403fc0, R3 = &00002000
U[)|| : 38352f4: B &03835008
U[)|| : 3835008: STR r7, [r10, #&80] ; R7 = &01070000, R10 = &07001814
U[)|| : 383500c: LDR r8, [r12, #-8] ; R12 = &08403fc0
U[)|| : 3835010: ANDS r8, r8, #&f ; R8 = &00000010
U[)|| : 3835014: BNE &03834300
U[)|| : 3835018: LDR r9, [r12, #&3c] ; R12 = &08403fc0
U[)|| : 383501c: CMP sp, #0 ; R13 = &08403fb8
U[)|| : 3835020: LDRTNE r11, [r9], #0 ; R9 = &0382c1c4
U[)|| : 3835024: ANDNE r8, r11, r11, LSL #1 ; R11 = &e1c23001, R11 = &e1c23001
U[)|| : 3835028: TSTNE r8, #&8000000 ; R8 = &c1802000, #134217728
U[)|| : 383502c: BLNE &03835798
U[)|| : 3835030: LDMDB r12, {r8, r9} ; R12 = &08403fc0
U[)|| : 3835034: MSR cpsr_fsxc, r9 ; R9 = &0000009b
U[)|| : 3835038: MSR spsr_fsxc, r8 ; R8 = &00000010
U[)|| : 383503c: MOV sp, r12 ; R12 = &08403fc0
U[)| : 3835040: LDMIA r12, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr} ^ ; R12 = &08403fc0
U[)| : 3835044: MOV r0, r0 ; R0 = &00000000
U[)| : 3835048: ADD sp, sp, #&3c ; R13 = &08403fc0
U[) : 383504c: LDMIA sp!, {pc} ^ ; R13 = &08403ffc
U[) : 382c1c4: {DA 'ROM', module 'SharedCLibrary'}
[|||||||| : 382c1c4: BIC r3, r2, r1 ; R2 = &01070000, R1 = &00070000
[|||||||| : 382c1c8: EOR r3, r3, r0 ; R3 = &01000000, R0 = &00000000
[|||||||| : 382c1cc: MCR p1, #1, r3, c0, c0, #0
[|||||||| : 3834108: {DA 'ROM', module 'FPEmulator'}
U[ : 3834108: SUB sp, sp, #&40 ; R13 = &08404000
U[| : 383410c: STMIA sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12} ; R13 = &08403fc0
U[| : 3834110: STMIA sp, {sp, lr} ^ ; R13 = &08403ff4
U[| : 3834114: MOV r0, r0 ; R0 = &00000000
U[| : 3834118: SUB sp, sp, #&34 ; R13 = &08403ff4
U[)| : 383411c: STR lr, [sp, #&3c] ; R14 = &0382c1d0, R13 = &08403fc0
U[)| : 3834120: MOV r12, sp ; R13 = &08403fc0
U[)| : 3834124: MRS r10, apsr
U[)| : 3834128: MRS r9, spsr
U[)| : 383412c: PUSH {r9, r10}
U[)|| : 3834130: TST r9, #&f ; R9 = &00000010, #15
U[)|| : 3834134: SUB r9, lr, #4 ; R14 = &0382c1d0
U[)|| : 3834138: LDRTEQ r11, [r9], #0 ; R9 = &0382c1cc
U[)|| : 383413c: LDRNE r11, [r9] ; R9 = &0382c1cc
U[)|| : 3834140: MOV r10, #0
U[)|| : 3834144: LDR r10, [r10, #&ff4] ; R10 = &00000000
U[)|| : 3834148: TST r11, #&8000000 ; R11 = &ee203110, #134217728
U[)|| : 383414c: BEQ &03835830
U[)|| : 3834150: AND r9, r11, #&f00 ; R11 = &ee203110
U[)|| : 3834154: CMP r9, #&100 ; R9 = &00000100, #256
U[)|| : 3834158: BNE &03835444
U[)|| : 383415c: LDR r8, [r10, #&84] ; R10 = &07001814
U[)|| : 3834160: TEQ r8, #0 ; R8 = &00000000
U[)|| : 3834164: BNE &0383542C
U[)|| : 3834168: MRS r8, apsr
U[)|| : 383416c: BIC r8, r8, #&80 ; R8 = &6000009b
U[)|| : 3834170: MSR cpsr_fsxc, r8 ; R8 = &6000001b
U[)|| : 3834174: MOV r0, r0 ; R0 = &00000000
U[)|| : 3834178: LDR r7, [r10, #&80] ; R10 = &07001814
U[)|| : 383417c: TST r11, #&2000000 ; R11 = &ee203110, #33554432
U[)|| : 3834180: BNE &03835140
U[)|| : 3835140: TST r11, #&80000 ; R11 = &ee203110, #524288
U[)|| : 3835144: TSTNE r11, #&80 ; R11 = &ee203110, #128
U[)|| : 3835148: BNE &03835830
U[)|| : 383514c: TST r11, #&10 ; R11 = &ee203110, #16
U[)|| : 3835150: BNE &03835230
U[)|| : 3835230: AND r8, r11, #&f00000 ; R11 = &ee203110
U[)|| : 3835234: ADD pc, pc, r8, LSR #18 ; R15 = &03835234, R8 = &00200000
U[)|| : 3835244: B &03835334
U[)|| : 3835334: AND r3, r11, #&f000 ; R11 = &ee203110
U[)|| : 3835338: CMP r3, #&d000 ; R3 = &00003000, #53248
U[)|| : 383533c: BHS &03835350
U[)|| : 3835340: LDR r6, [r12, r3, LSR #10] ; R12 = &08403fc0, R3 = &00003000
U[)|| : 3835344: BIC r6, r6, #&ff000000 ; R6 = &01000000
U[)|| : 3835348: ORR r7, r6, #&1000000 ; R6 = &00000000
U[)|| : 383534c: B &03835008
U[)|| : 3835008: STR r7, [r10, #&80] ; R7 = &01000000, R10 = &07001814
U[)|| : 383500c: LDR r8, [r12, #-8] ; R12 = &08403fc0
U[)|| : 3835010: ANDS r8, r8, #&f ; R8 = &00000010
U[)|| : 3835014: BNE &03834300
U[)|| : 3835018: LDR r9, [r12, #&3c] ; R12 = &08403fc0
U[)|| : 383501c: CMP sp, #0 ; R13 = &08403fb8
U[)|| : 3835020: LDRTNE r11, [r9], #0 ; R9 = &0382c1d0
U[)|| : 3835024: ANDNE r8, r11, r11, LSL #1 ; R11 = &e1a00002, R11 = &e1a00002
U[)|| : 3835028: TSTNE r8, #&8000000 ; R8 = &c1000000, #134217728
U[)|| : 383502c: BLNE &03835798
U[)|| : 3835030: LDMDB r12, {r8, r9} ; R12 = &08403fc0
U[)|| : 3835034: MSR cpsr_fsxc, r9 ; R9 = &0000009b
U[)|| : 3835038: MSR spsr_fsxc, r8 ; R8 = &00000010
U[)|| : 383503c: MOV sp, r12 ; R12 = &08403fc0
U[)| : 3835040: LDMIA r12, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr} ^ ; R12 = &08403fc0
U[)| : 3835044: MOV r0, r0 ; R0 = &00000000
U[)| : 3835048: ADD sp, sp, #&3c ; R13 = &08403fc0
U[) : 383504c: LDMIA sp!, {pc} ^ ; R13 = &08403ffc
U[) : 382c1d0: {DA 'ROM', module 'SharedCLibrary'}
[|||||||| : 382c1d0: MOV r0, r2 ; R2 = &01070000
[|||||||| : 382c1d4: TEQ r0, r0 ; R0 = &01070000, R0 = &01070000
[|||||||| : 382c1d8: TEQ pc, pc ; R15 = &0382c1d8, R15 = &0382c1d8
[|||||||| : 382c1dc: MOVSNE pc, lr ; R14 = &038283ac
[|||||||| : 382c1e0: MOV pc, lr ; R14 = &038283ac
[|||||||| : 38283ac: MOV r0, r5 ; R5 = &ffffffff
[|||||||| : 38283b0: LDMDB r11, {r4, r5, r11, sp, pc} ; R11 = &0000b1d4
[|||||||| : 80b8: {DA 'Application Space'}
So that's a lot longer - mostly because it's got the code from the undefined instruction handler (FPEmulator) in the middle where we update the FP flags. That code is executing in UND mode, indicated by the 'U
' at the start of the line.
That's why the RISC OS 5 CLibrary went into the invalid operation error code. And for some reason that invalid operation code caused exceptions. But only on actual RISC OS 5, and possibly only on RPCEmu.
The FPEmulator is returning the wrong result for a comparison of NaN. Maybe there's a flag setting that I missed which is meant to address that. I'll need to look into it.
I don't know what's wrong. At the very least it's looking like the C library isn't disabling signals when you request it. And then, whilst handling it, something is going wrong.