X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Fvfpu.h;h=cb7fe50592b18f1d4f9da5beb59c39dcdfeae1b1;hp=edf471ab9ac0b4ce39c501a76bf618fa4c1d1a58;hb=5456793e2aad4235c3db2ca75532c868aaa7c518;hpb=c0f947a6ce10a329eec81e4df820ac52f7ab371f diff --git a/src/vfpu.h b/src/vfpu.h index edf471a..cb7fe50 100644 --- a/src/vfpu.h +++ b/src/vfpu.h @@ -1,33 +1,95 @@ -#ifndef _VFPU_H -#define _VFPU_H - /** - * Implements a terrible and hacky interface to use a virtual FPU to do floating point operations + * @file vfpu.h + * @brief Implements a terrible and hacky interface to use a virtual FPU to do floating point operations + * Updated with even more terror! Whatever floats the boat! */ -#include +#ifndef _VFPU_H +#define _VFPU_H +#include namespace VFPU { - extern int Start(); // Starts the VFPU + extern int Start(const char * vcd_output = NULL); // Starts the VFPU extern int Halt(); // Halts the VFPU - -/** - -- 000 = add, - -- 001 = substract, - -- 010 = multiply, - -- 011 = divide, - -- 100 = square root - -- 101 = unused - -- 110 = unused - -- 111 = unused - */ - typedef enum {ADD=0x000, SUB=0x001, MULT=0x010, DIV=0x011, SQRT=0x100} Opcode; - typedef enum {EVEN=0x00, ZERO=0x01, UP=0x10, DOWN=0x11} Rmode; + typedef enum {ADD=0x0, SUB=0x1, MULT=0x2, DIV=0x3, SQRT=0x4} Opcode; + typedef enum {EVEN=0x0, ZERO=0x1, UP=0x2, DOWN=0x3} Rmode; // Rounding mode; to even, towards zero, always up, always down typedef std::bitset<32> Register; - extern Register Exec(const Register & a, const Register & b, Opcode op, Rmode rmode = EVEN); // operate with registers extern float Exec(float a, float b, Opcode op, Rmode rmode = EVEN); //converts floats into registers and back + + /** + * Wrapper class for floats where operations are done on the VFPU + */ + class VFloat + { + public: + VFloat(float f = 0) : m_value(f) + { + static bool init = false; + if (!init) + { + init = true; + VFPU::Start("flops.vcd"); + } + } + VFloat(const VFloat & cpy) : m_value(cpy.m_value) {} + virtual ~VFloat() + { + + } + + VFloat & operator+=(const VFloat & op) + { + m_value = Exec(m_value, op.m_value, ADD); + return *this; + } + VFloat & operator-=(const VFloat & op) + { + m_value = Exec(m_value, op.m_value, SUB); + return *this; + } + VFloat & operator*=(const VFloat & op) + { + m_value = Exec(m_value, op.m_value, MULT); + return *this; + } + VFloat & operator/=(const VFloat & op) + { + m_value = Exec(m_value, op.m_value, DIV); + return *this; + } + + VFloat operator+(const VFloat & op) const {VFloat f(*this); f+=op; return f;} + VFloat operator-(const VFloat & op) const {VFloat f(*this); f-=op; return f;} + VFloat operator*(const VFloat & op) const {VFloat f(*this); f*=op; return f;} + VFloat operator/(const VFloat & op) const {VFloat f(*this); f/=op; return f;} + + bool operator==(const VFloat & op) const + { + VFloat f(op); + f -= *this; + return (f.m_value == 0); + } + bool operator!=(const VFloat & op) const {return !this->operator==(op);} + bool operator<(const VFloat & op) const + { + VFloat f(op); + f -= *this; + return (f.m_value > 0); + } + bool operator<=(const VFloat & op) const + { + VFloat f(op); + f -= *this; + return (f.m_value >= 0); + } + bool operator>(const VFloat & op) const {return !this->operator<=(op);} + bool operator>=(const VFloat & op) const {return !this->operator<(op);} + + float m_value; + + }; } #endif //_VFPU_H