1#include <stdlib.h> 2#include <assert.h> 3#include <stdio.h> 4#include <stdint.h> 5#include <inttypes.h> 6 7/* This testcase is to illustrate that for convert to fixed the condition 8 code depends on the rounding mode. */ 9 10const char * 11rtext(unsigned round) 12{ 13 switch (round) { 14 case 0: return "[fpc]"; 15 case 1: return "[->near/away]"; 16 /* 2 is invalid */ 17 case 3: return "[prep short]"; 18 case 4: return "[->near/even]"; 19 case 5: return "[->0]"; 20 case 6: return "[->+inf]"; 21 case 7: return "[->-inf]"; 22 } 23 assert(0); 24} 25 26#define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \ 27do { \ 28 src_type src = value; \ 29 dst_type dst; \ 30 unsigned cc; \ 31 \ 32 __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \ 33 "ipm %[cc]\n\t" \ 34 "srl %[cc],28\n\t" \ 35 : [dst] "=d"(dst), [cc] "=d"(cc) \ 36 : [src] "f"(src) \ 37 : "cc"); \ 38 \ 39 printf("%s %-20s %f\t-> %"dst_fmt"\tcc = %u\n", \ 40 opcode, rtext(round), src, dst, cc); \ 41} while (0) 42 43 44#define cfdbr(round,value) \ 45 convert_to_int("cfdbr",double,int32_t,PRId32,round,value) 46 47int main(void) 48{ 49 double dval; 50 51 dval = -2147483648.5; // a < MN 52 53 // f64 -> i32 54 55 cfdbr(4, dval); // round to nearest with ties to even 56 cfdbr(5, dval); // round to zero 57 cfdbr(6, dval); // round to +inf 58 59 /* The next invocation needs to give cc=3. It used to give cc=1 when 60 we were considering the to-be-converted value ONLY */ 61 cfdbr(7, dval); // round to -inf 62 63 return 0; 64} 65