1
0
Fork 0
ca-tools/float/softfloat/main.c
2025-07-17 19:45:02 +03:00

97 lines
3.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#endif
#include "SoftFloat/source/include/softfloat.h"
#include "internals.h"
#define _FLOAT_INCLUDE_F16_H
#define _FLOAT_INCLUDE_F32_H
extern void f16_print(float16_t v);
extern void f32_print(float32_t v);
#define CREATE_VAR(name) __##name = {name}
#define ADD_PREFIX(name) __##name
#define OPERATION_DISPATCH(OP1, OP2, ...) \
case OP1: { \
if (fmt == HALF) { \
float16_t REPEAT(CREATE_VAR, __VA_ARGS__); \
f16_print(f16_##OP2(REPEAT(ADD_PREFIX, __VA_ARGS__))); \
} else { \
float32_t REPEAT(CREATE_VAR, __VA_ARGS__); \
f32_print(f32_##OP2(REPEAT(ADD_PREFIX, __VA_ARGS__))); \
} \
} break
NORETURN void die() {
fprintf(stderr,
"Usage: \n"
"<fmt> <округление> <число>\n"
"<fmt> <округление> <операция2> <число1> <число2>\n"
"<fmt> <округление> <операция3> <число1> <число2> <число3>\n");
exit(1);
}
int skkv_to_sf(int rt) {
switch (rt) {
case 0:
return softfloat_round_minMag;
case 1:
return softfloat_round_near_even;
case 2:
return softfloat_round_max;
case 3:
return softfloat_round_min;
default:
unreachable();
}
}
float16_t f16_mad(float16_t a, float16_t b, float16_t c) { return f16_add(f16_mul(a, b), c); }
float32_t f32_mad(float32_t a, float32_t b, float32_t c) { return f32_add(f32_mul(a, b), c); }
THREAD_LOCAL uint_fast8_t softfloat_detectTininess = 0;
THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags = 0;
THREAD_LOCAL uint_fast8_t softfloat_roundingMode;
int main(int argc, char **argv) {
#ifdef WIN32
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
#endif
u32 a = 0, b = 0, c = 0;
Operation operation = PRN;
switch (argc) {
case 4:
sscanf(argv[3], "%X", &a);
break;
case 7:
sscanf(argv[6], "%X", &c);
case 6:
sscanf(argv[3], "%c", (char *) &operation);
sscanf(argv[4], "%X", &a);
sscanf(argv[5], "%X", &b);
break;
default:
die();
}
Format fmt = *argv[1];
softfloat_roundingMode = skkv_to_sf(*argv[2] - '0');
switch (operation) {
OPERATION_DISPATCH(PRN, nop, a);
OPERATION_DISPATCH(ADD, add, a, b);
OPERATION_DISPATCH(SUB, sub, a, b);
OPERATION_DISPATCH(DIV, div, a, b);
OPERATION_DISPATCH(MUL, mul, a, b);
OPERATION_DISPATCH(FMA, mulAdd, a, b, c);
OPERATION_DISPATCH(MAD, mad, a, b, c);
}
}