summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarch/isa_parser.py10
-rw-r--r--arch/mips/isa/decoder.isa42
-rw-r--r--arch/mips/isa/formats/fp.isa2
-rw-r--r--arch/mips/isa_traits.cc83
-rw-r--r--arch/mips/isa_traits.hh96
-rwxr-xr-xconfigs/test/hello_mipsbin837626 -> 837718 bytes
-rw-r--r--cpu/simple/cpu.hh2
7 files changed, 151 insertions, 84 deletions
diff --git a/arch/isa_parser.py b/arch/isa_parser.py
index 921a6fa82..a92c85c3f 100755
--- a/arch/isa_parser.py
+++ b/arch/isa_parser.py
@@ -1226,6 +1226,10 @@ class FloatRegOperand(Operand):
width = 64;
else:
func = 'readFloatRegBits'
+ if (self.ctype == 'uint32_t'):
+ width = 32;
+ elif (self.ctype == 'uint64_t'):
+ width = 64;
if (self.size != self.dflt_size):
bit_select = 1
if width:
@@ -1251,6 +1255,12 @@ class FloatRegOperand(Operand):
elif (self.ctype == 'double'):
width = 64
func = 'setFloatReg'
+ elif (self.ctype == 'uint32_t'):
+ func = 'setFloatRegBits'
+ width = 32
+ elif (self.ctype == 'uint64_t'):
+ func = 'setFloatRegBits'
+ width = 64
else:
func = 'setFloatRegBits'
final_ctype = 'uint%d_t' % self.dflt_size
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 6feaec7cb..9bafe9f34 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -397,7 +397,7 @@ decode OPCODE_HI default Unknown::unknown() {
format FloatOp {
0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
- 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
+ 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
0x7: mthc1({{
uint64_t fs_hi = Rt.ud << 32;
uint64_t fs_lo = Fs.ud & 0x0000FFFF;
@@ -572,7 +572,7 @@ decode OPCODE_HI default Unknown::unknown() {
format FloatOp {
0x1: cvt_d_s({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_DOUBLE, rnd_mode);
+ Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_DOUBLE, rnd_mode);
}});
0x4: cvt_w_s({{
@@ -585,7 +585,7 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x5: cvt_l_s({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode);
+ Fd.ud = convert_and_round(Fs.uw, SINGLE_TO_LONG, rnd_mode);
}});
0x6: cvt_ps_st({{
@@ -605,7 +605,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
0x5: absd({{ Fd.df = fabs(Fs.df);}});
- 0x6: movd({{ Fd.df = Fs.df;}});
+ 0x6: movd({{ Fd.ud = Fs.ud;}});
0x7: negd({{ Fd.df = -1 * Fs.df;}});
}
}
@@ -613,37 +613,37 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode FUNCTION_LO {
format Float64Op {
0x0: round_l_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST);
+ Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST);
}});
0x1: trunc_l_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO);
+ Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO);
}});
0x2: ceil_l_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP);
+ Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP);
}});
0x3: floor_l_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN);
+ Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN);
}});
}
format FloatOp {
0x4: round_w_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST);
}});
0x5: trunc_w_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO);
}});
0x6: ceil_w_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP);
}});
0x7: floor_w_d({{
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN);
}});
}
}
@@ -671,12 +671,12 @@ decode OPCODE_HI default Unknown::unknown() {
format FloatOp {
0x0: cvt_s_d({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode);
}});
0x4: cvt_w_d({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode);
+ Fd.uw = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode);
}});
}
@@ -684,7 +684,7 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x5: cvt_l_d({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode);
+ Fd.ud = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode);
}});
}
}
@@ -695,12 +695,12 @@ decode OPCODE_HI default Unknown::unknown() {
format FloatOp {
0x20: cvt_s_w({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode);
+ Fd.uw = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode);
}});
0x21: cvt_d_w({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode);
+ Fd.ud = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode);
}});
}
}
@@ -712,12 +712,12 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x10: cvt_s_l({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode);
+ Fd.uw = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode);
}});
0x11: cvt_d_l({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode);
+ Fd.ud = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode);
}});
}
}
@@ -778,7 +778,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode FUNCTION_LO {
0x0: Float64Op::cvt_s_pu({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode);
+ Fd.uw = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode);
}});
}
@@ -786,7 +786,7 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x0: cvt_s_pl({{
int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
- Fd = convert_and_round(Fs.ud, PLOWER_TO_SINGLE,
+ Fd.uw = convert_and_round(Fs.ud, PLOWER_TO_SINGLE,
rnd_mode);
}});
diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa
index 65b259e20..fe6bd437f 100644
--- a/arch/mips/isa/formats/fp.isa
+++ b/arch/mips/isa/formats/fp.isa
@@ -32,6 +32,7 @@ output decoder {{
// Primary format for float operate instructions:
def format FloatOp(code, *flags) {{
+ code = 'std::cout << "Floating Point Op" << std::endl;\n' + code
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -41,6 +42,7 @@ def format FloatOp(code, *flags) {{
// Primary format for float64 operate instructions:
def format Float64Op(code, *flags) {{
+ code = 'std::cout << "Floating Point 64" << std::endl;\n' + code
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index d23cdf367..20c13fd36 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -30,40 +30,95 @@
#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(uint64_t fp_val, ConvertType cvt_type, int rnd_mode)
+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:
- break;
+ 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;
- case SINGLE_TO_WORD:
- break;
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ uint64_t single_sign = fp_val & 0x80000000;
- case SINGLE_TO_LONG:
- break;
+ uint64_t single_exp = (fp_val & 0x7F800000) >> 22;
+ single_exp -= 127;
- case DOUBLE_TO_SINGLE:
+ uint64_t single_mantissa = fp_val & 0x007FFFFF;
- break;
+ uint64_t double_exp = single_exp + 1023;
+ double_exp = double_exp << 51;
- case LONG_TO_SINGLE:
- break;
+ uint64_t double_val = single_sign << 63 | double_exp | single_mantissa;
- case WORD_TO_SINGLE:
- break;
+ return double_val;
default:
- panic("Invalid Floating Point Conversion type being used.\n");
+ 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
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 3ea72bde2..105d4c283 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -189,21 +189,24 @@ namespace MipsISA
};
- 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:
@@ -211,31 +214,33 @@ namespace MipsISA
//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.
+ using namespace std;
+
switch(width)
{
case SingleWidth:
- float result32;
- memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
- return htog(result32);
+ void *float_ptr = &regs[floatReg];
+ cout << "reading as float, reg." << floatReg << ": " << *(float *) float_ptr << endl;
+ cout << "reading as uint32_t, reg." << floatReg << ": " << *(uint32_t *) float_ptr << endl;
+ return *(float *) float_ptr;
case DoubleWidth:
- double result64;
- memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
- return htog(result64);
+ void *double_ptr = &regs[floatReg];
+ cout << "reading as double, reg." << floatReg <<": " << *(double *) double_ptr << endl;
+ cout << "reading as uint64_t, reg." << floatReg << hex << ": 0x" << *(uint64_t *) float_ptr << endl;
+ return *(double *) double_ptr;
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -244,20 +249,17 @@ namespace MipsISA
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);
@@ -266,47 +268,45 @@ namespace MipsISA
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:
@@ -348,8 +348,9 @@ namespace MipsISA
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);
@@ -637,7 +638,6 @@ extern const Addr PageOffset;
return miscRegFile.setRegWithEffect(miscReg, val, xc);
}
-
FloatReg readFloatReg(int floatReg)
{
return floatRegFile.readReg(floatReg,SingleWidth);
diff --git a/configs/test/hello_mips b/configs/test/hello_mips
index a3db001ec..33d9fbb58 100755
--- a/configs/test/hello_mips
+++ b/configs/test/hello_mips
Binary files differ
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index 252d57206..945de20af 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -373,7 +373,7 @@ class SimpleCPU : public BaseCPU
}
void setFloatRegBits(const StaticInst *si, int idx,
- FloatRegBits val, int width)
+ FloatRegBits val, int width)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
cpuXC->setFloatRegBits(reg_idx, val, width);