1#include <assert.h> 2#include <stdlib.h> 3#include <stdio.h> 4#include <stdint.h> 5#include <inttypes.h> 6#include "opcodes.h" 7#include "rounding.h" 8 9/* Test "fixbr" with rounding mode given in insn (m3 field) 10 Covers all generally available rounding modes that can be mapped to 11 IRRoundingMode. As a consequence m3=1 which is "round to nearest with 12 ties away from 0" is not tested here. 13*/ 14 15const char * 16rtext(unsigned m3_round) 17{ 18 switch (m3_round) { 19 case 0: return "[-> per fpc]"; 20 case 1: return "[-> nearest away]"; 21 case 3: return "[-> prepare short]"; // floating point extension fac needed 22 case 4: return "[-> nearest even]"; 23 case 5: return "[-> 0]"; 24 case 6: return "[-> +inf]"; 25 case 7: return "[-> -inf]"; 26 } 27 assert(0); 28} 29 30#define round_to_int(value,round) \ 31do { \ 32 long double src = value; \ 33 long double dst; \ 34 \ 35 __asm__ volatile ("fixbr %[dst]," #round ",%[src]\n\t" \ 36 : [dst] "=f"(dst) \ 37 : [src] "f"(src)); \ 38 \ 39 printf("fixbr %.5Lf\t-> %Lg %s\n", \ 40 src, dst, rtext(round)); \ 41} while (0) 42 43#define fixbr(value,round) round_to_int(value,round) 44 45void 46set_rounding_mode(unsigned mode) 47{ 48 register unsigned r asm("1") = mode; 49 __asm__ volatile ( SFPC(1) : : "d"(r) ); 50} 51 52 53int main(void) 54{ 55 int j; 56 static const long double dval[] = { 57 1.25, 1.5, 2.5, 1.75, -1.25, -1.5, -2.5, -1.75, 0.0, 58 }; 59 60 assert(sizeof(long double) == 16); 61 62 /* f128 -> f128, round to int */ 63 for (j = 0; j < sizeof dval / sizeof dval[0]; ++j) { 64 set_rounding_mode(FPC_BFP_ROUND_ZERO); 65 fixbr(dval[j], M3_BFP_ROUND_NEAREST_EVEN); 66 set_rounding_mode(FPC_BFP_ROUND_NEAREST_EVEN); 67 fixbr(dval[j], M3_BFP_ROUND_ZERO); 68 fixbr(dval[j], M3_BFP_ROUND_POSINF); 69 fixbr(dval[j], M3_BFP_ROUND_NEGINF); 70 } 71 72 return 0; 73} 74