BBC BASIC - 64 bit integer support, long string support
|
Are you saying your FPs are going to be 10 bytes (i.e. 80-bit IEEE 754-1985 double extended format)? Are you thinking of having this instead of 64-bit FP, or in addition to it? |
|
I’m also firmly on the side of having var%% be a completely different variable to var%. However, how would such an assignment work in practice? What happens if the 64 bit value is too large? Does it raise an error or does it truncate? Can truncation be selected? What about if a value that is positive has bit 31 set? Putting that into a 32 bit value will make a negative number. So many potential quirks… |
|
You can safely truncate if all the bits 63..32 are the same as bit 31. My preference would be for error. You could explictly truncate with a%% AND &FFFFFFFF (so long as the constant doesn’t sign extend!) |
|
If one were to assign a 64-bit integer into a 32-bit integer in BASIC, where the 64-bit value couldn’t be represented without a loss of precision, the canonical behaviour for BASIC would be to raise a “Number too big” error. And by “big” it means “too positive, or too negative”. And yes, you could selectively truncate: You’re right to question what happens if bit 31 is set in the 64-bit integer. |
|
@tymaja – I dropped you an email in case you want to discuss any of this offline. |
|
Steve Reville said :
The ARM64 ARM BBC BASIC I made (which is almost complete except for the matrix multiplication stuff in Array.S) uses 80-bit FP (originally 64bit 8bit, then 64bit/16bit). I did this so that I could keep the data flow the same as it is in 32-bit ARM BBC BASIC. It was a learning project, and I learnt a lot about ARM32 and Aarch64 assembly, and also software floating point, doing it!. Overall, it was worth doing simply to learn how BASIC actually works; the code is very similar to the ARM32 code, as it is essentially a hand-translation of that code into ARM64 code. I am planning to do a C rewrite of ARM BBC BASIC (which will help me practice C, which I only just started learning). I am currently reading around the subject (including things like structs in C / interworking with asm) I will check my email – thank you! |
|
What is doing the 80-bit FP? The old FPA/FPE supports it, but VFP and Neon on modern hardware don’t, so I assume you’ll be going with softfloat? |
|
The 80-bit FP is software-based; in essence what I did was convert the (32+8) bit software floating point code to (64+8+8bits spare), then to (64+16) bits; it runs at the same speed or slightly faster (on a Pi 5) than RISC OS ARM32 BBC BASIC on a Pi 4, and given the Pi5 is 3x faster than a Pi4, and I still have debug logging in the code, that isn’t bad! I did this as it was / is a learning project (to learn ARM32, ARM64, more about floating point, and also how BASIC works!). As a point of interest, it may be possible to hardware accelerate 80-bit FP on a 32/64-bit floating point unit. While I am focusing on what a C-based BBC BASIC with 32/64-bit ints etc would look like, it may be possible to write the core FP code in asm. If properly compartmentalized, this would mean rewriting a few dozen lines of asm ‘FP support code’, or defaulting to inbuilt soft-float. Rewriting a few dozen lines of asm code in ARM32, Aarch64, x86-64bit wouldn’t take long, and I think 64-bit intel supports 80-bit FP in hardware back in the 8086 days, so hopefully still does!) |
|
This is all great to see. I’m somewhat catching up on the forums as my day job was preventing me from doing so for some time. If you could drop me a line on info@riscosopen.org, it would be great for me to catch up on your progress. |
|
I’m late to the party here, but the num%% syntax for 64-bit integers is not only used by my BASICs (BB4W, BBCSDL, BBCTTY) but also by Matrix Brandy – which of course has a RISC OS build. As for 64-bit indirection, again both my BASICs and Matrix Brandy use the ] character for that (although there is a potential for confusion with the end-assembler-code usage it hasn’t presented a problem in practice):
All varieties of Brandy have strings with a 16-bit length (maximum 65535 bytes), my ‘modern’ BASICs have a 32-bit string length so the practical limit is determined by the heap size. |
|
Once you have 64-bit integers it makes sense to use 80-bit floats as well. One of the nice features of the ‘original’ BBC BASIC was that it was always possible to store an integer in a float variable with no loss of precision. There might be a speed penalty in using num rather than num% but not any truncation. It’s desirable for the same to apply with 64-bit integers, so you ideally want a floating-point format which has at least a 64-bit mantissa, as the 80-bit ‘long double’ format does. Then once again you can safely store any integer in a float with no loss of precision. Another way of looking at this is that both integers and floats are double the size they were in the original BBC BASIC (64-bit integers instead of 32, 80-bit floats instead of 40) which I think has a nice ‘feel’ to it as well as offering practical value. |
|
In my BASICs and Matrix Brandy the result is a ‘Number too big’ or ‘Number is out of range’ error respectively, as surely you would expect.
In my BASICs the ^ (address of) operator can be leveraged to do truncation: num% = !^num%%.
In my BASICs, and I presume in Matrix Brandy too, integers are internally always (signed) 64-bits, it’s only when stored in a regular integer variable that they become 32-bits, so this isn’t an issue.
‘Quirks’ (if that’s the right word) arise with the use of hexadecimal notation, but not otherwise as far as I’m aware. All the different data types can co-exist quite happily without any ambiguity. |
|
Certainly. Indeed this is one of the few remaining ways in which x86 can be said to be ‘better’ than ARM (early Acorn floating-point coprocessors also supported 80-bit FP in hardware, but for some reason this capability was dropped when integrated into the CPU). Apple’s ‘Rosetta 2’ x86 emulation works remarkably well, including the FPU, so it would be interesting to see how they have tackled 80-bit floating-point arithmetic in ARM code (unless they’ve squirreled some ‘secret’ hardware support for it into the Apple Silicon CPUs). |
|
Apple Silicon implements a non-standard FPU design for ARMv8 which has been shown to be identical to an x86 FPU design, opposed to the standard ARMv8 design. |
|
That would certainly explain it, I wish all ARMs did the same. It’s not what it says here however. |
|
I can imagine a couple of possible reasons why they don’t: there could be a licence fee involved, or a performance hit in execution speed or in energy consumption or both. I don’t know whether any of these apply though. And/or there could be a big customer (phone manufacturer?) who has different requirements. |
|
There wouldn’t be a licence fee for using an IEEE-standard, and the implementation used in Acorn’s floating-point coprocessor probably ended up belonging to ARM anyway. The Rosetta 2 article has some fascinating insights into other extensions of the armv8 instruction set seemingly designed specifically for x86 compatibility, but couched in terms like “alternate” behaviour. It’s particularly interesting that flag-setting instructions on Apple Silicon CPUs can optionally affect two additional flag bits – which happen to be identical to the x86 AF and PF flags! :-) |
|
So technically it isn’t IEEE compliant then?
Apple used x86 prior. Perhaps this is intended to simplify some of the clever tricks their compiler does when porting from this to that? |
|
Indeed not, but there could be for a particular method of implementation.
Almost certainly. It’s not Acorn’s FPC implementation that might need a licence, it’s Intel’s implementation of the IEEE-standard that might. Presumably Apple has that licence, if so – but ARM hasn’t put it in other implementations of ARM Arch64. |
|
I wouldn’t expect an ARM CPU vendor to have access to, or to want to copy, Intel’s implementation of anything! I assume they would either build it from scratch, or base it on what Acorn did in their coprocessor. Indeed the stack-based Intel FPU is not well suited to the way an interpreter does things, and in my versions of BBC BASIC I’m constantly moving data between the FPU registers and regular CPU registers, which is inefficient. |
|
Nor would I, it’s bonkers. It’s not my idea at all, it’s a quote by you from Andrew – just a day ago.
|
|
Why do you say that? |
|
I’m trying to find the article I read that showed that the Apple M series CPUs showed the same FP calculation errors as Intel’s opposed to what is expected from ARM when undertaking the same calculation |
|
Maybe this https://eclecticlight.co/2021/04/22/can-you-trust-floating-point-arithmetic-on-apple-silicon/. |
|
While Apple have baked in some assist-for-Intel into Apple Silicon for performance, it’s believed that the 80-bit floating point is handled with soft fp: https://dougallj.wordpress.com/2022/11/09/why-is-rosetta-2-fast/ |