#include "config/full_system.hh"
#include "cpu/static_inst.hh"
#include "sim/serialize.hh"
+#include "base/bitfield.hh"
using namespace MipsISA;
+using namespace std;
+
+uint64_t
+MipsISA::convert_and_round(uint32_t fp_val, ConvertType cvt_type, int rnd_mode)
+{
+
+ uint64_t ret_val = 0;
+
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ uint64_t single_sign = fp_val & 0x80000000;
+
+ uint64_t single_exp = (fp_val & 0x7F800000) >> 22;
+ single_exp -= 127;
+
+ uint64_t single_mantissa = fp_val & 0x007FFFFF;
+
+ uint64_t double_exp = single_exp + 1023;
+ double_exp = double_exp << 51;
+
+ uint64_t double_val = single_sign << 63 | double_exp | single_mantissa;
+
+ return double_val;
+
+ default:
+ panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+ return ret_val;
+ }
+}
uint64_t
MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode)
{
+
uint64_t ret_val = 0;
switch (cvt_type)
{
case SINGLE_TO_DOUBLE:
+ uint64_t single_sign = fp_val & 0x80000000;
- break;
+ uint64_t single_exp = (fp_val & 0x7F800000) >> 22;
+ single_exp -= 127;
+
+ uint64_t single_mantissa = fp_val & 0x007FFFFF;
+
+ uint64_t double_exp = single_exp + 1023;
+ double_exp = double_exp << 51;
+
+ uint64_t double_val = single_sign << 63 | double_exp | single_mantissa;
+
+ return double_val;
default:
panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+ return ret_val;
}
+}
+
+
+uint64_t
+MipsISA::convert_and_round(float fp_val, ConvertType cvt_type, int rnd_mode)
+{
+ void * ptr = &fp_val;
+ uint32_t fp_bits = * (uint32_t *) ptr;
+
+ cout << "Converting " << fp_val << " (" << hex << fp_bits << ") " << endl;
- return ret_val;
+ uint64_t ret_val = 0;
+
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ double double_val = fp_val;
+ void *double_ptr = &double_val;
+ uint64_t dp_bits = *(uint64_t *) double_ptr ;
+ cout << "To " << double_val << " (" << hex << dp_bits << ") " << endl;
+ double_ptr = &dp_bits;
+ cout << "Testing: " << *(double *) double_ptr << endl;
+ return dp_bits;
+
+ default:
+ panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type);
+ return ret_val;
+ }
}
void
};
- typedef double FloatReg;
+ typedef float FloatReg;
+
+ typedef uint32_t FloatReg32;
+ typedef uint64_t FloatReg64;
typedef uint64_t FloatRegBits;
+// const uint64_t hi_mask64 = 0xFFFFFFFF00000000;
+//const uint64_t lo_mask64 = 0x00000000FFFFFFFF;
+
const int SingleWidth = 32;
- const int SingleBytes = SingleWidth / 4;
+ const int SingleBytes = 4;
const int DoubleWidth = 64;
- const int DoubleBytes = DoubleWidth / 4;
+ const int DoubleBytes = 8;
const int QuadWidth = 128;
const int QuadBytes = QuadWidth / 4;
- const int FloatRegSize = SingleWidth / SingleBytes;
- const int DoubleRegSize = FloatRegSize * 2;
-
class FloatRegFile
{
protected:
//Since the floating point registers overlap each other,
//A generic storage space is used. The float to be returned is
//pulled from the appropriate section of this region.
- char regSpace[FloatRegSize * NumFloatRegs];
+ //char regSpace[SingleBytes * NumFloatRegs];
+ FloatReg32 regs[NumFloatRegs];
public:
void clear()
{
- bzero(regSpace, sizeof(regSpace));
+ bzero(regs, sizeof(regs));
}
- FloatReg readReg(int floatReg, int width)
+ double readReg(int floatReg, int width)
{
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
switch(width)
{
case SingleWidth:
- float result32;
- memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
- return htog(result32);
+ void *float_ptr = ®s[floatReg];
+ return *(float *) float_ptr;
case DoubleWidth:
- double result64;
- memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
- return htog(result64);
+ void *double_ptr = ®s[floatReg];
+ return *(double *) double_ptr;
default:
panic("Attempted to read a %d bit floating point register!", width);
FloatRegBits readRegBits(int floatReg, int width)
{
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
+ using namespace std;
+
switch(width)
{
case SingleWidth:
- uint32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
- return htog(result32);
+ return regs[floatReg];
case DoubleWidth:
- uint64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
- return htog(result64);
+ cout << hex << "Combining " << regs[floatReg + 1] << " & " << regs[floatReg + 1] << endl;
+ cout << hex << "Returning " << ((FloatReg64)regs[floatReg] << 32 | regs[floatReg + 1]) << endl;
+ return (FloatReg64)regs[floatReg] << 32 | regs[floatReg + 1];
default:
panic("Attempted to read a %d bit floating point register!", width);
Fault setReg(int floatReg, const FloatReg &val, int width)
{
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
+
switch(width)
{
case SingleWidth:
- uint32_t result32;
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+ float temp = val;
+ void *float_ptr = &temp;
+ regs[floatReg] = *(FloatReg32 *) float_ptr;
break;
case DoubleWidth:
- uint64_t result64;
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+ const void *double_ptr = &val;
+ FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
+ regs[floatReg] = temp_double >> 32;
+ regs[floatReg + 1] = temp_double;
break;
-
default:
panic("Attempted to read a %d bit floating point register!", width);
}
+
return NoFault;
}
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
{
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
+ using namespace std;
+
switch(width)
{
case SingleWidth:
- uint32_t result32;
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+ regs[floatReg] = val;
break;
case DoubleWidth:
- uint64_t result64;
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+ cout << hex << "Setting val: " << val << endl;
+ regs[floatReg] = val >> 32;
+ regs[floatReg + 1] = val;
+ cout << dec << "f" << floatReg << ": " << hex<< readRegBits(floatReg,32) << endl;
+ cout << dec << "f" << floatReg + 1 << ": " << hex << readRegBits(floatReg+1,32) << endl;
break;
default:
RND_NEAREST
};
+ uint64_t convert_and_round(uint32_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
-
+ uint64_t convert_and_round(float fp_val,ConvertType cvt_type, int rnd_mode = 0);
void copyRegs(ExecContext *src, ExecContext *dest);
return miscRegFile.setRegWithEffect(miscReg, val, xc);
}
-
FloatReg readFloatReg(int floatReg)
{
return floatRegFile.readReg(floatReg,SingleWidth);