tags:

views:

111

answers:

2

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..

I think i need to set the Rounding Control field of the FPU Control Word in accordance with the second argument?. 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.

Can someone give me an example of how i would use the RC fields? Or am i way off base with what i need to do?

I am going off this page.. http://www.website.masmforum.com/tutorials/fptute/fpuchap1.htm

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..

#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;
}
A: 

Have you checked if your environment includes the improved C99 floating point support? C99 defines the functions fegetround() and fesetround() to get and set the current floating point rounding mode. The rint() function can then be used to round according to the current rounding mode.

caf
I want to do it myself. I do not want to use a pre built function. I am trying to learn c with assembly.
Corey
A: 

If you have a memory variable called hwcntrlwd with the bits correctly set: (intel syntax)

mov eax,[hwcntrlwd]
fstcw ax
Arthur Kalliokoski
So, in my case i could do something like: mov eax,[n - ROUND_NEAREST_EVEN] // whatever enum mode?fstcw ax
Corey