Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

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

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

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.