Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12606 Discussions

Custom Instructions: Single-precision -mcustom-* compiler options

Altera_Forum
Honored Contributor II
1,079 Views

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
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
358 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

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 retWe tried it with gcc3 and gcc4. It's not working for both. 

 

Have you done it successfully?
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

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 retBut never mind, it's working:-) 

So thanks for your guiding to a solution! 

 

Regards
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
358 Views

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.
0 Kudos
Reply