- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
we have a couple of custom instructions (CI) for single precision floating point computing. Including <, >, <= ,int2float, float2int and all that. You can tell the compiler to use the CI instead of using the software implementation by setting some compiler options. For example the int to float typecast --- Quote Start --- -mcustom-floatis=N (with N the number of the CI) --- Quote End --- So all software calls to a typecast inside the code are replaced with the CI. This works pretty fine for the typecast int2float and float2int. But when it comes to floating point comparison, it does not work. I want the compiler to insert CI-call for floating point comparison:
if (float1 < float2)
{
.....
}
Therefore I use following compiler option (with 4 is the CI-number for lower comparison): --- Quote Start --- -mcustom-fcmplts=4 --- Quote End --- But when I take a look at the *.objdump it still calls the software implementation. does anybody know what i am doing wrong? Thanks for your efforts, Philipp
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Take a look at this one, it's really old but should still be applicable:
http://www.alterawiki.com/wiki/custom_floating_point_unit Assuming you supplied all the logical operators then I don't think you are seeing things like A > B optimized into B < A. However are you sure you are actually performing a single precision floating point comparison? For example if you did something like this I would expect it to turn into a double precision compare: if (my_float < 2.3) // 2.3 by default is double precision unless you use 2.3f or pass in a compiler flag to treat all constants as single precision values. If you post the flags you are passing to the compiler and the code you are seeing issues with (C and the objdump that accompanies it) we might have more pointers. Also if you are using gcc4 try the same compilation using gcc3. It could be a bug with the gcc4 port.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your post.
--- Quote Start --- However are you sure you are actually performing a single precision floating point comparison? --- Quote End --- Yes, I am or at least I think so. Here is my code for testing it. Should be single precision.float TEST_Float (float a, float b)
{
if (a<b)
a=b;
return a;
}
With following compiler (user) flags: --- Quote Start --- -mcustom-floatis=1 -mcustom-fixsi=2 -mcustom-fcmplts=25 -mcustom-fcmpgts=26 --- Quote End --- Becomes 020241b4 <TEST_Float>:
20241b4: defffd04 addi sp,sp,-12
20241b8: dc400115 stw r17,4(sp)
20241bc: dc000015 stw r16,0(sp)
20241c0: dfc00215 stw ra,8(sp)
20241c4: 2021883a mov r16,r4
20241c8: 2823883a mov r17,r5
20241cc: 202797c0 call 202797c <__ltsf2>
20241d0: 1000010e bge r2,zero,20241d8 <TEST_Float+0x24>
20241d4: 8821883a mov r16,r17
20241d8: 8005883a mov r2,r16
20241dc: dfc00217 ldw ra,8(sp)
20241e0: dc400117 ldw r17,4(sp)
20241e4: dc000017 ldw r16,0(sp)
20241e8: dec00304 addi sp,sp,12
20241ec: f800283a ret
We tried it with gcc3 and gcc4. It's not working for both. Have you done it successfully?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oops I said that wrong. A < B is equivalent to B >= A. Try passing in the flag for greater than or equal and see if the objdump contains the custom instruction mnemonic.
So I think your "if (a<b)" is being turned into "if(b>=a)" by the compiler.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now I added all CIs for floating point comparison. Not only the ones for >,<.
And it's working. The compiler flags I used: --- Quote Start --- -mcustom-floatis=1 -mcustom-fixsi=2 -mcustom-fcmplts=19 -mcustom-fcmples=20 -mcustom-fcmpgts=17 -mcustom-fcmpges=18 -mcustom-fcmpeqs=16 -mcustom-fcmpnes=21 --- Quote End --- --- Quote Start --- So I think your "if (a<b)" is being turned into "if(b>=a)" by the compiler. --- Quote End --- But actually the reason why it didn't work, seemed not to be the missing CI for the operator >= as you assumed. If I take a look at the *.objdump the compiler uses the CI for the operator <. (-O3 optimization)if ((float)a<(float)b)
a=b;
return a;
Becomes: 20239e0: 2143c4f2 custom 19,at,r4,r5
20239e4: 0800021e bne at,zero,20239f0 <TEST_Float+0x10>
20239e8: 2005883a mov r2,r4
20239ec: f800283a ret
20239f0: 2809883a mov r4,r5
20239f4: 2005883a mov r2,r4
20239f8: f800283a ret
But never mind, it's working:-) So thanks for your guiding to a solution! Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Possibly the compiler is assuming that the FP instructions are included in blocks, I have looked at the gcc code - but wasn't particularly interested in the FP bits.
That asm snippit also seems to have managed to use 'at' (r1 - assembler temporary). I've looked for, but never found, a place where it gets used. (Or have you explicitly enabled it in the compiler and assembler??) Actually it might be interesting to see the compiler output (foo.s) itself.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I've looked for, but never found, a place where it gets used. --- Quote End --- Did you not find it in the documentation or in the snippit? --- Quote Start --- (Or have you explicitly enabled it in the compiler and assembler??) --- Quote End --- No, I didn't. Don't know how. But honestly I don't know what you mean. What might I have enabled? Sorry, I am not so familiar with NIOS assembling language. We used Freescale DSP before. --- Quote Start --- Actually it might be interesting to see the compiler output (foo.s) itself. --- Quote End --- How can I get it? Didn't find it. Regards, Philipp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I searched the entire source tree for gcc and binutils :-)
'cc -S ...' will show you the asm, '-fverbose-asm' will give some extra info about the variable names. Not sure how you get the IDE to set those though - I keep as far away as I can from all IDEs.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page