Skip to content

Commit e3895cd

Browse files
authored
Add support for bf16 in rax2 and pf ##print
1 parent 86fc88d commit e3895cd

File tree

6 files changed

+131
-3
lines changed

6 files changed

+131
-3
lines changed

libr/core/cmd_print.inc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ static RCoreHelpMessage help_detail_pf = {
436436
" ", "e", "temporally swap endian",
437437
" ", "E", "resolve enum name (see t?)",
438438
" ", "f", "float value (4 bytes)",
439+
" ", "g", "BF16 value (2 bytes)",
439440
" ", "F", "double value (8 bytes)",
440441
" ", "G", "long double value (16 bytes (10 with padding))",
441442
" ", "i", "signed integer value (4 bytes) (see 'd' and 'x')",

libr/include/r_util/r_num.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ R_API size_t r_num_bit_clz64(ut64 val);
111111
R_API size_t r_num_bit_ctz32(ut32 val);
112112
R_API size_t r_num_bit_ctz64(ut64 val);
113113
R_API double r_num_get_double(RNum *num, const char *str);
114+
R_API ut16 r_num_float_to_bf16(float f);
115+
R_API float r_num_bf16_to_float(ut16 b);
114116

115117
static inline st64 r_num_abs(st64 num) {
116118
return num < 0 ? -num : num;

libr/main/rax2.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,28 @@ static bool format_output(RNum *num, char mode, const char *s, RaxMode m, RaxAct
121121
case 'f':
122122
printf ("%.01lf\n", num->fvalue);
123123
break;
124-
case 'l':
124+
case 'l':
125125
{
126126
R_STATIC_ASSERT (sizeof (float) == 4);
127127
float f = (float)num->fvalue;
128128
ut32 *p = (ut32 *)&f;
129129
printf ("Fx%08x\n", *p);
130130
}
131131
break;
132+
case 'g':
133+
{
134+
R_STATIC_ASSERT (sizeof (float) == 4);
135+
float f = (float)num->fvalue;
136+
ut16 bf16 = r_num_float_to_bf16 (f);
137+
printf ("Gx%04x\n", bf16);
138+
}
139+
break;
140+
case 'G':
141+
{
142+
float f = r_num_bf16_to_float ((ut16)n);
143+
printf ("%.9g\n", f);
144+
}
145+
break;
132146
case 'O': printf ("0%" PFMT64o "\n", n); break;
133147
case 'B':
134148
if (n) {
@@ -147,7 +161,7 @@ static bool format_output(RNum *num, char mode, const char *s, RaxMode m, RaxAct
147161
}
148162
break;
149163
default:
150-
R_LOG_ERROR ("Unknown output mode %d", m.omode);
164+
R_LOG_ERROR ("Unknown output mode %c", m.omode);
151165
return false;
152166
}
153167
return true;
@@ -169,6 +183,8 @@ static int help(void) {
169183
" ternary -> int ; rax2 1010dt\n"
170184
" float -> hex ; rax2 3.33f\n"
171185
" hex -> float ; rax2 Fx40551ed8\n"
186+
" BF16 -> hex ; rax2 1.5g\n"
187+
" hex -> BF16 ; rax2 Gx3f80\n"
172188
" oct -> hex ; rax2 35o\n"
173189
" hex -> oct ; rax2 Ox12 (O is a letter)\n"
174190
" bin -> hex ; rax2 1100011b\n"
@@ -588,6 +604,7 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM
588604
memcpy (&f, &n, sizeof (f));
589605
memcpy (&d, &n, sizeof (d));
590606
printf ("float %ff\n", f);
607+
printf ("bf16 Gx%04x\n", r_num_float_to_bf16 (f));
591608
printf ("double %lf\n", d);
592609
printf ("binary 0b%s\n", out);
593610

@@ -647,6 +664,7 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM
647664

648665
pj_ks (*pj, "fvalue", r_strf ("%.1lf", num->fvalue));
649666
pj_ks (*pj, "float", r_strf ("%ff", f));
667+
pj_ks (*pj, "bf16", r_strf ("Gx%04x", r_num_float_to_bf16 (f)));
650668
pj_ks (*pj, "double", r_strf ("%lf", d));
651669
pj_ks (*pj, "binary", r_strf ("0b%s", out));
652670
char b36str[16];
@@ -756,6 +774,9 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM
756774
} else if (r_str_startswith (str, "Bx")) {
757775
out_mode = 'B';
758776
*str = '0';
777+
} else if (r_str_startswith (str, "Gx")) {
778+
out_mode = 'G';
779+
*str = '0';
759780
} else if (r_str_startswith (str, "Tx")) {
760781
out_mode = 'T';
761782
*str = '0';
@@ -768,6 +789,8 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM
768789
// TODO: Move print into format_output
769790
} else if (r_str_endswith (str, "f")) {
770791
out_mode = 'l';
792+
} else if (r_str_endswith (str, "g")) {
793+
out_mode = 'g';
771794
} else if (r_str_endswith (str, "dt")) {
772795
out_mode = 'I';
773796
str[strlen (str) - 2] = 't';

libr/util/format2.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <r_cons.h>
44
#include <r_util.h>
55
#include <r_util/r_print.h>
6+
#include <r_util/r_num.h>
67
#include <r_reg.h>
78

89
// W T F :D
@@ -1038,6 +1039,63 @@ static void r_print_format_float(RPrintFormat *pf, const char *setval, ut64 seek
10381039
}
10391040
}
10401041

1042+
static void r_print_format_bf16(RPrintFormat *pf, const char *setval, ut64 seeki, ut8 *buf, int i, int size) {
1043+
RPrint *p = pf->p;
1044+
const int endian = pf->endian;
1045+
const int mode = pf->mode;
1046+
ut64 addr = 0;
1047+
int elem = -1;
1048+
if (size >= ARRAYINDEX_COEF) {
1049+
elem = size / ARRAYINDEX_COEF - 1;
1050+
size %= ARRAYINDEX_COEF;
1051+
}
1052+
ut16 val_u16 = updateAddr (buf + i, 2, endian, &addr, NULL);
1053+
float val_f = r_num_bf16_to_float(val_u16);
1054+
if (MUSTSET) {
1055+
r_print_printf (p, "wv2 %s @ 0x%08" PFMT64x "\n", setval,
1056+
seeki + ((elem >= 0)? elem * 2: 0));
1057+
} else if ((mode & R_PRINT_DOT) || MUSTSEESTRUCT) {
1058+
r_print_printf (p, "%.9g", val_f);
1059+
} else {
1060+
if (MUSTSEE) {
1061+
if (!SEEVALUE && !ISQUIET) {
1062+
r_print_printf (p, "0x%08" PFMT64x " = ",
1063+
seeki + ((elem >= 0)? elem * 2: 0));
1064+
}
1065+
}
1066+
if (size == -1) {
1067+
r_print_printf (p, "%.9g", val_f);
1068+
} else {
1069+
if (!SEEVALUE) {
1070+
r_print_printf (p, "[ ");
1071+
}
1072+
while (size--) {
1073+
val_u16 = updateAddr (buf + i, 2, endian, &addr, NULL);
1074+
val_f = r_num_bf16_to_float (val_u16);
1075+
if (elem == -1 || elem == 0) {
1076+
r_print_printf (p, "%.9g", val_f);
1077+
if (elem == 0) {
1078+
elem = -2;
1079+
}
1080+
}
1081+
if (size != 0 && elem == -1) {
1082+
r_print_printf (p, ", ");
1083+
}
1084+
if (elem > -1) {
1085+
elem--;
1086+
}
1087+
i += 2;
1088+
}
1089+
if (!SEEVALUE) {
1090+
r_print_printf (p, " ]");
1091+
}
1092+
}
1093+
}
1094+
if (!MUSTSEESTRUCT) {
1095+
// r_print_printf (p, "\n");
1096+
}
1097+
}
1098+
10411099
static void r_print_format_double(RPrintFormat *pf, const char *setval, ut64 seeki, ut8 *buf, int i, int size) {
10421100
const int mode = pf->mode;
10431101
const RPrint *p = pf->p;
@@ -2537,6 +2595,10 @@ R_API int r_print_format_internal(RPrint *p, RPrintFormat *pf, ut64 seek, const
25372595
r_print_format_float (pf, setval, seeki, buf, i, size);
25382596
i += (size == -1)? 4: 4 * size;
25392597
break;
2598+
case 'g':
2599+
r_print_format_bf16 (pf, setval, seeki, buf, i, size);
2600+
i += (size == -1)? 2: 2 * size;
2601+
break;
25402602
case 'F':
25412603
r_print_format_double (pf, setval, seeki, buf, i, size);
25422604
i += (size == -1)? sizeof (double): sizeof (double) * size;

libr/util/unum.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,30 @@ R_API double r_num_get_double(RNum *num, const char *str) {
500500
return d;
501501
}
502502

503+
R_API ut16 r_num_float_to_bf16(float f) {
504+
ut32 u;
505+
memcpy (&u, &f, sizeof u);
506+
// handle inf/nan
507+
if ((u & 0x7F800000u) == 0x7F800000u) {
508+
if (u & 0x007FFFFFu) { // NaN
509+
// translate to qNaN
510+
return (ut16)((u >> 16) | 0x0040u);
511+
}
512+
return (ut16)(u >> 16); // Inf
513+
}
514+
// Round-to-nearest-even sobre els 16 bits baixos
515+
ut32 lsb = (u >> 16) & 1u;
516+
ut32 rounding_bias = 0x7FFFu + lsb;
517+
return (ut16)((u + rounding_bias) >> 16);
518+
}
519+
520+
R_API float r_num_bf16_to_float(ut16 b) {
521+
ut32 u = ((ut32)b) << 16;
522+
float f;
523+
memcpy (&f, &u, sizeof f);
524+
return f;
525+
}
526+
503527
R_API int r_num_to_bits(char *out, ut64 num) {
504528
int size = 64, i;
505529

test/db/tools/rax2

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,22 @@ EXPECT=<<EOF
203203
EOF
204204
RUN
205205

206+
NAME=rax2 1.5g
207+
FILE=-
208+
CMDS=!rax2 1.5g
209+
EXPECT=<<EOF
210+
Gx3fc0
211+
EOF
212+
RUN
213+
214+
NAME=rax2 Gx3fc0
215+
FILE=-
216+
CMDS=!rax2 Gx3fc0
217+
EXPECT=<<EOF
218+
1.5
219+
EOF
220+
RUN
221+
206222
NAME=rax2 35o
207223
FILE=-
208224
CMDS=!rax2 35o
@@ -597,7 +613,7 @@ NAME=rax2 -j 0x1234
597613
FILE=-
598614
CMDS=!rax2 -j 0x1234
599615
EXPECT=<<EOF
600-
{"int32":"4660","uint32":"4660","int64":"4660","uint64":"4660","hex":"0x00001234","octal":"011064","unit":"4.6K","segment":"0000:0234","fvalue":"4660.0","float":"0.000000f","double":"0.000000","binary":"0b0001001000110100","base36":"0_3lg","ternary":"0t20101121"}
616+
{"int32":"4660","uint32":"4660","int64":"4660","uint64":"4660","hex":"0x00001234","octal":"011064","unit":"4.6K","segment":"0000:0234","fvalue":"4660.0","float":"0.000000f","bf16":"Gx0000","double":"0.000000","binary":"0b0001001000110100","base36":"0_3lg","ternary":"0t20101121"}
601617
EOF
602618
RUN
603619

0 commit comments

Comments
 (0)