8000 :sparkles: Add FMA support · srcarroll/flexfloat@81f0ecc · GitHub
[go: up one dir, main page]

Skip to content

Commit 81f0ecc

Browse files
author
Stefan Mach
committed
✨ Add FMA support
1 parent 28be2d4 commit 81f0ecc

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

include/flexfloat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ void ff_sub(flexfloat_t *dest, const flexfloat_t *a, const flexfloat_t *b);
197197
void ff_mul(flexfloat_t *dest, const flexfloat_t *a, const flexfloat_t *b);
198198
void ff_div(flexfloat_t *dest, const flexfloat_t *a, const flexfloat_t *b);
199199
void ff_acc(flexfloat_t *dest, const flexfloat_t *a);
200+
void ff_fma(flexfloat_t *dest, const flexfloat_t *a, const flexfloat_t *b, const flexfloat_t *c);
200201

201202

202203
// Relational operators
@@ -232,6 +233,7 @@ typedef struct {
232233
uint64_t sub;
233234
uint64_t mul;
234235
uint64_t div;
236+
uint64_t fma;
235237
uint64_t cmp;
236238
} OpStats;
237239

include/flexfloat.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ struct OpsStats {
3737
uint64_t sub;
3838
uint64_t mul;
3939
uint64_t div;
40+
uint64_t fma;
4041
uint64_t cmp;
4142

42-
OpsStats(): minus(0), add(0), sub(0), mul(0), div(0), cmp(0) { }
43+
OpsStats(): minus(0), add(0), sub(0), mul(0), div(0), fma(0), cmp(0) { }
4344
};
4445

4546
struct CastingStats {
@@ -130,6 +131,7 @@ static inline void flexfloat_print_stats() {
130131
std::cout << std::string(PADDING, ' ') << "SUB \t" << stat.second.sub << std::endl;
131132
std::cout << std::string(PADDING, ' ') << "MUL \t" << stat.second.mul << std::endl;
132133
std::cout << std::string(PADDING, ' ') << "DIV \t" << stat.second.div << std::endl;
134+
std::cout << std::string(PADDING, ' ') << "FMA \t" << stat.second.fma << std::endl;
133135
std::cout << std::string(PADDING, ' ') << "MINUS \t" << stat.second.minus << std::endl;
134136
std::cout << std::string(PADDING, ' ') << "CMP \t" << stat.second.cmp << std::endl;
135137
}
@@ -142,6 +144,7 @@ static inline void flexfloat_print_stats() {
142144
std::cout << std::string(PADDING, ' ') << "SUB \t" << stat.second.sub << std::endl;
143145
std::cout << std::string(PADDING, ' ') << "MUL \t" << stat.second.mul << std::endl;
144146
std::cout << std::string(PADDING, ' ') << "DIV \t" << stat.second.div << std::endl;
147+
std::cout << std::string(PADDING, ' ') << "FMA \t" << stat.second.fma << std::endl;
145148
std::cout << std::string(PADDING, ' ') << "MINUS \t" << stat.second.minus << std::endl;
146149
std::cout << std::string(PADDING, ' ') << "CMP \t" << stat.second.cmp << std::endl;
147150
}
@@ -507,4 +510,4 @@ INLINE uint64_t reinterpret_as_double_bits(fp_t v) noexcept
507510
INLINE fp_t reinterpret_double_bits_as(uint64_t v) noexcept
508511
{
509512
return fp_t(*((double *)(&(v))));
510-
}
513+
}

src/flexfloat.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
*/
1717

1818
#include "flexfloat.h"
19-
#include "math.h"
19+
// To avoid manually discerning backend-type for calls from math.h
20+
#include <tgmath.h>
2021

2122
#ifdef FLEXFLOAT_ROUNDING
2223
#include <fenv.h>
@@ -472,6 +473,21 @@ INLINE void ff_acc(flexfloat_t *dest, const flexfloat_t *a) {
472473
#endif
473474
}
474475

476+
INLINE void ff_fma(flexfloat_t *dest, const flexfloat_t *a, const flexfloat_t *b, const flexfloat_t *c) {
477+
assert((dest->desc.exp_bits == a->desc.exp_bits) && (dest->desc.frac_bits == a->desc.frac_bits) &&
478+
(a->desc.exp_bits == b->desc.exp_bits) && (a->desc.frac_bits == b->desc.frac_bits) &&
479+
(b->desc.exp_bits == c->desc.exp_bits) && (b->desc.frac_bits == c->desc.frac_bits));
480+
dest->value = fma(a->value, b->value, c->value);
481+
#ifdef FLEXFLOAT_TRACKING
482+
dest->exact_value = fma(a->exact_value, b->exact_value, c->exact_value);
483+
if(dest->tracking_fn) (dest->tracking_fn)(dest, dest->tracking_arg);
484+
#endif
485+
flexfloat_sanitize(dest);
486+
#ifdef FLEXFLOAT_STATS
487+
if(StatsEnabled) getOpStats(dest->desc)->fma += 1;
488+
#endif
489+
}
490+
475491

476492
// Relational operators
477493

@@ -615,6 +631,7 @@ void ff_print_stats() {
615631
printf(" SUB \t%lu\n", stats->sub);
616632
printf(" MUL \t%lu\n", stats->mul);
617633
printf(" DIV \t%lu\n", stats->div);
634+
printf(" FMA \t%lu\n", stats->fma);
618635
printf(" CMP \t%lu\n", stats->cmp);
619636
}
620637
}

0 commit comments

Comments
 (0)
0