diff options
-rwxr-xr-x | arch/isa_parser.py | 10 | ||||
-rw-r--r-- | arch/mips/isa/decoder.isa | 42 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 2 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 83 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 96 | ||||
-rwxr-xr-x | configs/test/hello_mips | bin | 837626 -> 837718 bytes | |||
-rw-r--r-- | cpu/simple/cpu.hh | 2 |
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 = ®s[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 = ®s[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 Binary files differindex a3db001ec..33d9fbb58 100755 --- a/configs/test/hello_mips +++ b/configs/test/hello_mips 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); |