fix mostly floating point related

src/arch/sparc/floatregfile.cc:
    fix fp read/writing to registers... looking for suggestions on cleaner ways if anyone has them
src/arch/sparc/isa/decoder.isa:
    fix some fp implementations
src/arch/sparc/isa/formats/basic.isa:
    add new fp op class that 0 cexec in fsr and sets rounding mode for the up comming op
src/arch/sparc/isa/includes.isa:
    include the appropriate header files for the rounding code
src/arch/sparc/miscregfile.cc:
    print fsr out when it's read/written and the Sparc traceflgas in on
src/cpu/exetrace.cc:
    fix printing of float registers

--HG--
extra : convert_revision : 49faab27f2e786a8455f9ca0f3f0132380c9d992
This commit is contained in:
Ali Saidi 2007-02-02 18:04:42 -05:00
parent 5c7192daed
commit 592f35ac0f
6 changed files with 118 additions and 61 deletions

View file

@ -69,22 +69,25 @@ FloatReg FloatRegFile::readReg(int floatReg, int width)
switch(width)
{
case SingleWidth:
float32_t result32;
uint32_t result32;
float32_t fresult32;
memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
result = htog(result32);
DPRINTF(Sparc, "Read FP32 register %d = 0x%x\n", floatReg, result);
result32 = htog(result32);
memcpy(&fresult32, &result32, sizeof(result32));
result = fresult32;
DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32);
break;
case DoubleWidth:
float64_t result64;
uint64_t result64;
float64_t fresult64;
memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
result = htog(result64);
DPRINTF(Sparc, "Read FP64 register %d = 0x%x\n", floatReg, result);
result64 = htog(result64);
memcpy(&fresult64, &result64, sizeof(result64));
result = fresult64;
DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64);
break;
case QuadWidth:
float128_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
result = htog(result128);
DPRINTF(Sparc, "Read FP128 register %d = 0x%x\n", floatReg, result);
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
@ -113,10 +116,7 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result);
break;
case QuadWidth:
uint64_t result128;
memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
result = htog(result128);
DPRINTF(Sparc, "Read FP128 bits register %d = 0x%x\n", floatReg, result);
panic("Quad width FP not implemented.");
break;
default:
panic("Attempted to read a %d bit floating point register!", width);
@ -132,15 +132,21 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
uint32_t result32;
uint64_t result64;
float32_t fresult32;
float64_t fresult64;
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
fresult32 = val;
memcpy(&result32, &fresult32, sizeof(result32));
result32 = gtoh(result32);
memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32);
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
fresult64 = val;
memcpy(&result64, &fresult64, sizeof(result64));
result64 = gtoh(result64);
memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64);
break;

View file

@ -718,7 +718,7 @@ decode OP default Unknown::unknown()
0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}});
}
0x34: decode OPF{
format BasicOperate{
format FpBasic{
0x01: fmovs({{
Frds.uw = Frs2s.uw;
//fsr.ftt = fsr.cexc = 0
@ -765,7 +765,7 @@ decode OP default Unknown::unknown()
0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
0x43: FpUnimpl::faddq();
0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}});
0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
0x46: fsubd({{Frd.df = Frs1.df - Frs2.df; }});
0x47: FpUnimpl::fsubq();
0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}});
0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
@ -776,26 +776,26 @@ decode OP default Unknown::unknown()
0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}});
0x6E: FpUnimpl::fdmulq();
0x81: fstox({{
Frd.df = (double)static_cast<int64_t>(Frs2s.sf);
Frd.sdw = static_cast<int64_t>(Frs2s.sf);
}});
0x82: fdtox({{
Frd.df = (double)static_cast<int64_t>(Frs2.df);
Frd.sdw = static_cast<int64_t>(Frs2.df);
}});
0x83: FpUnimpl::fqtox();
0x84: fxtos({{
Frds.sf = static_cast<float>((int64_t)Frs2.df);
Frds.sf = static_cast<float>(Frs2.sdw);
}});
0x88: fxtod({{
Frd.df = static_cast<double>((int64_t)Frs2.df);
Frd.df = static_cast<double>(Frs2.sdw);
}});
0x8C: FpUnimpl::fxtoq();
0xC4: fitos({{
Frds.sf = static_cast<float>((int32_t)Frs2s.sf);
Frds.sf = static_cast<float>(Frs2s.sw);
}});
0xC6: fdtos({{Frds.sf = Frs2.df;}});
0xC7: FpUnimpl::fqtos();
0xC8: fitod({{
Frd.df = static_cast<double>((int32_t)Frs2s.sf);
Frd.df = static_cast<double>(Frs2s.sw);
}});
0xC9: fstod({{Frd.df = Frs2s.sf;}});
0xCB: FpUnimpl::fqtod();
@ -803,17 +803,25 @@ decode OP default Unknown::unknown()
0xCD: FpUnimpl::fstoq();
0xCE: FpUnimpl::fdtoq();
0xD1: fstoi({{
Frds.sf = (float)static_cast<int32_t>(Frs2s.sf);
Frds.sw = static_cast<int32_t>(Frs2s.sf);
float t = Frds.sw;
if (t != Frs2s.sf)
Fsr = insertBits(Fsr, 4,0, 0x01);
Fsr |= Fsr<4:0> << 5;
}});
0xD2: fdtoi({{
Frds.sf = (float)static_cast<int32_t>(Frs2.df);
Frds.sw = static_cast<int32_t>(Frs2.df);
double t = Frds.sw;
if (t != Frs2.df)
Fsr = insertBits(Fsr, 4,0, 0x01);
Fsr |= Fsr<4:0> << 5;
}});
0xD3: FpUnimpl::fqtoi();
default: FailUnimpl::fpop1();
}
}
0x35: decode OPF{
format BasicOperate{
format FpBasic{
0x51: fcmps({{
uint8_t fcc;
if(isnan(Frs1s) || isnan(Frs2s))
@ -831,11 +839,11 @@ decode OP default Unknown::unknown()
}});
0x52: fcmpd({{
uint8_t fcc;
if(isnan(Frs1s) || isnan(Frs2s))
if(isnan(Frs1) || isnan(Frs2))
fcc = 3;
else if(Frs1s < Frs2s)
else if(Frs1 < Frs2)
fcc = 1;
else if(Frs1s > Frs2s)
else if(Frs1 > Frs2)
fcc = 2;
else
fcc = 0;
@ -860,11 +868,11 @@ decode OP default Unknown::unknown()
}});
0x56: fcmped({{
uint8_t fcc = 0;
if(isnan(Frs1s) || isnan(Frs2s))
if(isnan(Frs1) || isnan(Frs2))
fault = new FpExceptionIEEE754;
if(Frs1s < Frs2s)
if(Frs1 < Frs2)
fcc = 1;
else if(Frs1s > Frs2s)
else if(Frs1 > Frs2)
fcc = 2;
uint8_t firstbit = 10;
if(FCMPCC)
@ -960,24 +968,24 @@ decode OP default Unknown::unknown()
0x55: FailUnimpl::fpsub16s();
0x56: FailUnimpl::fpsub32();
0x57: FailUnimpl::fpsub32s();
0x60: BasicOperate::fzero({{Frd.df = 0;}});
0x61: BasicOperate::fzeros({{Frds.sf = 0;}});
0x60: FpBasic::fzero({{Frd.df = 0;}});
0x61: FpBasic::fzeros({{Frds.sf = 0;}});
0x62: FailUnimpl::fnor();
0x63: FailUnimpl::fnors();
0x64: FailUnimpl::fandnot2();
0x65: FailUnimpl::fandnot2s();
0x66: BasicOperate::fnot2({{
0x66: FpBasic::fnot2({{
Frd.df = (double)(~((uint64_t)Frs2.df));
}});
0x67: BasicOperate::fnot2s({{
0x67: FpBasic::fnot2s({{
Frds.sf = (float)(~((uint32_t)Frs2s.sf));
}});
0x68: FailUnimpl::fandnot1();
0x69: FailUnimpl::fandnot1s();
0x6A: BasicOperate::fnot1({{
0x6A: FpBasic::fnot1({{
Frd.df = (double)(~((uint64_t)Frs1.df));
}});
0x6B: BasicOperate::fnot1s({{
0x6B: FpBasic::fnot1s({{
Frds.sf = (float)(~((uint32_t)Frs1s.sf));
}});
0x6C: FailUnimpl::fxor();
@ -988,18 +996,18 @@ decode OP default Unknown::unknown()
0x71: FailUnimpl::fands();
0x72: FailUnimpl::fxnor();
0x73: FailUnimpl::fxnors();
0x74: BasicOperate::fsrc1({{Frd.udw = Frs1.udw;}});
0x75: BasicOperate::fsrc1s({{Frds.uw = Frs1s.uw;}});
0x74: FpBasic::fsrc1({{Frd.udw = Frs1.udw;}});
0x75: FpBasic::fsrc1s({{Frds.uw = Frs1s.uw;}});
0x76: FailUnimpl::fornot2();
0x77: FailUnimpl::fornot2s();
0x78: BasicOperate::fsrc2({{Frd.udw = Frs2.udw;}});
0x79: BasicOperate::fsrc2s({{Frds.uw = Frs2s.uw;}});
0x78: FpBasic::fsrc2({{Frd.udw = Frs2.udw;}});
0x79: FpBasic::fsrc2s({{Frds.uw = Frs2s.uw;}});
0x7A: FailUnimpl::fornot1();
0x7B: FailUnimpl::fornot1s();
0x7C: FailUnimpl::for();
0x7D: FailUnimpl::fors();
0x7E: BasicOperate::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
0x7F: BasicOperate::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
0x7E: FpBasic::fone({{Frd.udw = std::numeric_limits<uint64_t>::max();}});
0x7F: FpBasic::fones({{Frds.uw = std::numeric_limits<uint32_t>::max();}});
0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
0x81: FailUnimpl::siam();
}
@ -1236,16 +1244,20 @@ decode OP default Unknown::unknown()
Rd.uw = uReg0;}}, {{EXT_ASI}});
format Trap {
0x20: Load::ldf({{Frds.uw = Mem.uw;}});
0x21: decode X {
0x21: decode RD {
0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
default: FailUnimpl::ldfsrOther();
}
0x22: ldqf({{fault = new FpDisabled;}});
0x23: Load::lddf({{Frd.udw = Mem.udw;}});
0x24: Store::stf({{Mem.uw = Frds.uw;}});
0x25: decode X {
0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}});
0x1: Store::stxfsr({{Mem.udw = Fsr;}});
0x25: decode RD {
0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;
Fsr = insertBits(Fsr,16,14,0);}});
0x1: Store::stxfsr({{Mem.udw = Fsr;
Fsr = insertBits(Fsr,16,14,0);}});
default: FailUnimpl::stfsrOther();
}
0x26: stqf({{fault = new FpDisabled;}});
0x27: Store::stdf({{Mem.udw = Frd.udw;}});

View file

@ -103,3 +103,42 @@ def format BasicOperate(code, *flags) {{
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FpBasic(code, *flags) {{
fp_code = """
Fsr = insertBits(Fsr,4,0,0);
#if defined(__sun) || defined (__OpenBSD__)
fp_rnd newrnd = FP_RN;
switch (Fsr<31:30>) {
case 0: newrnd = FP_RN; break;
case 1: newrnd = FP_RZ; break;
case 2: newrnd = FP_RP; break;
case 3: newrnd = FP_RM; break;
}
fp_rnd oldrnd = fpsetround(newrnd);
#else
int newrnd = FE_TONEAREST;
switch (Fsr<31:30>) {
case 0: newrnd = FE_TONEAREST; break;
case 1: newrnd = FE_TOWARDZERO; break;
case 2: newrnd = FE_UPWARD; break;
case 3: newrnd = FE_DOWNWARD; break;
}
int oldrnd = fegetround();
fesetround(newrnd);
#endif
"""
fp_code += code
fp_code += """
#if defined(__sun) || defined (__OpenBSD__)
fpsetround(oldrnd);
#else
fesetround(oldrnd);
#endif
"""
iop = InstObjParams(name, Name, 'SparcStaticInst', fp_code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -53,7 +53,7 @@ output decoder {{
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include "mem/packet.hh"
#if defined(linux)
#if defined(linux) || defined(__APPLE__)
#include <fenv.h>
#endif
#include <algorithm>
@ -62,9 +62,14 @@ using namespace SparcISA;
}};
output exec {{
#if defined(linux)
#if defined(linux) || defined(__APPLE__)
#include <fenv.h>
#endif
#if defined(__sun) || defined (__OpenBSD__)
#include <ieeefp.h>
#endif
#include <limits>
#include <cmath>

View file

@ -232,6 +232,7 @@ MiscReg MiscRegFile::readReg(int miscReg)
/** Floating Point Status Register */
case MISCREG_FSR:
DPRINTF(Sparc, "FSR read as: %#x\n", fsr);
return fsr;
case MISCREG_MMU_P_CONTEXT:
@ -337,10 +338,6 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
case MISCREG_PCR:
case MISCREG_PIC:
panic("Performance Instrumentation not impl\n");
/** Floating Point Status Register */
case MISCREG_FSR:
warn("Reading FSR Floating Point not implemented\n");
break;
case MISCREG_SOFTINT_CLR:
case MISCREG_SOFTINT_SET:
panic("Can read from softint clr/set\n");
@ -488,6 +485,7 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
/** Floating Point Status Register */
case MISCREG_FSR:
fsr = val;
DPRINTF(Sparc, "FSR written with: %#x\n", fsr);
break;
case MISCREG_MMU_P_CONTEXT:

View file

@ -450,16 +450,13 @@ Trace::InstRecord::dump(ostream &outs)
diffTlb = true;
}
if ((diffPC || diffCC || diffInst || diffIntRegs ||
if (diffPC || diffCC || diffInst || diffIntRegs ||
diffFpRegs || diffTpc || diffTnpc || diffTstate ||
diffTt || diffHpstate || diffHtstate || diffHtba ||
diffPstate || diffY || diffCcr || diffTl || diffFsr ||
diffGl || diffAsi || diffPil || diffCwp || diffCansave ||
diffCanrestore || diffOtherwin || diffCleanwin || diffTlb)
&& !((staticInst->machInst & 0xC1F80000) == 0x81D00000)
&& !(((staticInst->machInst & 0xC0000000) == 0xC0000000)
&& shared_data->tl == thread->readMiscReg(MISCREG_TL) + 1)
) {
{
outs << "Differences found between M5 and Legion:";
if (diffPC)
@ -639,7 +636,7 @@ Trace::InstRecord::dump(ostream &outs)
char label[8];
sprintf(label, "%%f%d", x);
printRegPair(outs, label,
thread->readFloatRegBits(x,FloatRegFile::DoubleWidth),
thread->readFloatRegBits(x*2,FloatRegFile::DoubleWidth),
shared_data->fpregs[x]);
}
}