#include <assert.h> #include <stdlib.h> #include <stdio.h> #include "opcodes.h" #define srnmb(b,d) \ ({ \ __asm__ volatile ( "lghi 8," #b "\n\t" \ SRNMB(8,d) \ ::: "8"); \ }) /* Like srnm above, except it uses r0 as a base register */ #define srnmb0(d) \ ({ \ __asm__ volatile ( SRNMB(0,d) \ ::: "0"); \ }) unsigned get_rounding_mode(void) { unsigned fpc; __asm__ volatile ("stfpc %0\n\t" : "=m"(fpc)); return fpc & 0x7; } int main(void) { printf("initial rounding mode = %u\n", get_rounding_mode()); /* Set basic rounding modes in various ways */ srnmb(1,002); // 1 + 2 = 3 printf("rounding mode = %u\n", get_rounding_mode()); srnmb(2,000); printf("rounding mode = %u\n", get_rounding_mode()); srnmb(0,001); printf("rounding mode = %u\n", get_rounding_mode()); srnmb(0,000); printf("rounding mode = %u\n", get_rounding_mode()); #if 0 // fpext srnmb(7,000); // -> 7 printf("rounding mode = %u\n", get_rounding_mode()); srnmb(0,000); // -> 0 printf("rounding mode = %u\n", get_rounding_mode()); srnmb(0,007); // -> 7 printf("rounding mode = %u\n", get_rounding_mode()); #endif srnmb(0,001); printf("rounding mode = %u\n", get_rounding_mode()); srnmb0(004); // -> emul warning invalid rounding mode printf("rounding mode = %u\n", get_rounding_mode()); return 0; }