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

100 lines
3.6 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(RoundType rt) {
switch (rt) {
case TO_ZERO:
return softfloat_round_minMag;
case TO_NEAREST_EVEN:
return softfloat_round_near_even;
case TO_POSITIVE_INFINITY:
return softfloat_round_max;
case TO_NEGATIVE_INFINITY:
return softfloat_round_min;
default:
unreachable();
}
}
RoundType _float_round_type = 0;
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);
}
}