mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
94 lines
1.8 KiB
C
94 lines
1.8 KiB
C
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include "opcodes.h"
|
|
|
|
/* Test "convert from fixed" with universally available rounding modes.
|
|
Rounding mode is provided via FPC. */
|
|
|
|
volatile int32_t i32;
|
|
volatile int64_t i64;
|
|
|
|
const char *
|
|
rtext(unsigned fpc_round)
|
|
{
|
|
switch (fpc_round) {
|
|
case 0: return "[-> near]";
|
|
case 1: return "[-> zero]";
|
|
case 2: return "[-> +inf]";
|
|
case 3: return "[-> -inf]";
|
|
}
|
|
assert(0);
|
|
}
|
|
|
|
void
|
|
set_rounding_mode(unsigned mode)
|
|
{
|
|
printf("setting FPC rounding mode to %s\n", rtext(mode));
|
|
register unsigned r asm("1") = mode;
|
|
__asm__ volatile ( SFPC(1) : : "d"(r) );
|
|
}
|
|
|
|
void cefbr(unsigned mode)
|
|
{
|
|
set_rounding_mode(mode);
|
|
|
|
float out;
|
|
|
|
__asm__ volatile("cefbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i32));
|
|
printf("cefbr: %"PRId32" -> %f\n", i32, out);
|
|
}
|
|
|
|
void cegbr(unsigned mode)
|
|
{
|
|
set_rounding_mode(mode);
|
|
|
|
float out;
|
|
|
|
__asm__ volatile("cegbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
|
|
printf("cegbr: %"PRId64" -> %f\n", i64, out);
|
|
}
|
|
|
|
void cdgbr(unsigned mode)
|
|
{
|
|
set_rounding_mode(mode);
|
|
|
|
double out;
|
|
|
|
__asm__ volatile("cdgbr %[r1],%[r2]" : [r1] "=f"(out) : [r2] "d"(i64));
|
|
printf("cegbr: %"PRId64" -> %f\n", i64, out);
|
|
}
|
|
|
|
|
|
int main()
|
|
{
|
|
int mode;
|
|
|
|
/* i32 -> f32 */
|
|
i32 = INT32_MAX;
|
|
for (mode = 0; mode <= 3; ++mode) cefbr(mode);
|
|
printf("\n");
|
|
i32 = INT32_MIN;
|
|
for (mode = 0; mode <= 3; ++mode) cefbr(mode);
|
|
printf("\n");
|
|
|
|
/* i64 -> f32 */
|
|
i64 = INT64_MAX;
|
|
for (mode = 0; mode <= 3; ++mode) cegbr(mode);
|
|
printf("\n");
|
|
i64 = INT64_MIN;
|
|
for (mode = 0; mode <= 3; ++mode) cegbr(mode);
|
|
printf("\n");
|
|
|
|
/* i64 -> f64 */
|
|
i64 = INT64_MAX;
|
|
for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
|
|
printf("\n");
|
|
i64 = INT64_MIN;
|
|
for (mode = 0; mode <= 3; ++mode) cdgbr(mode);
|
|
printf("\n");
|
|
|
|
return 0;
|
|
}
|