1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Test conversions between 64- and 80- bit quiet NaNs. Uses 3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "canonical forms" for qNaNs. It also tests sNaNs but it's not 4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng clear what the canonical form of them should be, so the results are 5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pretty much irrelevant. Failure to do this right is the cause 6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng of https://bugzilla.mozilla.org/show_bug.cgi?id=738117 7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/ 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <assert.h> 10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h> 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdlib.h> 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <string.h> 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef unsigned char UChar; 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid do_64_to_80 ( UChar* dst, UChar* src ) 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__( 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "fldl (%0); fstpt (%1)" 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : : "r"(src), "r"(dst) : "memory" 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid do_80_to_64 ( UChar* dst, UChar* src ) 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ __volatile__( 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "fldt (%0); fstpl (%1)" 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : : "r"(src), "r"(dst) : "memory" 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ); 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid print80 ( char* s, UChar* v ) 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i; 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%s", s); 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 9; i >= 0; i--) 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%02x", (unsigned int)v[i]); 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid print64 ( char* s, UChar* v ) 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int i; 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%s", s); 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 7; i >= 0; i--) { 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("%02x", (unsigned int)v[i]); 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if 0 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid gen_qnan_64 ( UChar* dst ) 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SWAPC(_xx,_yy) { UChar tmp = _xx; _xx = _yy; _yy = tmp; } 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void rev64 ( UChar* f64 ) 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f64[0], f64[7] ); 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f64[1], f64[6] ); 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f64[2], f64[5] ); 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f64[3], f64[4] ); 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void rev80 ( UChar* f80 ) 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f80[0], f80[9] ); 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f80[1], f80[8] ); 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f80[2], f80[7] ); 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f80[3], f80[6] ); 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng SWAPC( f80[4], f80[5] ); 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef SWAPC 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main ( void ) 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar ref_qnan64[8] 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = { 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar ref_snan64[8] 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = { 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar ref_qnan80[10] 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = { 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar ref_snan80[10] 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = { 0x7f, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng rev64( ref_qnan64 ); 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng rev64( ref_snan64 ); 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng rev80( ref_qnan80 ); 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng rev80( ref_snan80 ); 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar* res = malloc(10); 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define ZAP memset(res, 0x55, 10) 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int pass; 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (pass = 1; pass <= 2; pass++) { 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZAP; do_64_to_80( res, ref_qnan64 ); 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print64( "src = qnan64: ", ref_qnan64 ); 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print80( "dst = qnan80: ", res ); 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZAP; do_64_to_80( res, ref_snan64 ); 112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print64( "src = snan64: ", ref_snan64 ); 113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print80( "dst = snan80: ", res ); 114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZAP; do_80_to_64( res, ref_qnan80 ); 117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print80( "src = qnan80: ", ref_qnan80 ); 118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print64( "dst = qnan64: ", res ); 119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ZAP; do_80_to_64( res, ref_snan80 ); 122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print80( "src = snan80: ", ref_snan80 ); 123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng print64( "dst = snan64: ", res ); 124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("\n"); 125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* now make all the reference inputs negative and do it again */ 127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ref_qnan64[7] ^= 0x80; 129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ref_snan64[7] ^= 0x80; 130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ref_qnan80[9] ^= 0x80; 132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ref_snan80[9] ^= 0x80; 133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#undef ZAP 137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng free(res); 139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 141