Added some reading material, floating point support.

git-svn-id: http://www.cdkersey.com/harp/harptool@9 0246edb2-e076-4747-b392-db732a341fa2
This commit is contained in:
chad
2011-07-23 11:16:39 +00:00
parent e2d99e8841
commit 269fe72f2d
5 changed files with 209 additions and 10 deletions

123
src/include/harpfloat.h Normal file
View File

@@ -0,0 +1,123 @@
/*******************************************************************************
HARPtools by Chad D. Kersey, Summer 2011
*******************************************************************************/
#include <math.h>
#include <stdlib.h>
#include "types.h"
#ifdef DEBUG
#include <iostream>
#define DEBUGMSG(x) do { \
std::cout << __FILE__ << ':' <<__LINE__ << ": " << x << '\n'; \
} while(0)
#else
#define DEBUGMSG(x) do { } while(0)
#endif
namespace Harp {
// This class serves to handle the strange-precision floating point that can
// crop up in HARP.
class Float {
public:
Float(Word_u bin, Size n): sz(n) {
DEBUGMSG("Float(0x" << std::hex << bin << ", " << std::dec << n << ')');
bool sign(bin >> (n*8 - 1));
Size expSz;
if (n < 4) {
expSz = 5;
} else if (n < 8) {
expSz = 8;
} else {
expSz = 11;
}
Size sigSz = n*8 - expSz - 1;
DEBUGMSG(" exp: " << std::dec << expSz <<
" bits, sig: " << std::dec << sigSz << " bits.");
int exp = (bin >> sigSz) & ((1<<expSz) - 1);
Word_u sig = bin & ((1llu<<sigSz) - 1);
DEBUGMSG(" sig=" << std::dec << sig << " exp=" << exp);
if (exp == 0) {
// Subnormal
d = sig / pow(2, ((1<<(expSz-1))-2)) / pow(2, sigSz);
DEBUGMSG(" Denorm.");
} else if (exp == ((1<<expSz) - 1)) {
// Infinity
d = HUGE_VAL;
DEBUGMSG(" Inf.");
} else {
// Normalized, implied 1.
exp -= (1<<(expSz - 1)) - 1;
d = pow(2.0, exp - int(sigSz)) * double((1ll << sigSz) + sig);
DEBUGMSG(" Norm, exp=" << exp);
}
if (sign) d = -d;
DEBUGMSG("Set to " << d);
}
Float(double d, Size n): sz(n), d(d) { DEBUGMSG("Float(double, size)"); }
operator Word_u() {
DEBUGMSG("Float -> Word_u: " << d);
Size expSz;
if (sz < 4) {
expSz = 5;
} else if (sz < 8) {
expSz = 8;
} else {
expSz = 11;
}
Size sigSz = 8*sz - expSz - 1;
bool sign(d < 0);
bool inf(isinf(d)), zero(d == 0.0);
int exp;
if (!inf && !zero) exp = floor(log2(fabs(d)));
Word_u rval;
if (inf) {
// Infinity
DEBUGMSG(" Inf.");
rval = ((1llu<<expSz)-1llu)<<sigSz;
} else if (!zero && abs(exp) < (1<<(expSz-1)) - 1) {
// Normalized with implied 1.
Word_u sig = (fabs(d) * pow(2.0, -exp) - 1.0) * pow(2.0, sigSz);
DEBUGMSG(" Norm, exp=" << exp << ", sig=" << sig);
rval = ((((exp + ((1llu<<(expSz-1)) - 1llu))
&((1llu<<expSz)-1llu)))<<sigSz) | sig;
} else if (!zero && exp > -(1<<(expSz-1)) - sigSz) {
// Subnormal number.
Word_u sig = round(fabs(d)*pow(2.0,((1<<(expSz-1))-2))*pow(2.0, sigSz));
DEBUGMSG(" Denorm, exp=" << exp << ", sig=" << sig);
rval = sig;
} else {
// Zero.
rval = 0;
}
if (sign) rval |= 1llu<<(sz*8 - 1);
DEBUGMSG(" Returning 0x" << std::hex << rval);
return rval;
}
operator double() { DEBUGMSG("Float->double " << d); return d; }
private:
double d;
Size sz;
};
};

View File

@@ -29,7 +29,8 @@ namespace Harp {
ANDI, ORI, XORI, ADDI, SUBI, MULI, DIVI, MODI, SHLI, SHRI,
JALI, JALR, JMPI, JMPR, CLONE, JALIS, JALRS,
JMPRT, LD, ST, LDI, RTOP, ANDP, ORP, XORP, NOTP, ISNEG,
ISZERO, HALT, TRAP, JMPRU, SKEP, RETI, TLBRM };
ISZERO, HALT, TRAP, JMPRU, SKEP, RETI, TLBRM,
ITOF, FTOI, FADD, FSUB, FMUL, FDIV, FNEG };
enum ArgClass {
AC_NONE, AC_2REG, AC_2IMM, AC_3REG, AC_3PREG, AC_3IMM, AC_3REGSRC,
AC_1IMM, AC_1REG, AC_3IMMSRC, AC_PREG_REG, AC_2PREG

View File

@@ -12,8 +12,8 @@ namespace Harp {
typedef uint64_t Word_u;
typedef int64_t Word_s;
typedef Word Addr;
typedef Word Size;
typedef Word_u Addr;
typedef Word_u Size;
typedef unsigned RegNum;
typedef unsigned ThdNum;