mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-14 19:36:18 +00:00
125 lines
2.6 KiB
C
125 lines
2.6 KiB
C
|
|
#include <stdio.h>
|
|
#include "tests/malloc.h"
|
|
|
|
/* This is a Marie Celeste instruction. Some IBM documents think it
|
|
exists, others don't. The same appears to be true for
|
|
implementations - ppc970 doesn't think it exists, but POWER5
|
|
does. */
|
|
double do_fre ( double x )
|
|
{
|
|
double block[2];
|
|
block[0] = x;
|
|
__asm__ __volatile__(
|
|
"lfd %%f1, 0(%0)\n\t"
|
|
".long 0xfc200830\n\t" /* == fre %%f1,%%f1 */
|
|
"stfd %%f1, 8(%0)"
|
|
: /*out*/
|
|
: /*in*/ "b" (&block[0])
|
|
: /*trash*/ "memory", "fr1"
|
|
);
|
|
return block[1];
|
|
}
|
|
|
|
double do_fres ( double x )
|
|
{
|
|
double block[2];
|
|
block[0] = x;
|
|
__asm__ __volatile__(
|
|
"lfd %%f1, 0(%0)\n\t"
|
|
"fres %%f1,%%f1\n\t"
|
|
"stfd %%f1, 8(%0)"
|
|
: /*out*/
|
|
: /*in*/ "b" (&block[0])
|
|
: /*trash*/ "memory", "fr1"
|
|
);
|
|
return block[1];
|
|
}
|
|
|
|
double do_frsqrte ( double x )
|
|
{
|
|
double block[2];
|
|
block[0] = x;
|
|
__asm__ __volatile__(
|
|
"lfd %%f1, 0(%0)\n\t"
|
|
"frsqrte %%f1,%%f1\n\t"
|
|
"stfd %%f1, 8(%0)"
|
|
: /*out*/
|
|
: /*in*/ "b" (&block[0])
|
|
: /*trash*/ "memory", "fr1"
|
|
);
|
|
return block[1];
|
|
}
|
|
|
|
/* Another Marie Celeste insn. */
|
|
double do_frsqrtes ( double x )
|
|
{
|
|
double block[2];
|
|
block[0] = x;
|
|
__asm__ __volatile__(
|
|
"lfd %%f1, 0(%0)\n\t"
|
|
".long 0xec200834\n\t" /* == frsqrtes %%f1,%%f1 */
|
|
"stfd %%f1, 8(%0)"
|
|
: /*out*/
|
|
: /*in*/ "b" (&block[0])
|
|
: /*trash*/ "memory", "fr1"
|
|
);
|
|
return block[1];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
|
void do_one ( char* name,
|
|
double(*f)(double),
|
|
double* args, int nargs,
|
|
char* argfmt, char* resfmt )
|
|
{
|
|
int i;
|
|
double a, r;
|
|
printf("\n");
|
|
|
|
for (i = 0; i < nargs; i++) {
|
|
a = args[i];
|
|
r = f(a);
|
|
printf("%s ", name);
|
|
printf(argfmt, a);
|
|
printf(" -> ");
|
|
printf(resfmt, r);
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
int main ( void )
|
|
{
|
|
int nargs = 19;
|
|
double* args = malloc(nargs * sizeof(double));
|
|
args[0] = 0.0;
|
|
args[1] = 1.0 / 0.0; // inf
|
|
args[2] = -args[1]; // -inf
|
|
args[3] = args[2]/args[2]; // nan
|
|
args[4] = -args[3]; // -nan
|
|
args[5] = -5e100;
|
|
args[6] = -5e20;
|
|
args[7] = -501.0;
|
|
args[8] = -6.0;
|
|
args[9] = -1.01;
|
|
args[10] = -2e-20;
|
|
args[11] = -2e-200;
|
|
args[12] = 2e-200;
|
|
args[13] = 2e-20;
|
|
args[14] = 1.01;
|
|
args[15] = 6.0;
|
|
args[16] = 501.0;
|
|
args[17] = 5e20;
|
|
args[18] = 5e100;
|
|
|
|
do_one( "fre", do_fre, args, nargs, "%e", "%4.1e");
|
|
do_one( "fres", do_fres, args, nargs, "%e", "%4.1e");
|
|
|
|
do_one( "frsqrte", do_frsqrte, args, nargs, "%e", "%4.1e");
|
|
do_one( "frsqrtes", do_frsqrtes, args, nargs, "%e", "%4.1e");
|
|
|
|
free(args);
|
|
return 0;
|
|
}
|