|
Basic floating numbers in machine code |
|
Loris (16:15 9/12/2004) andrew (16:54 9/12/2004) Loris (18:09 9/12/2004) not_ginger_matt (18:27 9/12/2004) Loris (13:12 16/12/2004) Phlamethrower (19:09 9/12/2004) Loris (11:03 10/12/2004) Phlamethrower (18:40 10/12/2004) Loris (20:49 10/12/2004)
|
|
Tony Haines |
Message #60569, posted by Loris at 16:15, 9/12/2004 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
So I'm making artgraph go faster, and the inner loop for plotting the image uses EVAL. And I decide to convert this bit to ARM-code, and retain BASICs evaluation function by interfacing using CALL. This can still be faster because the tokenisation only needs to be done once, and plotting can be sped up. And it is going OK so far. I found a lot of information in the BASIC stronghelp manual about the environment info and stuff that CALL sets up, which I hardly knew existed. And I reverse-engineered the internal representation of floats IE R0..R3 format.
But today an idle search of the web turned up this: this (on Rick's ARM pages) This is the bit which worries me:
The floating point values in R0...R3 are given as follows:
R0 = 32 bit mantissa, normalised (so bit 31 = 1) R1 = Exponent in excess-128 form R2 = Undefined R3 = Sign, 0 is positive and &80000000 is negative
This is informational only, and the developers reserve the right to change the format. You are asked to treat R0...R3 as a single item, without worrying about the constituent parts. Now I'd determined R0,1 and 3 as he describes, but I hadn't considered the possibility that new versions of basic might change the representation.
Does the Iyonix, Omega etc change this? Thinking about it, the high precision BASIC (Basic64?) presumably does as well.
Any suggestions on how I can future-proof my code? I can't just read the floating data direct from memory myself - because this might change too. I really need to get the mantissa part and exponent in a defined format. |
|
[ Log in to reply ] |
|
Andrew |
Message #60570, posted by andrew at 16:54, 9/12/2004, in reply to message #60569 |
Handbag Boi
Posts: 3439
|
The BASIC stack register isn't documented in the PRMs nor the BBC BASIC V manual if IIRC! |
|
[ Log in to reply ] |
|
Tony Haines |
Message #60572, posted by Loris at 18:09, 9/12/2004, in reply to message #60570 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
The BASIC stack register isn't documented in the PRMs nor the BBC BASIC V manual if IIRC! I have the PRMs but not the BASIC guide (my Dad has our copy). The PRMs point to another book, I wasn't sure if it is that 'standard' one or not. The PRMs are essentially worthless for this topic - which is why I was using the stronghelp manual.
Oh, and another thing - apparently Basic (at least on 26-bit systems) needs the flags preserved over the call, I've been using LDM..^ . Will this work on eg Iyonix?
[Edited by Loris at 18:10, 9/12/2004] |
|
[ Log in to reply ] |
|
Richard Wilson |
Message #60577, posted by not_ginger_matt at 18:27, 9/12/2004, in reply to message #60572 |
Member
Posts: 63
|
Oh, and another thing - apparently Basic (at least on 26-bit systems) needs the flags preserved over the call, I've been using LDM..^ . Will this work on eg Iyonix?
Are you sure you've not just got the V flag set and it's treating R0 as an error block? Try adding 'CMPVS R15,#&80000000:CMNVS R15,#&80000000' or similar before exit.
R. |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #60579, posted by Phlamethrower at 19:09, 9/12/2004, in reply to message #60569 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
Any suggestions on how I can future-proof my code? I can't just read the floating data direct from memory myself - because this might change too. I really need to get the mantissa part and exponent in a defined format. Doesn't BASIC64 use the IEEE double precision format? So you could just use that and read the numbers from memory.
You could also try decoding the numbers in BASIC. |
|
[ Log in to reply ] |
|
Tony Haines |
Message #60583, posted by Loris at 11:03, 10/12/2004, in reply to message #60579 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
Doesn't BASIC64 use the IEEE double precision format? So you could just use that and read the numbers from memory. Quite possibly. But I don't want higher precision (with the associated reduced speed). I really just want a whatever-basic-format float to defined float convertion. So when the specs change the program will still work
You could also try decoding the numbers in BASIC. What do you mean? I know what the format is *currently*; the problem is a future version of basic might change it (if the basic in Iyonix hasn't changed already).
I guess I'll just check that a few pre-defined numbers match the format I'm expecting, and if not fall-back to doing it all in Basic. Any newer machine should be faster, anyway. |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #60599, posted by Phlamethrower at 18:40, 10/12/2004, in reply to message #60583 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
You could also try decoding the numbers in BASIC. What do you mean? I know what the format is *currently*; the problem is a future version of basic might change it (if the basic in Iyonix hasn't changed already).
sign%=0 exponent%=0 IF number<0 THEN sign%=-1 number=-number ENDIF IF number>=2^128 THEN exponent%+=128 number=number >> 128 ENDIF IF number>=2^64 THEN exponent%+=64 number=number >> 64 ENDIF
... etc.
I guess I'll just check that a few pre-defined numbers match the format I'm expecting, and if not fall-back to doing it all in Basic. Any newer machine should be faster, anyway. You can always include both versions of the code, and have it only use the ARM code one if it's on a tested version of BASIC. |
|
[ Log in to reply ] |
|
Tony Haines |
Message #60625, posted by Loris at 20:49, 10/12/2004, in reply to message #60599 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
sign%=0 exponent%=0 IF number<0 THEN sign%=-1 number=-number ENDIF IF number>=2^128 THEN exponent%+=128 number=number >> 128 ENDIF IF number>=2^64 THEN exponent%+=64 number=number >> 64 ENDIF
... etc. I can't do this, unfortunately. Because I need to know the format of the result of the EVAL (which I'm calling from machine code).
I guess I'll just check that a few pre-defined numbers match the format I'm expecting, and if not fall-back to doing it all in Basic. Any newer machine should be faster, anyway. You can always include both versions of the code, and have it only use the ARM code one if it's on a tested version of BASIC. ...but then I'd actually have to test it on every existing version of BASIC, and it still wouldn't work fast on a new version, even if it potentially could.
Testing a representative set of numbers for conforming to the current format would be pretty quick, because I could do:
a=%1010101/64 CALL code%,a
[machine code fetch number compare number with data perform operation on number compare number with data ... ]
Provided I check small and big, and maybe negative numbers it should be OK. |
|
[ Log in to reply ] |
|
Tony Haines |
Message #60777, posted by Loris at 13:12, 16/12/2004, in reply to message #60577 |
Ha ha, me mine, mwahahahaha
Posts: 1025
|
Oh, and another thing - apparently Basic (at least on 26-bit systems) needs the flags preserved over the call, I've been using LDM..^ . Will this work on eg Iyonix?
Are you sure you've not just got the V flag set and it's treating R0 as an error block? Try adding 'CMPVS R15,#&80000000:CMNVS R15,#&80000000' or similar before exit. I think you are correct. I didn't even need these instructions in the end, a loop test does the job by itself. |
|
[ Log in to reply ] |
|
|