From a4ed65d0fa0a66d069f70a01c0caeb215e7ec760 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Mon, 8 May 2006 03:59:40 -0400 Subject: [PATCH] Start working on more complex FP tests Debug FP instructions to handle these FP insts arch/mips/isa/bitfields.isa: add Bitfield for Floating Point Condition Codes arch/mips/isa/decoder.isa: Follow instruction naming style with FP single insts Send the float value to the convert&round functions in single FP add ll inst support add 'token' sc support arch/mips/isa_traits.cc: Add SINGLE->WORD, WORD->SINGLE, & WORD->DOUBLE conversions arch/mips/regfile.hh: update header files arch/mips/regfile/float_regfile.hh: Add more FP registers --HG-- rename : arch/mips/int_regfile.hh => arch/mips/regfile/int_regfile.hh rename : arch/mips/misc_regfile.hh => arch/mips/regfile/misc_regfile.hh extra : convert_revision : 92faf0bfd8542ade762ac569ec158d198f6a9c7e --- arch/mips/isa/bitfields.isa | 5 +- arch/mips/isa/decoder.isa | 48 +++--- arch/mips/isa_traits.cc | 29 +++- arch/mips/regfile.hh | 6 +- arch/mips/regfile/float_regfile.hh | 187 ++++++++++++++++++++++++ arch/mips/{ => regfile}/int_regfile.hh | 0 arch/mips/{ => regfile}/misc_regfile.hh | 0 7 files changed, 240 insertions(+), 35 deletions(-) create mode 100644 arch/mips/regfile/float_regfile.hh rename arch/mips/{ => regfile}/int_regfile.hh (100%) rename arch/mips/{ => regfile}/misc_regfile.hh (100%) diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index eb917595c..e1124a591 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -39,7 +39,6 @@ def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; -def bitfield CC <20:18>; def bitfield ND <17:17>; def bitfield TF <16:16>; def bitfield MOVCI <16:16>; @@ -48,6 +47,10 @@ def bitfield SRL <21:21>; def bitfield SRLV < 6: 6>; def bitfield SA <10: 6>; +// Floating Point Condition Codes +def bitfield CC <10:8>; +def bitfield BRANCH_CC <20:18>; + // CP0 Register Select def bitfield SEL < 2: 0>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 53bbb94a4..d2d14efd0 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -500,51 +500,51 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format FloatOp { - 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); - 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); - 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); - 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); - 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); - 0x5: abss({{ Fd.sf = fabs(Fs.sf);}}); - 0x6: movs({{ Fd.sf = Fs.sf;}}); - 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); + 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}}); + 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}}); + 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}}); + 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}}); + 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}}); + 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}}); + 0x6: mov_s({{ Fd.sf = Fs.sf;}}); + 0x7: neg_s({{ Fd.sf = -1 * Fs.sf;}}); } } 0x1: decode FUNCTION_LO { format Float64Op { 0x0: round_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST); + Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_NEAREST); }}); 0x1: trunc_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO); + Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_ZERO); }}); 0x2: ceil_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP); + Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_UP); }}); 0x3: floor_l_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN); + Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, RND_DOWN); }}); } format FloatOp { 0x4: round_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST); + Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_NEAREST); }}); 0x5: trunc_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO); + Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_ZERO); }}); 0x6: ceil_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP); + Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_UP); }}); 0x7: floor_w_s({{ - Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN); + Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, RND_DOWN); }}); } } @@ -578,7 +578,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode); + Fd.uw = convert_and_round(Fs.sf, SINGLE_TO_WORD, rnd_mode); }}); } @@ -586,7 +586,7 @@ decode OPCODE_HI default Unknown::unknown() { format Float64Op { 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.uw, SINGLE_TO_LONG, rnd_mode); + Fd.ud = convert_and_round(Fs.sf, SINGLE_TO_LONG, rnd_mode); }}); 0x6: cvt_ps_st({{ @@ -696,12 +696,12 @@ decode OPCODE_HI default Unknown::unknown() { format FloatOp { 0x20: cvt_s_w({{ int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.uw = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode); + Fd.uw = convert_and_round(Fs.sf, WORD_TO_SINGLE, rnd_mode); }}); 0x21: cvt_d_w({{ int rnd_mode = xc->readMiscReg(FCSR) & 0x03; - Fd.ud = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode); + Fd.ud = convert_and_round(Fs.sf, WORD_TO_DOUBLE, rnd_mode); }}); } } @@ -1033,8 +1033,6 @@ decode OPCODE_HI default Unknown::unknown() { uint32_t unalign_addr = Rs + disp; uint32_t offset = unalign_addr & 0x00000003; #if BYTE_ORDER == BIG_ENDIAN - std::cout << "Big Endian Byte Order\n"; - switch(offset) { case 0: @@ -1060,8 +1058,6 @@ decode OPCODE_HI default Unknown::unknown() { panic("lwl: bad offset"); } #elif BYTE_ORDER == LITTLE_ENDIAN - std::cout << "Little Endian Byte Order\n"; - switch(offset) { case 0: @@ -1274,7 +1270,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: FailUnimpl::ll(); + 0x0: LoadMemory::ll({{Rt.uw = Mem.uw}},mem_flags=LOCKED); format LoadFloatMemory { 0x1: lwc1({{ Ft.uw = Mem.uw; }}); @@ -1284,7 +1280,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: FailUnimpl::sc(); + 0x0: StoreMemory::sc({{ Mem.uw = Rt.uw; Rt.uw = 1; }}); format StoreFloatMemory { 0x1: swc1({{ Mem.uw = Ft.uw; }}); diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index fcc3007ca..2260cdc35 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -122,16 +122,35 @@ MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) uint64_t MipsISA::convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode) { + 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 ; - return dp_bits; + double sdouble_val = fp_val; + void *sdouble_ptr = &sdouble_val; + uint64_t sdp_bits = *(uint64_t *) sdouble_ptr ; + return sdp_bits; + + case SINGLE_TO_WORD: + int32_t sword_val = (int32_t) fp_val; + void *sword_ptr = &sword_val; + uint64_t sword_bits= *(uint32_t *) sword_ptr ; + return sword_bits; + + case WORD_TO_SINGLE: + float wfloat_val = fp_val; + void *wfloat_ptr = &wfloat_val; + uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr ; + return wfloat_bits; + + case WORD_TO_DOUBLE: + double wdouble_val = fp_val; + void *wdouble_ptr = &wdouble_val; + uint64_t wdp_bits = *(uint64_t *) wdouble_ptr ; + return wdp_bits; default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); + panic("Invalid Floating Point Conversion Type (%d). See types.hh for Conversion List\n",cvt_type); return 0; } } diff --git a/arch/mips/regfile.hh b/arch/mips/regfile.hh index 3dcf8ef18..bd825d479 100644 --- a/arch/mips/regfile.hh +++ b/arch/mips/regfile.hh @@ -31,9 +31,9 @@ #include "arch/mips/types.hh" #include "arch/mips/constants.hh" -#include "arch/mips/int_regfile.hh" -#include "arch/mips/float_regfile.hh" -#include "arch/mips/misc_regfile.hh" +#include "arch/mips/regfile/int_regfile.hh" +#include "arch/mips/regfile/float_regfile.hh" +#include "arch/mips/regfile/misc_regfile.hh" #include "sim/faults.hh" class Checkpoint; diff --git a/arch/mips/regfile/float_regfile.hh b/arch/mips/regfile/float_regfile.hh new file mode 100644 index 000000000..308d418a0 --- /dev/null +++ b/arch/mips/regfile/float_regfile.hh @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_MIPS_FLOAT_REGFILE_HH__ +#define __ARCH_MIPS_FLOAT_REGFILE_HH__ + +#include "arch/mips/types.hh" +#include "arch/mips/constants.hh" +#include "base/misc.hh" +#include "config/full_system.hh" +#include "sim/byteswap.hh" +#include "sim/faults.hh" +#include "sim/host.hh" + +class Checkpoint; +class ExecContext; +class Regfile; + +namespace MipsISA +{ + class FloatRegFile + { + protected: + FloatReg32 regs[NumFloatRegs]; + FloatReg32 fir; + FloatReg32 fcsr; + + FloatReg32 fpcr; + + FloatReg32 fccr; + FloatReg32 fexr; + FloatReg32 fenr; + + public: + + void clear() + { + bzero(regs, sizeof(regs)); + } + + double readReg(int floatReg, int width) + { + using namespace std; + + switch(width) + { + case SingleWidth: + void *float_ptr = ®s[floatReg]; + return *(float *) float_ptr; + + case DoubleWidth: + uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + void *double_ptr = &double_val; + return *(double *) double_ptr; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } + + FloatRegBits readRegBits(int floatReg, int width) + { + switch(width) + { + case SingleWidth: + return regs[floatReg]; + + case DoubleWidth: + return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg]; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + } + + Fault setReg(int floatReg, const FloatReg &val, int width) + { + + switch(width) + { + case SingleWidth: + float temp = val; + void *float_ptr = &temp; + regs[floatReg] = *(FloatReg32 *) float_ptr; + break; + + case DoubleWidth: + const void *double_ptr = &val; + FloatReg64 temp_double = *(FloatReg64 *) double_ptr; + regs[floatReg + 1] = temp_double >> 32; + regs[floatReg] = 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) + { + using namespace std; + + switch(width) + { + case SingleWidth: + regs[floatReg] = val; + break; + + case DoubleWidth: + regs[floatReg + 1] = val >> 32; + regs[floatReg] = val; + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; + } + + MiscReg readFIR() + { + return fir; + } + + Fault setFIR(const MiscReg &val) + { + fir = val; + return NoFault; + } + + MiscReg readFCSR() + { + return fcsr; + } + + Fault setFCSR(const MiscReg &val) + { + fcsr = val; + return NoFault; + } + + MiscReg readFPCR() + { + return fpcr; + } + + Fault setFPCR(const MiscReg &val) + { + fpcr = val; + return NoFault; + } + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + }; + +} // namespace MipsISA + +#endif diff --git a/arch/mips/int_regfile.hh b/arch/mips/regfile/int_regfile.hh similarity index 100% rename from arch/mips/int_regfile.hh rename to arch/mips/regfile/int_regfile.hh diff --git a/arch/mips/misc_regfile.hh b/arch/mips/regfile/misc_regfile.hh similarity index 100% rename from arch/mips/misc_regfile.hh rename to arch/mips/regfile/misc_regfile.hh -- 2.30.2