I have a quick question about ARM float endianness, since I can't seem to find a concise listing of what devices & compiler situations result in the four upper and lower bytes in an ARM float being flipped.
I'm thinking about trying to include some sort of test for this, but I'd like to be able to use a configuration that has things flipped so that I can test things, and also know when to expect this behavior. It looks like, from the beta docs, that it simply depends on whether or not one is using an EABI or non-EABI compiler toolchain. I believe I've heard elsewhere that it's related to device type, and therefore I'm now just unsure :-) I'm thinking that it would be nice to do something like the following for float enabled cases: 1. set some float to a particular value 2. use a union or cast to look at the individual bytes and determine what pattern it might match. Certainly there could also be some defines or something else to clue things in at compile time, but autodetection would be nice in the sense that it isn't dependent on the compiler defining something to clue the code in. I'm not sure if there's fragility built into such an approach though. -- James Snyder Biomedical Engineering Northwestern University [hidden email] http://fanplastic.org/key.txt ph: (847) 448-0386 _______________________________________________ Elua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
I have a quick question about ARM float endianness, since I can't seem to find a concise listing of what devices & compiler situations result in the four upper and lower bytes in an ARM float being flipped. It's not really a compiler issue, it's about the ARM core implementation. Although the ARM architecture manual states that an ARM core should be able to support both little and big endian, I personally don't know of any ARM-based micro that actually gives you a choice here. The vaste majority are little endian and stay like that. I'm thinking about trying to include some sort of test for this, but I'd like to be able to use a configuration that has things flipped so that I can test things, and also know when to expect this behavior. Think AVR32 then :) Currently the only eLua target that can do big endian. It looks like, from the beta docs, that it simply depends on whether or not one is using an EABI or non-EABI compiler toolchain. Big or little endian have nothing to do with the toolchain. All the toolchains I know are capable of compiling little or big endian without problems, all you need to do is give the compiler/linker/assembler the correct options. I'm thinking that it would be nice to do something like the following for float enabled cases: You don't even need a float, the test is actually easier to implement with integers: int is_big_endian() { u32 test = 0x12345678; return *( ( u8 * )&test ) == 0x12; } Certainly there could also be some defines or something else to clue things in at compile time, but autodetection would be nice in the sense that it isn't dependent on the compiler defining something to clue the code in. I'm not sure if there's fragility built into such an approach though. Autodetection is so easy to do that you don't need any other macros. At least at runtime. Of course, if you're doing conditional compilation, you will need some macro to tell you if you're compiling for little or big endian. Best, Bogdan _______________________________________________ Elua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev |
On Jun 23, 2009, at 2:14 AM, Bogdan Marinescu wrote:
What I mean here are the cases where you have everything little endian except for the floats where the first four bytes are flipped with the last four bytes. That's what I'm getting the impression may be toolchain based. I'm thinking of the arm_float option provided by the cross compiler. In the updated docs you mention using arm_float for a non-EABI toolchain, and just float for an EABI toolchain.
Hmm... I don't have one unfortunately... maybe what I should do is get an emulator going with PowerPC or something similar running Linux and at least test things there to make sure that stuff gets negotiated properly. It currently is set up to use the native format for both ends (if they're the same), and default to network order (big endian) if they differ. I think this should be a reasonable compromise for speed (though with the current implementation I'm not sure how much of a speed hit is incurred by flipping everything).
I suppose I should check compiling with these options too. That might be one way to try big-endian on ARM.
Currently I'm just using the same test Lua does on an int: int test=1; target.little_endian=*(char*)&test; I suppose this works so long as int isn't only a single byte (or some other weird ordering can confuse it). Perhaps some efficient byte swapping and configuration checking functions would be good to have in the general toolchest of functions on eLua? It looks like on ARM platforms there are some fairly efficient ways to do this in the instruction set (not sure if this is exposed in C): I'm not that worried about speed, and it's probably the last thing I'll touch, but as with everything else, I prefer to leave as much time for the VM as possible, rather than wasting cycles on mundane stuff like byte swapping. I also figure this sort of thing might actually matter on faster links.
Right, I figure that this is actually more cross-compiler friendly as well. Since if integer or floating point representations don't match some pre-defined pattern anyways, they're going to require some additional mangling to get things to communicate anyways. -jsnyder _______________________________________________ Elua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev smime.p7s (2K) Download Attachment |
Anyone have any further thoughts?
here's a section from ldump.c that handles swapping if the particular mode is enabled: // ARM FPA mode: keep endianness, but swap high and low parts of the // memory representation. This is the default compilation mode for ARM // targets (at least with GCC) if(D->target.is_arm_fpa) { char *pnum=(char*)&y, temp[4]; memcpy(temp,pnum,4); memcpy(pnum,pnum+4,4); memcpy(pnum+4,temp,4); } In the beta docs, for stock standard gcc (I assume non-EABI) it is suggested that this is needed, however it does not suggest enabling this when using CodeSourcery's toolchain (EABI compliant). -jsnyder On Jun 23, 2009, at 9:46 AM, James Snyder wrote: > > On Jun 23, 2009, at 2:14 AM, Bogdan Marinescu wrote: > >> I have a quick question about ARM float endianness, since I can't >> seem to find a concise listing of what devices & compiler >> situations result in the four upper and lower bytes in an ARM float >> being flipped. >> >> It's not really a compiler issue, it's about the ARM core >> implementation. Although the ARM architecture manual states that an >> ARM core should be able to support both little and big endian, I >> personally don't know of any ARM-based micro that actually gives >> you a choice here. The vaste majority are little endian and stay >> like that. > > What I mean here are the cases where you have everything little > endian except for the floats where the first four bytes are flipped > with the last four bytes. That's what I'm getting the impression > may be toolchain based. > > I'm thinking of the arm_float option provided by the cross > compiler. In the updated docs you mention using arm_float for a non- > EABI toolchain, and just float for an EABI toolchain. > >> >> I'm thinking about trying to include some sort of test for this, >> but I'd like to be able to use a configuration that has things >> flipped so that I can test things, and also know when to expect >> this behavior. >> >> Think AVR32 then :) Currently the only eLua target that can do big >> endian. > > Hmm... I don't have one unfortunately... maybe what I should do is > get an emulator going with PowerPC or something similar running > Linux and at least test things there to make sure that stuff gets > negotiated properly. > > It currently is set up to use the native format for both ends (if > they're the same), and default to network order (big endian) if they > differ. I think this should be a reasonable compromise for speed > (though with the current implementation I'm not sure how much of a > speed hit is incurred by flipping everything). > >> >> It looks like, from the beta docs, that it simply depends on >> whether or not one is using an EABI or non-EABI compiler toolchain. >> >> Big or little endian have nothing to do with the toolchain. All the >> toolchains I know are capable of compiling little or big endian >> without problems, all you need to do is give the compiler/linker/ >> assembler the correct options. > > I suppose I should check compiling with these options too. That > might be one way to try big-endian on ARM. > >> >> I'm thinking that it would be nice to do something like the >> following for float enabled cases: >> 1. set some float to a particular value >> 2. use a union or cast to look at the individual bytes and >> determine what pattern it might match. >> >> You don't even need a float, the test is actually easier to >> implement with integers: >> >> int is_big_endian() >> { >> u32 test = 0x12345678; >> >> return *( ( u8 * )&test ) == 0x12; >> } > > Currently I'm just using the same test Lua does on an int: > > int test=1; > target.little_endian=*(char*)&test; > > I suppose this works so long as int isn't only a single byte (or > some other weird ordering can confuse it). > > Perhaps some efficient byte swapping and configuration checking > functions would be good to have in the general toolchest of > functions on eLua? > > It looks like on ARM platforms there are some fairly efficient ways > to do this in the instruction set (not sure if this is exposed in C): > http://www.doulos.com/knowhow/arm/Hints_and_Tips/Byte_Swapping/ > > I'm not that worried about speed, and it's probably the last thing > I'll touch, but as with everything else, I prefer to leave as much > time for the VM as possible, rather than wasting cycles on mundane > stuff like byte swapping. I also figure this sort of thing might > actually matter on faster links. > >> >> Certainly there could also be some defines or something else to >> clue things in at compile time, but autodetection would be nice in >> the sense that it isn't dependent on the compiler defining >> something to clue the code in. I'm not sure if there's fragility >> built into such an approach though. >> >> Autodetection is so easy to do that you don't need any other >> macros. At least at runtime. Of course, if you're doing conditional >> compilation, you will need some macro to tell you if you're >> compiling for little or big endian. > > Right, I figure that this is actually more cross-compiler friendly > as well. Since if integer or floating point representations don't > match some pre-defined pattern anyways, they're going to require > some additional mangling to get things to communicate anyways. > > -jsnyder > _______________________________________________ > Elua-dev mailing list > [hidden email] > https://lists.berlios.de/mailman/listinfo/elua-dev James Snyder Biomedical Engineering Northwestern University [hidden email] http://fanplastic.org/key.txt ph: 847.448.0386 _______________________________________________ Elua-dev mailing list [hidden email] https://lists.berlios.de/mailman/listinfo/elua-dev smime.p7s (5K) Download Attachment |
Free forum by Nabble | Edit this page |