10d48b436SJoseph Myers /* Test fscale instruction. */ 20d48b436SJoseph Myers 30d48b436SJoseph Myers #include <stdint.h> 40d48b436SJoseph Myers #include <stdio.h> 50d48b436SJoseph Myers 60d48b436SJoseph Myers union u { 70d48b436SJoseph Myers struct { uint64_t sig; uint16_t sign_exp; } s; 80d48b436SJoseph Myers long double ld; 90d48b436SJoseph Myers }; 100d48b436SJoseph Myers 11*b40eec96SJoseph Myers volatile union u ld_invalid_1 = { .s = { 1, 1234 } }; 12*b40eec96SJoseph Myers volatile union u ld_invalid_2 = { .s = { 0, 1234 } }; 13*b40eec96SJoseph Myers volatile union u ld_invalid_3 = { .s = { 0, 0x7fff } }; 14*b40eec96SJoseph Myers volatile union u ld_invalid_4 = { .s = { (UINT64_C(1) << 63) - 1, 0x7fff } }; 15*b40eec96SJoseph Myers 160d48b436SJoseph Myers volatile long double ld_res; 170d48b436SJoseph Myers 180d48b436SJoseph Myers int isnan_ld(long double x) 190d48b436SJoseph Myers { 200d48b436SJoseph Myers union u tmp = { .ld = x }; 210d48b436SJoseph Myers return ((tmp.s.sign_exp & 0x7fff) == 0x7fff && 220d48b436SJoseph Myers (tmp.s.sig >> 63) != 0 && 230d48b436SJoseph Myers (tmp.s.sig << 1) != 0); 240d48b436SJoseph Myers } 250d48b436SJoseph Myers 260d48b436SJoseph Myers int issignaling_ld(long double x) 270d48b436SJoseph Myers { 280d48b436SJoseph Myers union u tmp = { .ld = x }; 290d48b436SJoseph Myers return isnan_ld(x) && (tmp.s.sig & UINT64_C(0x4000000000000000)) == 0; 300d48b436SJoseph Myers } 310d48b436SJoseph Myers 320d48b436SJoseph Myers int main(void) 330d48b436SJoseph Myers { 340d48b436SJoseph Myers int ret = 0; 350d48b436SJoseph Myers __asm__ volatile ("fscale" : "=t" (ld_res) : 360d48b436SJoseph Myers "0" (2.5L), "u" (__builtin_nansl(""))); 370d48b436SJoseph Myers if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) { 380d48b436SJoseph Myers printf("FAIL: fscale snan\n"); 390d48b436SJoseph Myers ret = 1; 400d48b436SJoseph Myers } 41*b40eec96SJoseph Myers __asm__ volatile ("fscale" : "=t" (ld_res) : 42*b40eec96SJoseph Myers "0" (2.5L), "u" (ld_invalid_1.ld)); 43*b40eec96SJoseph Myers if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) { 44*b40eec96SJoseph Myers printf("FAIL: fscale invalid 1\n"); 45*b40eec96SJoseph Myers ret = 1; 46*b40eec96SJoseph Myers } 47*b40eec96SJoseph Myers __asm__ volatile ("fscale" : "=t" (ld_res) : 48*b40eec96SJoseph Myers "0" (2.5L), "u" (ld_invalid_2.ld)); 49*b40eec96SJoseph Myers if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) { 50*b40eec96SJoseph Myers printf("FAIL: fscale invalid 2\n"); 51*b40eec96SJoseph Myers ret = 1; 52*b40eec96SJoseph Myers } 53*b40eec96SJoseph Myers __asm__ volatile ("fscale" : "=t" (ld_res) : 54*b40eec96SJoseph Myers "0" (2.5L), "u" (ld_invalid_3.ld)); 55*b40eec96SJoseph Myers if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) { 56*b40eec96SJoseph Myers printf("FAIL: fscale invalid 3\n"); 57*b40eec96SJoseph Myers ret = 1; 58*b40eec96SJoseph Myers } 59*b40eec96SJoseph Myers __asm__ volatile ("fscale" : "=t" (ld_res) : 60*b40eec96SJoseph Myers "0" (2.5L), "u" (ld_invalid_4.ld)); 61*b40eec96SJoseph Myers if (!isnan_ld(ld_res) || issignaling_ld(ld_res)) { 62*b40eec96SJoseph Myers printf("FAIL: fscale invalid 4\n"); 63*b40eec96SJoseph Myers ret = 1; 64*b40eec96SJoseph Myers } 650d48b436SJoseph Myers return ret; 660d48b436SJoseph Myers } 67