mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
tests/tcg: add float_convd test
This is a simple transliteration of the float_convs test but this time working with doubles. I'm used it to test the handling of vector registers in gdbstub but wasn't able to find a non-ugly way to automate it. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220419091020.3008144-23-alex.bennee@linaro.org>
This commit is contained in:
parent
9730a27ef4
commit
2931014c3d
5 changed files with 4058 additions and 0 deletions
106
tests/tcg/multiarch/float_convd.c
Normal file
106
tests/tcg/multiarch/float_convd.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Floating Point Convert Doubles to Various
|
||||
*
|
||||
* Copyright (c) 2019 Linaro
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <fenv.h>
|
||||
|
||||
|
||||
#include "float_helpers.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
typedef struct {
|
||||
int flag;
|
||||
char *desc;
|
||||
} float_mapping;
|
||||
|
||||
float_mapping round_flags[] = {
|
||||
{ FE_TONEAREST, "to nearest" },
|
||||
#ifdef FE_UPWARD
|
||||
{ FE_UPWARD, "upwards" },
|
||||
#endif
|
||||
#ifdef FE_DOWNWARD
|
||||
{ FE_DOWNWARD, "downwards" },
|
||||
#endif
|
||||
#ifdef FE_TOWARDZERO
|
||||
{ FE_TOWARDZERO, "to zero" }
|
||||
#endif
|
||||
};
|
||||
|
||||
static void print_input(double input)
|
||||
{
|
||||
char *in_fmt = fmt_f64(input);
|
||||
printf("from double: %s\n", in_fmt);
|
||||
free(in_fmt);
|
||||
}
|
||||
|
||||
static void convert_double_to_single(double input)
|
||||
{
|
||||
float output;
|
||||
char *out_fmt, *flag_fmt;
|
||||
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
|
||||
output = input;
|
||||
|
||||
flag_fmt = fmt_flags();
|
||||
out_fmt = fmt_f32(output);
|
||||
printf(" to single: %s (%s)\n", out_fmt, flag_fmt);
|
||||
free(out_fmt);
|
||||
free(flag_fmt);
|
||||
}
|
||||
|
||||
#define xstr(a) str(a)
|
||||
#define str(a) #a
|
||||
|
||||
#define CONVERT_DOUBLE_TO_INT(TYPE, FMT) \
|
||||
static void convert_double_to_ ## TYPE(double input) \
|
||||
{ \
|
||||
TYPE ## _t output; \
|
||||
char *flag_fmt; \
|
||||
const char to[] = "to " xstr(TYPE); \
|
||||
feclearexcept(FE_ALL_EXCEPT); \
|
||||
output = input; \
|
||||
flag_fmt = fmt_flags(); \
|
||||
printf("%11s: %" FMT " (%s)\n", to, output, flag_fmt); \
|
||||
free(flag_fmt); \
|
||||
}
|
||||
|
||||
CONVERT_DOUBLE_TO_INT( int32, PRId32)
|
||||
CONVERT_DOUBLE_TO_INT(uint32, PRId32)
|
||||
CONVERT_DOUBLE_TO_INT( int64, PRId64)
|
||||
CONVERT_DOUBLE_TO_INT(uint64, PRId64)
|
||||
|
||||
int main(int argc, char *argv[argc])
|
||||
{
|
||||
int i, j, nums;
|
||||
|
||||
nums = get_num_f64();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(round_flags); ++i) {
|
||||
if (fesetround(round_flags[i].flag) != 0) {
|
||||
printf("### Rounding %s skipped\n", round_flags[i].desc);
|
||||
continue;
|
||||
}
|
||||
printf("### Rounding %s\n", round_flags[i].desc);
|
||||
for (j = 0; j < nums; j++) {
|
||||
double input = get_f64(j);
|
||||
print_input(input);
|
||||
convert_double_to_single(input);
|
||||
convert_double_to_int32(input);
|
||||
convert_double_to_int64(input);
|
||||
convert_double_to_uint32(input);
|
||||
convert_double_to_uint64(input);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue