T
thisismyidentity
Hi all,
I am trying to predict the behaviour of floating point load and store
operations on integer locations. I ve written a small piece of code
having some inline assembly code which I am describing here.
========================================================
#include<stdio.h>
#include<stdlib.h>
void fp_int_mem_ops(unsigned long);
void print_byte_vals(unsigned long);
static int unmatched_count = 0;
main ()
{
unsigned long foo;
int i, seed;
for(i = 1000 ; i < 500000; i++){// Just to generate some random
ints.
seed = rand();
srand(seed);
foo = rand();
fp_int_mem_ops(foo);
}
printf ("\n%d mismatches\n", unmatched_count);
return 0;
}
void fp_int_mem_ops(unsigned long location)
{
unsigned long fp, fp1;
printf("\n===\n");
printf("%x\n", location);
__asm__ __volatile__ (
"flds %1;"
"fstps %0;"
:"=m"(fp)
:"m"(location), "m" (fp1)
);
printf("%x\n", fp);
if(location != fp)
{
printf("NOT MATCHED\n");
unmatched_count++;
}
}
========================================================
In this code, my motive is to initialize a memory location with an
integer value and then do a floating point load from that location on
the FPU stack and store the Top of stack back to some other integer
location. I am trying to initialize the integer locations from which
the floating point loads happen with some random integers. After
running the above code some of the integer values get changed after FP
store operation. Some examples of unmatched values are:
===
7fafd17c
7fefd17c
===
7fbb8dc1
7ffb8dc1
===
7f99e608
7fd9e608
===
7f812d46
7fc12d46
As observed, in some of the cases the two values differ only in one
particular bit (22nd bit assuming lsb as 0th bit) and that too this
particular bit changing from 0 -> 1. Eg.
a -> e : 1010 -> 1110
b -> f : 1011 -> 1111
9 -> d : 1001 -> 1101
8 -> c : 1000 -> 1100
Above are the only four unique cases occuring.
The above observations clearly point to floating operations (most
probably FP load) doing some of the rounding stuff to those random
values. Bit 22 is also the last bit of mantissa in IEEE 754 format
(http://en.wikipedia.org/wiki/IEEE_754). I have tried the above code on
8-byte values too and in that case bit 51 gets flipped from 0 -> 1
(again note that 51st bit is last bit of mantissa in double-precision
numbers in IEEE 754 format).
Some of my doubts in light of above observations are:
-> Is that particular bit getting flipped coz of rounding or something
else creates the problem?
-> Assuming that rounding is happening, why shud it happen when the
values which we are picking up randomly are integers. Why should FPU
see those random bytes as some unrepresentable floating point numbers
(and do rounding) when they are already declared as integers ?
-> How shud I proceed to generate the numbers for which FP operations
do not create such mismatch ?
Given above observations, It will be really helpful if someone can give
insight into whats happening.
Thanks.
I am trying to predict the behaviour of floating point load and store
operations on integer locations. I ve written a small piece of code
having some inline assembly code which I am describing here.
========================================================
#include<stdio.h>
#include<stdlib.h>
void fp_int_mem_ops(unsigned long);
void print_byte_vals(unsigned long);
static int unmatched_count = 0;
main ()
{
unsigned long foo;
int i, seed;
for(i = 1000 ; i < 500000; i++){// Just to generate some random
ints.
seed = rand();
srand(seed);
foo = rand();
fp_int_mem_ops(foo);
}
printf ("\n%d mismatches\n", unmatched_count);
return 0;
}
void fp_int_mem_ops(unsigned long location)
{
unsigned long fp, fp1;
printf("\n===\n");
printf("%x\n", location);
__asm__ __volatile__ (
"flds %1;"
"fstps %0;"
:"=m"(fp)
:"m"(location), "m" (fp1)
);
printf("%x\n", fp);
if(location != fp)
{
printf("NOT MATCHED\n");
unmatched_count++;
}
}
========================================================
In this code, my motive is to initialize a memory location with an
integer value and then do a floating point load from that location on
the FPU stack and store the Top of stack back to some other integer
location. I am trying to initialize the integer locations from which
the floating point loads happen with some random integers. After
running the above code some of the integer values get changed after FP
store operation. Some examples of unmatched values are:
===
7fafd17c
7fefd17c
===
7fbb8dc1
7ffb8dc1
===
7f99e608
7fd9e608
===
7f812d46
7fc12d46
As observed, in some of the cases the two values differ only in one
particular bit (22nd bit assuming lsb as 0th bit) and that too this
particular bit changing from 0 -> 1. Eg.
a -> e : 1010 -> 1110
b -> f : 1011 -> 1111
9 -> d : 1001 -> 1101
8 -> c : 1000 -> 1100
Above are the only four unique cases occuring.
The above observations clearly point to floating operations (most
probably FP load) doing some of the rounding stuff to those random
values. Bit 22 is also the last bit of mantissa in IEEE 754 format
(http://en.wikipedia.org/wiki/IEEE_754). I have tried the above code on
8-byte values too and in that case bit 51 gets flipped from 0 -> 1
(again note that 51st bit is last bit of mantissa in double-precision
numbers in IEEE 754 format).
Some of my doubts in light of above observations are:
-> Is that particular bit getting flipped coz of rounding or something
else creates the problem?
-> Assuming that rounding is happening, why shud it happen when the
values which we are picking up randomly are integers. Why should FPU
see those random bytes as some unrepresentable floating point numbers
(and do rounding) when they are already declared as integers ?
-> How shud I proceed to generate the numbers for which FP operations
do not create such mismatch ?
Given above observations, It will be really helpful if someone can give
insight into whats happening.
Thanks.