1 #include <float.h> 2 #include <stdio.h> 3 #include <assert.h> 4 #include "opcodes.h" 5 6 7 #define L2F(insn, initial, target,round) \ 8 ({ \ 9 register unsigned long source asm("2") = initial; \ 10 register typeof(target) _t asm("f0"); \ 11 asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source)); \ 12 _t; \ 13 }) 14 15 #define F2L(insn, initial, type, round, cc) \ 16 ({ \ 17 register type source asm("f0") = initial; \ 18 register unsigned long target asm ("2") = 0; \ 19 asm volatile(insn(round,0,2,0) \ 20 "ipm %1\n\t" \ 21 "srl %1,28\n\t" \ 22 :"=d" (target), "=d" (cc) :"f"(source):"cc"); \ 23 target; \ 24 }) 25 26 27 #define DO_INSN_L2F32(insn, round) \ 28 ({ \ 29 float f32; \ 30 printf(#insn " %f\n", L2F(insn, 0, f32, round)); \ 31 printf(#insn " %f\n", L2F(insn, 1, f32, round)); \ 32 printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f32, round)); \ 33 printf(#insn " %f\n", L2F(insn, 0x80000000UL, f32, round)); \ 34 printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f32, round)); \ 35 printf(#insn " %f\n", L2F(insn, 0x100000000UL, f32, round)); \ 36 printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f32, round)); \ 37 printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f32, round)); \ 38 printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f32, round)); \ 39 }) 40 41 #define DO_INSN_L2F64(insn, round) \ 42 ({ \ 43 double f64; \ 44 printf(#insn " %f\n", L2F(insn, 0, f64, round)); \ 45 printf(#insn " %f\n", L2F(insn, 1, f64, round)); \ 46 printf(#insn " %f\n", L2F(insn, 0xffffffffUL, f64, round)); \ 47 printf(#insn " %f\n", L2F(insn, 0x80000000UL, f64, round)); \ 48 printf(#insn " %f\n", L2F(insn, 0x7fffffffUL, f64, round)); \ 49 printf(#insn " %f\n", L2F(insn, 0x100000000UL, f64, round)); \ 50 printf(#insn " %f\n", L2F(insn, 0xffffffffffffffffUL, f64, round)); \ 51 printf(#insn " %f\n", L2F(insn, 0x8000000000000000UL, f64, round)); \ 52 printf(#insn " %f\n", L2F(insn, 0x7fffffffffffffffUL, f64, round)); \ 53 }) 54 55 #define DO_INSN_L2F128(insn, round) \ 56 ({ \ 57 long double f128; \ 58 printf(#insn " %Lf\n", L2F(insn, 0, f128, round)); \ 59 printf(#insn " %Lf\n", L2F(insn, 1, f128, round)); \ 60 printf(#insn " %Lf\n", L2F(insn, 0xffffffffUL, f128, round)); \ 61 printf(#insn " %Lf\n", L2F(insn, 0x80000000UL, f128, round)); \ 62 printf(#insn " %Lf\n", L2F(insn, 0x7fffffffUL, f128, round)); \ 63 printf(#insn " %Lf\n", L2F(insn, 0x100000000UL, f128, round)); \ 64 printf(#insn " %Lf\n", L2F(insn, 0xffffffffffffffffUL, f128, round)); \ 65 printf(#insn " %Lf\n", L2F(insn, 0x8000000000000000UL, f128, round)); \ 66 printf(#insn " %Lf\n", L2F(insn, 0x7fffffffffffffffUL, f128, round)); \ 67 }) 68 69 #define DO_INSN_F2L(insn, round, type) \ 70 ({ \ 71 int cc; \ 72 printf(#insn " %lu ", F2L(insn, -1.1, type, round, cc)); \ 73 printf("cc=%d\n", cc); \ 74 printf(#insn " %lu ", F2L(insn, 0, type, round, cc)); \ 75 printf("cc=%d\n", cc); \ 76 printf(#insn " %lu ", F2L(insn, 1, type, round, cc)); \ 77 printf("cc=%d\n", cc); \ 78 printf(#insn " %lu ", F2L(insn, 1.4, type, round, cc)); \ 79 printf("cc=%d\n", cc); \ 80 printf(#insn " %lu ", F2L(insn, 1.5, type, round, cc)); \ 81 printf("cc=%d\n", cc); \ 82 printf(#insn " %lu ", F2L(insn, 1.6, type, round, cc)); \ 83 printf("cc=%d\n", cc); \ 84 printf(#insn " %lu ", F2L(insn, 1.6E+4, type, round, cc)); \ 85 printf("cc=%d\n", cc); \ 86 printf(#insn " %lu ", F2L(insn, 1.6E+8, type, round, cc)); \ 87 printf("cc=%d\n", cc); \ 88 printf(#insn " %lu ", F2L(insn, 1.6E+12, type, round, cc)); \ 89 printf("cc=%d\n", cc); \ 90 printf(#insn " %lu ", F2L(insn, 1.6E+20, type, round, cc)); \ 91 printf("cc=%d\n", cc); \ 92 printf(#insn " %lu ", F2L(insn, 1.6E+200, type, round, cc)); \ 93 printf("cc=%d\n", cc); \ 94 printf(#insn " %lu ", F2L(insn, 1.6E+2000L, type, round, cc)); \ 95 printf("cc=%d\n", cc); \ 96 printf(#insn " %lu ", F2L(insn, 1.6E-4, type, round, cc)); \ 97 printf("cc=%d\n", cc); \ 98 printf(#insn " %lu ", F2L(insn, FLT_MIN, type, round, cc)); \ 99 printf("cc=%d\n", cc); \ 100 printf(#insn " %lu ", F2L(insn, FLT_MAX, type, round, cc)); \ 101 printf("cc=%d\n", cc); \ 102 printf(#insn " %lu ", F2L(insn, DBL_MIN, type, round, cc)); \ 103 printf("cc=%d\n", cc); \ 104 printf(#insn " %lu ", F2L(insn, DBL_MAX, type, round, cc)); \ 105 printf("cc=%d\n", cc); \ 106 printf(#insn " %lu ", F2L(insn, LDBL_MIN, type, round, cc)); \ 107 printf("cc=%d\n", cc); \ 108 printf(#insn " %lu ", F2L(insn, LDBL_MAX, type, round, cc)); \ 109 printf("cc=%d\n", cc); \ 110 }) 111 112 #define DO_L2F(round) \ 113 ({ \ 114 DO_INSN_L2F32(CELFBR, round); \ 115 DO_INSN_L2F32(CELGBR, round); \ 116 DO_INSN_L2F64(CDLFBR, round); \ 117 DO_INSN_L2F64(CDLGBR, round); \ 118 DO_INSN_L2F128(CXLFBR, round); \ 119 DO_INSN_L2F128(CXLGBR, round); \ 120 }) 121 122 #define DO_F2L(round) \ 123 ({ \ 124 DO_INSN_F2L(CLFEBR, round, float); \ 125 DO_INSN_F2L(CLGEBR, round, float); \ 126 DO_INSN_F2L(CLFDBR, round, double); \ 127 DO_INSN_F2L(CLGDBR, round, double); \ 128 DO_INSN_F2L(CLFXBR, round, long double); \ 129 DO_INSN_F2L(CLGXBR, round, long double); \ 130 }) 131 132 133 int main() 134 { 135 assert(sizeof(long double) == 16); 136 DO_L2F(4); 137 DO_F2L(4); 138 139 DO_L2F(5); 140 DO_F2L(5); 141 142 DO_L2F(6); 143 DO_F2L(6); 144 145 DO_L2F(7); 146 DO_F2L(7); 147 148 return 0; 149 } 150