Thread: gcc inline assembler - rounding mode

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221

    gcc inline assembler - rounding mode

    I am trying to write a function named roundD that rounds its first argument to an integer value according to the mode specified by its second argument.

    I will be writing the function in assembly language, using gcc’s inline assembler. I do not want to use any predefined functions.. preferably intels syntax
    please keep in mind i have studied for a week on how to accomplish this task.


    I also think i need to restore the original value of the Rounding Control field before roundD returns?

    I am trying to figure out how i should accomplish this in the right order..

    Should i use the Control Word of the FPU?

    1. Do i load the value into the FPU?
    2. Use the control word - BIT FIELDS to do the calculations?

    like: The RC field (bits 11 and 10) or Rounding Control determines how the FPU will round results.
    which in my case are the enum values..


    I am going off this page.. Simply FPU Chap.1

    is this a good page to go from? What else do i need to google for information? Any help is much appreciated.. I think i just need a detailed analysis of the steps i need to take to accomplish this..

    This is what i have so far.. This should give you a good idea on what i want to accomplish.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define PRECISION           3
    #define RND_CTL_BIT_SHIFT   10
    
    // floating point rounding modes: IA-32 Manual, Vol. 1, p. 4-20
    typedef enum {
    ROUND_NEAREST_EVEN =    0 << RND_CTL_BIT_SHIFT,
    ROUND_MINUS_INF =       1 << RND_CTL_BIT_SHIFT,
    ROUND_PLUS_INF =        2 << RND_CTL_BIT_SHIFT,
    ROUND_TOWARD_ZERO =     3 << RND_CTL_BIT_SHIFT
    } RoundingMode;
    
    double roundD (double n, RoundingMode roundingMode)
    {
    
    return n;
    
    
    }
    
    int main (int argc, char **argv)
    {
    double  n = 0.0;
    
    printf("Rounding - Assembly");
    if (argc > 1)
        n = atof(argv[1]);
    
    printf("roundD even %.*f = %.*f\n",
           PRECISION, n, PRECISION, roundD(n, ROUND_NEAREST_EVEN));
    printf("roundD down %.*f = %.*f\n",
           PRECISION, n, PRECISION, roundD(n, ROUND_MINUS_INF));
    printf("roundD up   %.*f = %.*f\n",
           PRECISION, n, PRECISION, roundD(n, ROUND_PLUS_INF));
    printf("roundD zero %.*f = %.*f\n",
           PRECISION, n, PRECISION, roundD(n, ROUND_TOWARD_ZERO));
    
    return 0;
    }
    I understand that :
    The RC field (bits 11 and 10) or Rounding Control determines how the FPU will round results in one of four ways:

    00 = Round to nearest, or to even if equidistant (this is the initialized state)
    01 = Round down (toward -infinity)
    10 = Round up (toward +infinity)
    11 = Truncate (toward 0)

    so, my enum should serve the same purpose?


    Do i need to do something like this?

    Code:
    push %ebp;
    movl %ebp, %eax;
    mov1 %eax[n- whatever enum rounding mode];    // double  n = 0.0;
    fstcw ax;
    I think i am confused on how to set the Rounding Control Field of the FPU control word accordance
    with the second argument in the function..
    Last edited by mrsirpoopsalot; 02-08-2010 at 02:33 PM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mrsirpoopsalot View Post
    I think i just need a detailed analysis of the steps i need to take to accomplish this.
    I've had that thought a few times myself

    This is a neat idea, if you are doing this out of an interest in assembly, but I dunno if that will really be advantageous, considering that rounding a number is a pretty simple, straightforward task that probably does not leave tons of room for optimization.

    Speaking of which, if that is what you are after, I'd have two functions (roundDown, roundUp) with one parameter rather than one function with an extra "mode" parameter. That will save you the overhead of evaluating a conditional every time (since I presume your goal here is something that's going to get called thousands of times a second, so you want it as tight as possible).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Fiddling with the FPU control word goes against your goal of being fast. Reprogramming the FPU rounding mode has serious, negative consequences, like flushing the floating point pipeline. If you have to read or write the control word, you may end up anywhere from tens to hundreds of times slower than if you hadn't.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    I was hoping someone could help me instead of telling me i should do it a different way.
    I was planning on using a switch statement to handle the different enum values being passed in.

    I am not really worried about optimization or being fast.
    I would like to keep it the way i have it. I am trying to learn assembly.
    is there a good book that could help me?
    thank you

    do i need to do something like

    int num;

    fld n ; //Push n' into st(0) of FPU stack?
    fist num ; //Convert and store st(0) to integer?
    fild num ; //Push integer to st(0) ?
    fnstsw %ax;
    mov %eax,[n - enum value];
    fstcw %ax;
    Last edited by mrsirpoopsalot; 02-08-2010 at 04:18 PM.

  5. #5
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Quote Originally Posted by mrsirpoopsalot View Post
    I was hoping someone could help me instead of telling me i should do it a different way.
    I was planning on using a switch statement to handle the different enum values being passed in.

    I am not really worried about optimization or being fast.
    I would like to keep it the way i have it. I am trying to learn assembly.
    is there a good book that could help me?
    thank you
    Seek out either Peter Nortons Guide to Intel Assembly Language or there are free Linux-based resources on the web for assembly....this is a C/C++ forum and while you are welcome to ask about your assy code, most are not assy coders that would respond which is why I recommend a reference volume..
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  6. #6
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    Quote Originally Posted by jeffcobb View Post
    Seek out either Peter Nortons Guide to Intel Assembly Language or there are free Linux-based resources on the web for assembly....this is a C/C++ forum and while you are welcome to ask about your assy code, most are not assy coders that would respond which is why I recommend a reference volume..
    I thought since its a mixture of C / assembly it whould be ok. Besides, dont c/c++ programmers need to know assembly to get their degrees?

    Thank you for the book recommendation..

  7. #7
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Quote Originally Posted by mrsirpoopsalot View Post
    I thought since its a mixture of C / assembly it whould be ok. Besides, dont c/c++ programmers need to know assembly to get their degrees?

    Thank you for the book recommendation..
    That implies you need a degree to be a C/C++ programmer. Assembly has nothing to do with either the C or C++ language, that's purely implementation specific.

  8. #8
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Quote Originally Posted by mrsirpoopsalot View Post
    I thought since its a mixture of C / assembly it whould be ok. Besides, dont c/c++ programmers need to know assembly to get their degrees?

    Thank you for the book recommendation..
    Maybe I don't know anymore. I picked up assembly back in 83 or so on the 6502...got to Intel circa 89 I think, realized it stunk on ice and never bothered with it again. It you are into it, that's your cross to bear...

    Most degrees these days also seem to require some Java but I don't how far you would get asking about C/Java (JNI) here either...
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Sorry, I assumed that you were using assembly for some practical purpose, not just trying to learn.

    You actually have to load the current control word, flip the bits 10 and 11 to what you want, then store it back again. If you just store a word into the CR which has those bits sets, you'll toggle a bunch of other bits that you didn't intend to change.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Sep 2006
    Location
    vancouver wa
    Posts
    221
    Quote Originally Posted by brewbuck View Post
    You actually have to load the current control word, flip the bits 10 and 11 to what you want, then store it back again. If you just store a word into the CR which has those bits sets, you'll toggle a bunch of other bits that you didn't intend to change.
    1. not sure how to load the control word.
    2. flip the bits 10 and 11 - isnt that what i am doing in the enum?

    crap, well i guess i am still lost. I ordered the book. I will do some more digging around.
    I am trying to learn the FPU.

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mrsirpoopsalot View Post
    I ordered the book.
    Hooray! Good move.

    I dunno any asm tho, so I can't comment further.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting C++ inline ASM from GCC to VS
    By ggoodesa in forum C++ Programming
    Replies: 4
    Last Post: 01-23-2010, 12:59 PM
  2. Undefined reference to...
    By legendus in forum C Programming
    Replies: 19
    Last Post: 10-25-2009, 06:18 AM
  3. Buidl Library with ./configure script
    By Jardon in forum C Programming
    Replies: 6
    Last Post: 07-24-2009, 09:36 AM
  4. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  5. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM