Changes to get Floating Point Instructions w/new regfile to at least not segfault and break my INT tests
arch/mips/isa/decoder.isa:
Change decoder to read COP1 (floating point) instructions to decode correctly
arch/mips/isa_traits.hh:
Change to use overlapping single/double FP regfile
--HG--
extra : convert_revision : 2d15d6d88939f7e0d63279d5c35d7eea536a573c
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
default:
|
||||
panic("Attempted to read a %d bit floating point register!", width);
|
||||
}
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg, int width)
|
||||
{
|
||||
return readRegBits(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:
|
||||
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);
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
d[floatReg] = val;
|
||||
return NoFault;
|
||||
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);
|
||||
}
|
||||
//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;
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
q[floatReg] = val;
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user