diff options
-rw-r--r-- | arch/mips/isa/decoder.isa | 30 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 141 |
2 files changed, 123 insertions, 48 deletions
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 077f0afd0..1a188d67a 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -450,8 +450,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S //(( single-word )) - 0x0: decode RS_HI { - 0x0: decode RS_LO { + 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;}}); @@ -464,7 +464,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { + 0x1: decode FUNCTION_LO { //only legal for 64 bit-FP format Float64Op { 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}}); @@ -481,7 +481,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); @@ -500,7 +500,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { format FloatOp { 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR); @@ -524,8 +524,8 @@ decode OPCODE_HI default Unknown::unknown() { } //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D - 0x1: decode RS_HI { - 0x0: decode RS_LO { + 0x1: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format FloatOp { 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); @@ -538,7 +538,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { + 0x1: decode FUNCTION_LO { //only legal for 64 bit format Float64Op { 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); @@ -555,7 +555,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }}); @@ -574,7 +574,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { format FloatOp { 0x0: cvt_s_d({{ int rnd_mode = xc->readMiscReg(FCSR); @@ -632,8 +632,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 //Note: "1. Format type PS is legal only if 64-bit floating point operations //are enabled. " - 0x6: decode RS_HI { - 0x0: decode RS_LO { + 0x6: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format Float64Op { 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut @@ -667,7 +667,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format Float64Op { 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}}); @@ -682,14 +682,14 @@ decode OPCODE_HI default Unknown::unknown() { } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { 0x0: Float64Op::cvt_s_pu({{ int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } - 0x5: decode RS_LO { + 0x5: decode FUNCTION_LO { format Float64Op { 0x0: cvt_s_pl({{ int rnd_mode = xc->readMiscReg(FCSR); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 1f4ccbd90..2403782d0 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -30,8 +30,10 @@ #define __ARCH_MIPS_ISA_TRAITS_HH__ //#include "arch/mips/misc_regfile.hh" +#include "arch/mips/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" +#include "sim/byteswap.hh" #include "sim/host.hh" #include "sim/faults.hh" @@ -105,7 +107,7 @@ namespace MipsISA const int NumPALShadowRegs = 8; const int NumFloatArchRegs = 32; // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 32; + const int NumMiscArchRegs = 265; const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; const int NumFloatRegs = NumFloatArchRegs; @@ -189,63 +191,135 @@ namespace MipsISA typedef double FloatReg; typedef uint64_t FloatRegBits; + + const int SingleWidth = 32; + const int SingleBytes = SingleWidth / 4; + + const int DoubleWidth = 64; + const int DoubleBytes = DoubleWidth / 4; + + const int QuadWidth = 128; + const int QuadBytes = QuadWidth / 4; + + const int FloatRegSize = SingleWidth / SingleBytes; + const int DoubleRegSize = FloatRegSize * 2; + class FloatRegFile { protected: - FloatRegBits q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view + //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]; public: - FloatReg readReg(int floatReg) + void clear() { - return d[floatReg]; + bzero(regSpace, sizeof(regSpace)); } FloatReg readReg(int floatReg, int width) { - return readReg(floatReg); - } + //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); - FloatRegBits readRegBits(int floatReg) - { - return q[floatReg]; - } + case DoubleWidth: + double result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); - FloatRegBits readRegBits(int floatReg, int width) - { - return readRegBits(floatReg); + default: + panic("Attempted to read a %d bit floating point register!", width); + } } - Fault setReg(int floatReg, const FloatReg &val) + FloatRegBits readRegBits(int floatReg, int width) { - d[floatReg] = val; - return NoFault; + //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; + memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize); + return htog(result32); + case DoubleWidth: + uint64_t result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); + + default: + panic("Attempted to read a %d bit floating point register!", width); + } } Fault setReg(int floatReg, const FloatReg &val, int width) { - return setReg(floatReg, val); - } - - Fault setRegBits(int floatReg, const FloatRegBits &val) - { - q[floatReg] = val; + //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); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + + default: + panic("Attempted to read a %d bit floating point register!", width); + } return NoFault; } Fault setRegBits(int floatReg, const FloatRegBits &val, int width) { - return setRegBits(floatReg, val); + //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); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; } void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - }; + void copyRegs(ExecContext *src, ExecContext *dest); // cop-0/cop-1 system control register file @@ -532,44 +606,45 @@ extern const Addr PageOffset; return miscRegFile.setRegWithEffect(miscReg, val, xc); } + FloatReg readFloatReg(int floatReg) { - return floatRegFile.readReg(floatReg); + return floatRegFile.readReg(floatReg,SingleWidth); } FloatReg readFloatReg(int floatReg, int width) { - return readFloatReg(floatReg); + return floatRegFile.readReg(floatReg,width); } FloatRegBits readFloatRegBits(int floatReg) { - return floatRegFile.readRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,SingleWidth); } FloatRegBits readFloatRegBits(int floatReg, int width) { - return readFloatRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,width); } Fault setFloatReg(int floatReg, const FloatReg &val) { - return floatRegFile.setReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, SingleWidth); } Fault setFloatReg(int floatReg, const FloatReg &val, int width) { - return setFloatReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, width); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val) { - return floatRegFile.setRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, SingleWidth); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return setFloatRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, width); } IntReg readIntReg(int intReg) |