Well, the ABI does allow for floats to be passed. And it is efficient to use registers since it needs to be calculated in FPRs. But AmigaOS doesn't traditionally pass floats in library functions. As well as the A1222 having non standard FPU. The taglist is restricted to 32 bit words and has been criticised for being unable so support 64 bit types directly. It is however designed to be key/value system with pointers. Tags do have flags so they could be extended but that would involve extending to 64 bits, either to mixed or 64 only. Tags have flags lol.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
But AmigaOS doesn't traditionally pass floats in library functions
I’m really not sure why that is, but I can imagine it’s because of the choice of ABI, that uses register passing, and most 680x0 cpu did not have FPU they run into little problem, even so, it can be passed on standard A0-A7 registers, perhaps an address a float, or double instead of value of. Some functions use fix float type, where decimal point is moved to a fixed position on a integer.
Quote:
As well as the A1222 having nonstandard FPU. The taglist is restricted to 32 bit words and has been criticised for being unable so support 64 bit types directly. It is however designed to be key/value system with pointers.
But you can do the same with var args,
type=va_var(args,int); // type value=va_var(args,double); // value
double is the same size as uint64. value=va_var(args,uint64); // value
or perhaps a class that can do the set and get stuff internally using inline assembly, or soft float. Quote:
Tags do have flags so they could be extended but that would involve extending to 64 bits, either to mixed or 64 only. Tags have flags lol.
they can be variable length as with var args, technically, its question how does it initialize memory, it won’t as simple as setting up an array (I come back to this later).
how do you read it. the reading parts is simple use macros like var_arg(args,type) do.
tags lists advantage is of course it can be setup it once at top of the code, and forgotten it, while var args, has to be built on stack in place, every time you call a function.
I think you can write taglist initialize function that takes var args as parameter. this can be as easy as calculate size, allocate memory and copy memory from stack to your local array.
see va_copy() macro.
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.
I’m really not sure why that is, but I can imagine it’s because of the choice of ABI, that uses register passing, and most 680x0 cpu did not have FPU they run into little problem, even so, it can be passed on standard A0-A7 registers, perhaps an address a float, or double instead of value of. Some functions use fix float type, where decimal point is moved to a fixed position on a integer.
I agree, the 68000 lacked FPU, so the OS couldn't rely on it. In fact through the OS history they had trouble keeping up with CPU. Mostly after OS3.1 as that was A500 compatible. But with OSS3.5+, which was post Commodore, they required 32 bit 68020 up. Eventually this led to complaints about the latest OS not supporting the earliest CPU. Thus OS3.2 was produced for old fashioned 68000 only with better CPUs needing the driver. 68K series is too complicated.
Given the FPU had 80 bits precision for storage they couldn't fit directly into any register except an FPR. So a pointer to an FPU array makes sense. The fixed format is good for basic float calculations using just 32 bit integers. The OS did have those maths libraries as well which was an early OS standard for doing floats.
Quote:
But you can do the same with var args,
That's the thing. They are more complicated and specific to data. For example, they are used a lot for "messages" to BOOPSI objects. Now most of those are just long arrays but each method expects certain values in specific order. So in that respect they are similar to rigid structures like NewWindow but untyped. A BOOPSI message is a simple example.
A tag list is longer, since it contains key and values, but allows optional keys to be given with value and otherwise defaults set. So it's good for random data where order doesn't matter. But it needs to an array of longs.
Quote:
tags lists advantage is of course it can be setup it once at top of the code, and forgotten it, while var args, has to be built on stack in place, every time you call a function.
That could be up to compiler as well which could reserve static data. Though given locals tended to be taken from stack so it's just a bigger stack allocation. A static list need not be run time computed just like static tags. But once you need dynamic lists it needs building.
Quote:
I think you can write taglist initialize function that takes var args as parameter. this can be as easy as calculate size, allocate memory and copy memory from stack to your local array.
Yes a lot of OS functions do that. For some reason since 68K they look to be split into two different functions. But I didn't see why since in either case there would be a pointer to a long array in a data register.
The organised long array of tag lists makes it hard to expand. Not sure if any FPU specific libraries used tag lists. But the 64 bit question does come into this. For expanding data it should be 64 bit list array. This would of course bloat it out even more. But 64 bit is really only needed for a 64 bit CPU with 64 bit addresses. For now, a pointer to larger datatypes should be reasonable, since pointers are used a lot. This of course means a extra long word is needed.
The most obvious route to expansion in tag control flags. Expanding TAG_MORE and TAG_END. I don't think they could easily be included in a list like var args. So likely any 64 bit expansion would need a specific 64 bit list array. Unless tag was 32 bit and value 64 bit. But they need to consider CPU alignment issues as well.
Oh no… I think you lack creativity, or perhaps your confusing size of data bus with the size of address bus?
What I mean is the tag list has a specific size with each entry. Right now the pairs are always 32 bits each. For tag and data. For larger datatypes they are specified by a pointer to data.
Sure, tags could be expanded to accept larger types, so 32 bit tags could be matched to 64 bit data, or even 128 bit for vectors. But then there is an alignment issue, as each tag pair is designed to fit in even 64 bit boundaries. If a 32 bit tag has 64 bit data that tag pair is now 96 bits wide. So whole tag array is out of alignment. Mind you, utility.library has functions to iterate through tag arrays. But, they are designed as 32 bit arrays.
A 64 bit tag list could be considered as a substitute. But then, you need extended 64 bit functions. It would need to be considered for a 64 bit port of AmigaOS. Until then 32 bit pointers are not an issue. And variable data types can still be passed as pointer. So it's not really an issue yet, but it does mean data takes up more space than it needs. For example, a 64 bit double would need 4 longs in total. Tag, ptr, double data. Same as a 64 bit list would need directly as it happens.
Fix length, is not that good, I agree alligment is issue. making it smaller then 32bit, like 16bit or 8bit will sure create alligment issue, but sizeof(char)
case is_32bit_value:
value32 = *((uint32*) (ptr)); ptr+=4; break;
}
type = *((uint32*) ptr); ptr+=4;
}
The natural alternative to tag lists and var_args is overloaded methods. by definition function pointer is almost the same as virtual method, it’s a small jump from current implementation of AmigaOS4.1 interfaces.
C code, can be compiled by C++ compiler, so OS4.1 does not need to support C compiler anymore.
with over loaded methods, you do not need type argument, type and data argument, it already defined in the language standard. No need to interpret tag list, or var args to see what they contain.
var args and tag list will ways be slow, because they are in a array, or on stack. technical overloaded methods also are on stack, but type is known beforehand, sure it’s less flexible as you need to extend number of methods, to cope with different arguments.
Edited by LiveForIt on 2024/5/15 20:47:29 Edited by LiveForIt on 2024/5/16 12:25:25 Edited by LiveForIt on 2024/5/16 12:26:05 Edited by LiveForIt on 2024/5/16 12:26:44 Edited by LiveForIt on 2024/5/16 12:28:35 Edited by LiveForIt on 2024/5/16 12:49:24
(NutsAboutAmiga)
Basilisk II for AmigaOS4 AmigaInputAnywhere Excalibur and other tools and apps.