1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "tests/malloc.h" 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is a Marie Celeste instruction. Some IBM documents think it 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exists, others don't. The same appears to be true for 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown implementations - ppc970 doesn't think it exists, but POWER5 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does. */ 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndouble do_fre ( double x ) 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double block[2]; 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = x; 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lfd %%f1, 0(%0)\n\t" 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".long 0xfc200830\n\t" /* == fre %%f1,%%f1 */ 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stfd %%f1, 8(%0)" 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "b" (&block[0]) 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "memory", "fr1" 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return block[1]; 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndouble do_fres ( double x ) 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double block[2]; 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = x; 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lfd %%f1, 0(%0)\n\t" 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "fres %%f1,%%f1\n\t" 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stfd %%f1, 8(%0)" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "b" (&block[0]) 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "memory", "fr1" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return block[1]; 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndouble do_frsqrte ( double x ) 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double block[2]; 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = x; 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lfd %%f1, 0(%0)\n\t" 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "frsqrte %%f1,%%f1\n\t" 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stfd %%f1, 8(%0)" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "b" (&block[0]) 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "memory", "fr1" 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return block[1]; 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Another Marie Celeste insn. */ 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndouble do_frsqrtes ( double x ) 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double block[2]; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = x; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "lfd %%f1, 0(%0)\n\t" 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ".long 0xec200834\n\t" /* == frsqrtes %%f1,%%f1 */ 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stfd %%f1, 8(%0)" 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "b" (&block[0]) 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "memory", "fr1" 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return block[1]; 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//////////////////////////////////////////////////////////// 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_one ( char* name, 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double(*f)(double), 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double* args, int nargs, 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char* argfmt, char* resfmt ) 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double a, r; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("\n"); 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < nargs; i++) { 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a = args[i]; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r = f(a); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("%s ", name); 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf(argfmt, a); 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf(" -> "); 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf(resfmt, r); 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("\n"); 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void ) 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int nargs = 19; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double* args = malloc(nargs * sizeof(double)); 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[0] = 0.0; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[1] = 1.0 / 0.0; // inf 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[2] = -args[1]; // -inf 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[3] = args[2]/args[2]; // nan 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[4] = -args[3]; // -nan 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[5] = -5e100; 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[6] = -5e20; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[7] = -501.0; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[8] = -6.0; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[9] = -1.01; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[10] = -2e-20; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[11] = -2e-200; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[12] = 2e-200; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[13] = 2e-20; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[14] = 1.01; 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[15] = 6.0; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[16] = 501.0; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[17] = 5e20; 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown args[18] = 5e100; 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one( "fre", do_fre, args, nargs, "%e", "%4.1e"); 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one( "fres", do_fres, args, nargs, "%e", "%4.1e"); 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one( "frsqrte", do_frsqrte, args, nargs, "%e", "%4.1e"); 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_one( "frsqrtes", do_frsqrtes, args, nargs, "%e", "%4.1e"); 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free(args); 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 125