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