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?
- Do i load the value into the FPU?
- 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;
}