From: Sam Moore Date: Wed, 9 Apr 2014 17:45:06 +0000 (+0800) Subject: VFPU now using std::bitset instead of just float typedef X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=79d61ba24ac2d29cea6e7f1fee2f83705c5fb4ac VFPU now using std::bitset instead of just float typedef It's still 32 bits. However it might not break if I change it? Can't test it at the moment because the virtual FPU is 32 bits still. --- diff --git a/src/vfpu.cpp b/src/vfpu.cpp index 67f5249..58725f7 100644 --- a/src/vfpu.cpp +++ b/src/vfpu.cpp @@ -12,6 +12,11 @@ #include #include +#include +#include + +using namespace std; + namespace VFPU { @@ -79,45 +84,47 @@ int Halt() return 0; } +float Exec(float opa, float opb, Opcode op) +{ + unsigned a; memcpy(&a, &opa, sizeof(float)); + unsigned b; memcpy(&b, &opb, sizeof(float)); + + unsigned r = (unsigned)(Exec(Register(a), Register(b), op).to_ulong()); + float result; memcpy(&result, &r, sizeof(float)); + return result; +} + /** * Tell the VFPU to execute an instruction, wait for it to finish, return the result - * TODO: Generalise for non 32bit Registers + * TODO: Make this not mix C++ and C so badly? */ -Register Exec(const Register & opa, const Register & opb, Opcode op) +Register Exec(const Register & a, const Register & b, Opcode op) { assert(g_running); - - // Copy floats into 32 bits (casting will alter the representation) - unsigned a; memcpy(&a, &opa, 8); - unsigned b; memcpy(&b, &opb, 8); - - - char buffer[BUFSIZ]; - int len = sprintf(buffer, "%08x\n%08x\n%03x\n",a, b, op); // This is... truly awful... why am I doing this - //fprintf(stderr, "Writing:\n%s", buffer); + + stringstream s; + s << hex << a.to_ullong() << "\n" << b.to_ullong() << "\n" << setw(3) << setfill('0') << op << "\n"; + string str(s.str()); + //fprintf(stderr, "Writing:\n%s\n", str.c_str()); - assert(len == 9+9+4); - assert(write(g_fpu_socket[1], buffer, len) == len); + // So we used C++ streams to make our C string... + assert(write(g_fpu_socket[1], str.c_str(), str.size()) == (int)str.size()); //fprintf(stderr, "Wrote!\n"); - len = read(g_fpu_socket[1], buffer, sizeof(buffer)); - assert(len == 9); - buffer[len] = '\0'; + char buffer[BUFSIZ]; + int len = read(g_fpu_socket[1], buffer, sizeof(buffer)); + //assert(len == 9); + buffer[--len] = '\0'; // Get rid of newline + //fprintf(stderr, "Read!\n"); - - unsigned result = 0x00000000; + Register result(0); for (int i = 0; i < len/2; ++i) { - unsigned byte2; // cos its two bytes - sscanf(buffer+2*i, "%02x", &byte2); - result |= (byte2 << 8*(len/2-i-1)); + unsigned byte; // It is ONE byte (2 nibbles == 2 hex digits) + sscanf(buffer+2*i, "%02x", &byte); + result |= (byte << 8*(len/2-i-1)); } - - //fprintf(stderr, "Buffer: %s\nResult: %08x\n", buffer, result); - - Register r; - memcpy(&r, &result, 8); // Amazing. - return r; + return result; } } diff --git a/src/vfpu.h b/src/vfpu.h index da130a4..c489e89 100644 --- a/src/vfpu.h +++ b/src/vfpu.h @@ -5,6 +5,8 @@ * Implements a terrible and hacky interface to use a virtual FPU to do floating point operations */ +#include + namespace VFPU { extern int Start(); // Starts the VFPU @@ -21,10 +23,10 @@ namespace VFPU -- 111 = unused */ typedef enum {ADD=0x000, SUB=0x001, MULT=0x010, DIV=0x011, SQRT=0x100} Opcode; - typedef float Register; + typedef std::bitset<32> Register; - extern Register Exec(const Register & a, const Register & b, Opcode op); - + extern Register Exec(const Register & a, const Register & b, Opcode op); // operate with registers + extern float Exec(float a, float b, Opcode op); //converts floats into registers and back } #endif //_VFPU_H