#include <stdlib.h> #include <assert.h> #include <stdio.h> #include <stdint.h> #include <inttypes.h> /* This testcase is to illustrate that for convert to fixed the condition code depends on the rounding mode. */ const char * rtext(unsigned round) { switch (round) { case 0: return "[fpc]"; case 1: return "[->near/away]"; /* 2 is invalid */ case 3: return "[prep short]"; case 4: return "[->near/even]"; case 5: return "[->0]"; case 6: return "[->+inf]"; case 7: return "[->-inf]"; } assert(0); } #define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \ do { \ src_type src = value; \ dst_type dst; \ unsigned cc; \ \ __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \ "ipm %[cc]\n\t" \ "srl %[cc],28\n\t" \ : [dst] "=d"(dst), [cc] "=d"(cc) \ : [src] "f"(src) \ : "cc"); \ \ printf("%s %-20s %f\t-> %"dst_fmt"\tcc = %u\n", \ opcode, rtext(round), src, dst, cc); \ } while (0) #define cfdbr(round,value) \ convert_to_int("cfdbr",double,int32_t,PRId32,round,value) int main(void) { double dval; dval = -2147483648.5; // a < MN // f64 -> i32 cfdbr(4, dval); // round to nearest with ties to even cfdbr(5, dval); // round to zero cfdbr(6, dval); // round to +inf /* The next invocation needs to give cc=3. It used to give cc=1 when we were considering the to-be-converted value ONLY */ cfdbr(7, dval); // round to -inf return 0; }