#include #include #include #include static void div_su(void) { asm("divt/su %0,%1,$f0; trapb" : : "f"(1.0), "f"(3.0) : "$f0"); } static void div_sui(void) { asm("divt/su %0,%1,$f0; trapb" : : "f"(1.0), "f"(3.0) : "$f0"); } static void mul_su(void) { asm("mult/su %0,%0,$f0; trapb" : : "f"(DBL_MIN) : "$f0"); } static void mul_sui(void) { asm("mult/sui %0,%0,$f0; trapb" : : "f"(DBL_MIN) : "$f0"); } static void cvttq_45(void) { asm("cvttq/c %0,$f0; trapb" : : "f"(4.5) : "$f0"); } static void cvttq_sv_45(void) { asm("cvttq/svc %0,$f0; trapb" : : "f"(4.5) : "$f0"); } static void cvttq_svi_45(void) { asm("cvttq/svic %0,$f0; trapb" : : "f"(4.5) : "$f0"); } static void cvttq_max(void) { asm("cvttq/c %0,$f0; trapb" : : "f"(DBL_MAX) : "$f0"); } static void cvttq_sv_max(void) { asm("cvttq/svc %0,$f0; trapb" : : "f"(DBL_MAX) : "$f0"); } static void cvttq_svi_max(void) { asm("cvttq/svic %0,$f0; trapb" : : "f"(DBL_MAX) : "$f0"); } static struct test { void (*fn)(void); const char *name; } const tests[] = { { div_su, "/su : 1/3" }, { div_sui, "/sui : 1/3" }, { mul_su, "/su : min*min" }, { mul_sui, "/sui : min*min" }, { cvttq_45, "/ : (long)4.5" }, { cvttq_sv_45, "/sv : (long)4.5" }, { cvttq_svi_45, "/svi : (long)4.5" }, { cvttq_max, "/ : (long)max" }, { cvttq_sv_max, "/sv : (long)max" }, { cvttq_svi_max, "/svi : (long)max" }, }; int main() { char result[8]; int i, e; for (i = 0; i < sizeof(tests)/sizeof(struct test); ++i) { feclearexcept(FE_ALL_EXCEPT); tests[i].fn(); e = fetestexcept(FE_ALL_EXCEPT); result[0] = e & FE_DIVBYZERO ? 'd' : '-'; result[1] = e & FE_INEXACT ? 'i' : '-'; result[2] = e & FE_INVALID ? 'I' : '-'; result[3] = e & FE_OVERFLOW ? 'o' : '-'; result[4] = e & FE_UNDERFLOW ? 'u' : '-'; result[5] = '\0'; printf("%-20s %s\n", tests[i].name, result); } return 0; }