diff options
author | rsc <devnull@localhost> | 2004-04-19 19:29:25 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-04-19 19:29:25 +0000 |
commit | a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 (patch) | |
tree | 59a0e921597e5aa53e83d487c16727a7bf01547a /src/libmach/fpformat.c | |
parent | 0e3cc9f456ea49919459bf1164d0c8309a6134fa (diff) | |
download | plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.gz plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.tar.bz2 plan9port-a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46.zip |
libmach
Diffstat (limited to 'src/libmach/fpformat.c')
-rw-r--r-- | src/libmach/fpformat.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/libmach/fpformat.c b/src/libmach/fpformat.c new file mode 100644 index 00000000..a94a096a --- /dev/null +++ b/src/libmach/fpformat.c @@ -0,0 +1,65 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <mach.h> + +/* + * Format floating point registers + * + * Register codes in format field: + * 'X' - print as 32-bit hexadecimal value + * 'F' - 64-bit double register when modif == 'F'; else 32-bit single reg + * 'f' - 32-bit ieee float + * '8' - big endian 80-bit ieee extended float + * '3' - little endian 80-bit ieee extended float with hole in bytes 8&9 + */ +int +fpformat(Map *map, Regdesc *rp, char *buf, uint n, uint modif) +{ + char reg[12]; + u32int r; + + switch(rp->format) + { + case 'X': + if (get4(map, rp->offset, &r) < 0) + return -1; + snprint(buf, n, "%lux", r); + break; + case 'F': /* first reg of double reg pair */ + if (modif == 'F') + if ((rp->format=='F') || (((rp+1)->flags&RFLT) && (rp+1)->format == 'f')) { + if (get1(map, rp->offset, (uchar *)reg, 8) < 0) + return -1; + mach->ftoa64(buf, n, reg); + if (rp->format == 'F') + return 1; + return 2; + } + /* treat it like 'f' */ + if (get1(map, rp->offset, (uchar *)reg, 4) < 0) + return -1; + mach->ftoa32(buf, n, reg); + break; + case 'f': /* 32 bit float */ + if (get1(map, rp->offset, (uchar *)reg, 4) < 0) + return -1; + mach->ftoa32(buf, n, reg); + break; + case '3': /* little endian ieee 80 with hole in bytes 8&9 */ + if (get1(map, rp->offset, (uchar *)reg, 10) < 0) + return -1; + memmove(reg+10, reg+8, 2); /* open hole */ + memset(reg+8, 0, 2); /* fill it */ + leieeeftoa80(buf, n, reg); + break; + case '8': /* big-endian ieee 80 */ + if (get1(map, rp->offset, (uchar *)reg, 10) < 0) + return -1; + beieeeftoa80(buf, n, reg); + break; + default: /* unknown */ + break; + } + return 1; +} |