merge my index fix and lisa's fix
--HG-- extra : convert_revision : 5f2c7d46c96fa061bbfb66edf188d405ca600020
This commit is contained in:
commit
8ffd12e807
10 changed files with 377 additions and 229 deletions
|
@ -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;
|
||||
|
|
|
@ -46,164 +46,167 @@ enum interrupts_t {
|
|||
num_interrupt_types
|
||||
};
|
||||
|
||||
class Interrupts
|
||||
class Interrupts
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
bool interrupts[num_interrupt_types];
|
||||
int numPosted;
|
||||
|
||||
public:
|
||||
Interrupts()
|
||||
{
|
||||
for (int i = 0; i < num_interrupt_types; ++i) {
|
||||
interrupts[i] = false;
|
||||
}
|
||||
numPosted = 0;
|
||||
}
|
||||
|
||||
void post(int int_type)
|
||||
{
|
||||
if (int_type < 0 || int_type >= num_interrupt_types)
|
||||
panic("posting unknown interrupt!\n");
|
||||
if (interrupts[int_type] == false) {
|
||||
interrupts[int_type] = true;
|
||||
++numPosted;
|
||||
}
|
||||
}
|
||||
|
||||
void post(int int_num, int index)
|
||||
{
|
||||
|
||||
private:
|
||||
}
|
||||
|
||||
bool interrupts[num_interrupt_types];
|
||||
int numPosted;
|
||||
void clear(int int_num, int index)
|
||||
{
|
||||
|
||||
public:
|
||||
Interrupts()
|
||||
{
|
||||
for (int i = 0; i < num_interrupt_types; ++i) {
|
||||
interrupts[i] = false;
|
||||
}
|
||||
numPosted = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void post(int int_type)
|
||||
{
|
||||
if (int_type < 0 || int_type >= num_interrupt_types)
|
||||
panic("posting unknown interrupt!\n");
|
||||
void clear_all()
|
||||
{
|
||||
|
||||
if (interrupts[int_type] == false) {
|
||||
interrupts[int_type] = true;
|
||||
++numPosted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void post(int int_num, int index)
|
||||
{
|
||||
bool check_interrupts(ThreadContext * tc) const
|
||||
{
|
||||
if (numPosted)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
Fault getInterrupt(ThreadContext * tc)
|
||||
{
|
||||
int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
int pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool ie = pstate & PSTATE::ie;
|
||||
|
||||
void clear(int int_num, int index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void clear_all()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool check_interrupts(ThreadContext * tc) const
|
||||
{
|
||||
if (numPosted)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Fault getInterrupt(ThreadContext * tc)
|
||||
{
|
||||
int hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
int pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool ie = pstate & PSTATE::ie;
|
||||
|
||||
// THESE ARE IN ORDER OF PRIORITY
|
||||
// since there are early returns, and the highest
|
||||
// priority interrupts should get serviced,
|
||||
// it is v. important that new interrupts are inserted
|
||||
// in the right order of processing
|
||||
if (hpstate & HPSTATE::hpriv) {
|
||||
if (ie) {
|
||||
if (interrupts[hstick_match]) {
|
||||
if (tc->readMiscReg(MISCREG_HINTP) & 1) {
|
||||
interrupts[hstick_match] = false;
|
||||
--numPosted;
|
||||
return new HstickMatch;
|
||||
}
|
||||
}
|
||||
if (interrupts[interrupt_vector]) {
|
||||
interrupts[interrupt_vector] = false;
|
||||
--numPosted;
|
||||
//HAVEN'T IMPLed THIS YET
|
||||
return NoFault;
|
||||
}
|
||||
} else {
|
||||
if (interrupts[hstick_match]) {
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (interrupts[trap_level_zero]) {
|
||||
if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
|
||||
interrupts[trap_level_zero] = false;
|
||||
--numPosted;
|
||||
return new TrapLevelZero;
|
||||
}
|
||||
}
|
||||
// THESE ARE IN ORDER OF PRIORITY
|
||||
// since there are early returns, and the highest
|
||||
// priority interrupts should get serviced,
|
||||
// it is v. important that new interrupts are inserted
|
||||
// in the right order of processing
|
||||
if (hpstate & HPSTATE::hpriv) {
|
||||
if (ie) {
|
||||
if (interrupts[hstick_match]) {
|
||||
if (tc->readMiscReg(MISCREG_HINTP) & 1) {
|
||||
interrupts[hstick_match] = false;
|
||||
--numPosted;
|
||||
return new HstickMatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ie) {
|
||||
if (interrupts[cpu_mondo]) {
|
||||
interrupts[cpu_mondo] = false;
|
||||
--numPosted;
|
||||
return new CpuMondo;
|
||||
}
|
||||
if (interrupts[dev_mondo]) {
|
||||
interrupts[dev_mondo] = false;
|
||||
--numPosted;
|
||||
return new DevMondo;
|
||||
}
|
||||
if (interrupts[soft_interrupt]) {
|
||||
int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
|
||||
// it seems that interrupt vectors are right in
|
||||
// the middle of interrupt levels with regard to
|
||||
// priority, so have to check
|
||||
if ((il < 6) &&
|
||||
interrupts[interrupt_vector]) {
|
||||
// may require more details here since there
|
||||
// may be lots of interrupts embedded in an
|
||||
// platform interrupt vector
|
||||
interrupts[interrupt_vector] = false;
|
||||
--numPosted;
|
||||
//HAVEN'T IMPLed YET
|
||||
return NoFault;
|
||||
} else {
|
||||
if (il > tc->readMiscReg(MISCREG_PIL)) {
|
||||
uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
|
||||
uint64_t more = si & ~(1 << (il + 1));
|
||||
if (!InterruptLevel(more)) {
|
||||
interrupts[soft_interrupt] = false;
|
||||
--numPosted;
|
||||
}
|
||||
return new InterruptLevelN(il);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (interrupts[resumable_error]) {
|
||||
interrupts[resumable_error] = false;
|
||||
--numPosted;
|
||||
return new ResumableError;
|
||||
}
|
||||
if (interrupts[interrupt_vector]) {
|
||||
interrupts[interrupt_vector] = false;
|
||||
--numPosted;
|
||||
//HAVEN'T IMPLed THIS YET
|
||||
return NoFault;
|
||||
}
|
||||
} else {
|
||||
if (interrupts[hstick_match]) {
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (interrupts[trap_level_zero]) {
|
||||
if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
|
||||
interrupts[trap_level_zero] = false;
|
||||
--numPosted;
|
||||
return new TrapLevelZero;
|
||||
}
|
||||
}
|
||||
if (interrupts[hstick_match]) {
|
||||
if (tc->readMiscReg(MISCREG_HINTP) & 1) {
|
||||
interrupts[hstick_match] = false;
|
||||
--numPosted;
|
||||
return new HstickMatch;
|
||||
}
|
||||
}
|
||||
if (ie) {
|
||||
if (interrupts[cpu_mondo]) {
|
||||
interrupts[cpu_mondo] = false;
|
||||
--numPosted;
|
||||
return new CpuMondo;
|
||||
}
|
||||
if (interrupts[dev_mondo]) {
|
||||
interrupts[dev_mondo] = false;
|
||||
--numPosted;
|
||||
return new DevMondo;
|
||||
}
|
||||
if (interrupts[soft_interrupt]) {
|
||||
int il = InterruptLevel(tc->readMiscReg(MISCREG_SOFTINT));
|
||||
// it seems that interrupt vectors are right in
|
||||
// the middle of interrupt levels with regard to
|
||||
// priority, so have to check
|
||||
if ((il < 6) &&
|
||||
interrupts[interrupt_vector]) {
|
||||
// may require more details here since there
|
||||
// may be lots of interrupts embedded in an
|
||||
// platform interrupt vector
|
||||
interrupts[interrupt_vector] = false;
|
||||
--numPosted;
|
||||
//HAVEN'T IMPLed YET
|
||||
return NoFault;
|
||||
} else {
|
||||
if (il > tc->readMiscReg(MISCREG_PIL)) {
|
||||
uint64_t si = tc->readMiscReg(MISCREG_SOFTINT);
|
||||
uint64_t more = si & ~(1 << (il + 1));
|
||||
if (!InterruptLevel(more)) {
|
||||
interrupts[soft_interrupt] = false;
|
||||
--numPosted;
|
||||
}
|
||||
return new InterruptLevelN(il);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (interrupts[resumable_error]) {
|
||||
interrupts[resumable_error] = false;
|
||||
--numPosted;
|
||||
return new ResumableError;
|
||||
}
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void updateIntrInfo(ThreadContext * tc)
|
||||
{
|
||||
void updateIntrInfo(ThreadContext * tc)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os)
|
||||
{
|
||||
}
|
||||
void serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(interrupts,num_interrupt_types);
|
||||
SERIALIZE_SCALAR(numPosted);
|
||||
}
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
void unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
|
||||
UNSERIALIZE_SCALAR(numPosted);
|
||||
}
|
||||
};
|
||||
} // namespace SPARC_ISA
|
||||
|
||||
#endif // __ARCH_SPARC_INTERRUPT_HH__
|
||||
|
|
|
@ -479,10 +479,10 @@ decode OP default Unknown::unknown()
|
|||
0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}});
|
||||
//0x12 should cause an illegal instruction exception
|
||||
0x13: NoPriv::rdgsr({{
|
||||
if(Fprs<2:> == 0 || Pstate<4:> == 0)
|
||||
Rd = Gsr;
|
||||
else
|
||||
fault = new FpDisabled;
|
||||
fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
return fault;
|
||||
Rd = Gsr;
|
||||
}});
|
||||
//0x14-0x15 should cause an illegal instruction exception
|
||||
0x16: Priv::rdsoftint({{Rd = Softint;}});
|
||||
|
@ -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,23 @@ 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);
|
||||
}});
|
||||
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);
|
||||
}});
|
||||
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 +837,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 +866,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 +966,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 +994,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 +1242,32 @@ decode OP default Unknown::unknown()
|
|||
Rd.uw = uReg0;}}, {{EXT_ASI}});
|
||||
format Trap {
|
||||
0x20: Load::ldf({{Frds.uw = Mem.uw;}});
|
||||
0x21: decode X {
|
||||
0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
|
||||
0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
|
||||
0x21: decode RD {
|
||||
0x0: Load::ldfsr({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
return fault;
|
||||
Fsr = Mem.uw | Fsr<63:32>;}});
|
||||
0x1: Load::ldxfsr({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
return fault;
|
||||
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({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
return fault;
|
||||
Mem.uw = Fsr<31:0>;
|
||||
Fsr = insertBits(Fsr,16,14,0);}});
|
||||
0x1: Store::stxfsr({{fault = checkFpEnableFault(xc);
|
||||
if (fault)
|
||||
return fault;
|
||||
Mem.udw = Fsr;
|
||||
Fsr = insertBits(Fsr,16,14,0);}});
|
||||
default: FailUnimpl::stfsrOther();
|
||||
}
|
||||
0x26: stqf({{fault = new FpDisabled;}});
|
||||
0x27: Store::stdf({{Mem.udw = Frd.udw;}});
|
||||
|
|
|
@ -103,3 +103,46 @@ def format BasicOperate(code, *flags) {{
|
|||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = BasicExecute.subst(iop)
|
||||
}};
|
||||
|
||||
def format FpBasic(code, *flags) {{
|
||||
fp_code = """
|
||||
Fsr |= bits(Fsr,4,0) << 5;
|
||||
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)
|
||||
}};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -668,8 +668,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
if (!implicit && asi != ASI_P && asi != ASI_S) {
|
||||
if (AsiIsLittle(asi))
|
||||
panic("Little Endian ASIs not supported\n");
|
||||
if (AsiIsBlock(asi))
|
||||
panic("Block ASIs not supported\n");
|
||||
if (AsiIsNoFault(asi))
|
||||
panic("No Fault ASIs not supported\n");
|
||||
|
||||
|
@ -688,7 +686,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
|||
goto handleSparcErrorRegAccess;
|
||||
|
||||
if (!AsiIsReal(asi) && !AsiIsNucleus(asi) && !AsiIsAsIfUser(asi) &&
|
||||
!AsiIsTwin(asi))
|
||||
!AsiIsTwin(asi) && !AsiIsBlock(asi))
|
||||
panic("Accessing ASI %#X. Should we?\n", asi);
|
||||
}
|
||||
|
||||
|
|
|
@ -411,8 +411,14 @@ Trace::InstRecord::dump(ostream &outs)
|
|||
if(shared_data->y !=
|
||||
thread->readIntReg(NumIntArchRegs + 1))
|
||||
diffY = true;
|
||||
if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR))
|
||||
if(shared_data->fsr != thread->readMiscReg(MISCREG_FSR)) {
|
||||
diffFsr = true;
|
||||
if (mbits(shared_data->fsr, 63,10) ==
|
||||
mbits(thread->readMiscReg(MISCREG_FSR), 63,10)) {
|
||||
thread->setMiscReg(MISCREG_FSR, shared_data->fsr);
|
||||
diffFsr = false;
|
||||
}
|
||||
}
|
||||
//if(shared_data->ccr != thread->readMiscReg(MISCREG_CCR))
|
||||
if(shared_data->ccr !=
|
||||
thread->readIntReg(NumIntArchRegs + 2))
|
||||
|
@ -450,16 +456,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 +642,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]);
|
||||
}
|
||||
}
|
||||
|
@ -667,7 +670,7 @@ Trace::InstRecord::dump(ostream &outs)
|
|||
}
|
||||
|
||||
diffcount++;
|
||||
if (diffcount > 2)
|
||||
if (diffcount > 3)
|
||||
fatal("Differences found between Legion and M5\n");
|
||||
} else
|
||||
diffcount = 0;
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
MmDisk::MmDisk(Params *p)
|
||||
: BasicPioDevice(p), image(p->image), curSector((uint64_t)-1), dirty(false)
|
||||
{
|
||||
std::memset(&bytes, 0, SectorSize);
|
||||
std::memset(&diskData, 0, SectorSize);
|
||||
pioSize = image->size() * SectorSize;
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,9 @@ MmDisk::read(PacketPtr pkt)
|
|||
Addr accessAddr;
|
||||
off_t sector;
|
||||
off_t bytes_read;
|
||||
uint16_t *d16;
|
||||
uint32_t *d32;
|
||||
uint64_t *d64;
|
||||
uint16_t d16;
|
||||
uint32_t d32;
|
||||
uint64_t d64;
|
||||
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
|
@ -68,26 +68,34 @@ MmDisk::read(PacketPtr pkt)
|
|||
sector = accessAddr / SectorSize;
|
||||
|
||||
if (sector != curSector) {
|
||||
if (dirty)
|
||||
bytes_read = image->write(bytes, curSector);
|
||||
bytes_read = image->read(bytes, sector);
|
||||
if (dirty) {
|
||||
bytes_read = image->write(diskData, curSector);
|
||||
assert(bytes_read == SectorSize);
|
||||
}
|
||||
bytes_read = image->read(diskData, sector);
|
||||
assert(bytes_read == SectorSize);
|
||||
curSector = sector;
|
||||
}
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint8_t):
|
||||
pkt->set(bytes[accessAddr % SectorSize]);
|
||||
pkt->set(diskData[accessAddr % SectorSize]);
|
||||
DPRINTF(IdeDisk, "reading byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
|
||||
SectorSize]);
|
||||
break;
|
||||
case sizeof(uint16_t):
|
||||
d16 = (uint16_t*)bytes + (accessAddr % SectorSize)/2;
|
||||
pkt->set(htobe(*d16));
|
||||
memcpy(&d16, diskData + (accessAddr % SectorSize), 2);
|
||||
pkt->set(htobe(d32));
|
||||
DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16);
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
d32 = (uint32_t*)bytes + (accessAddr % SectorSize)/4;
|
||||
pkt->set(htobe(*d32));
|
||||
memcpy(&d32, diskData + (accessAddr % SectorSize), 4);
|
||||
pkt->set(htobe(d32));
|
||||
DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32);
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
d64 = (uint64_t*)bytes + (accessAddr % SectorSize)/8;
|
||||
pkt->set(htobe(*d64));
|
||||
memcpy(&d64, diskData + (accessAddr % SectorSize), 8);
|
||||
pkt->set(htobe(d64));
|
||||
DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64);
|
||||
break;
|
||||
default:
|
||||
panic("Invalid access size\n");
|
||||
|
@ -100,10 +108,73 @@ MmDisk::read(PacketPtr pkt)
|
|||
Tick
|
||||
MmDisk::write(PacketPtr pkt)
|
||||
{
|
||||
panic("need to implement\n");
|
||||
M5_DUMMY_RETURN
|
||||
Addr accessAddr;
|
||||
off_t sector;
|
||||
off_t bytes_read;
|
||||
uint16_t d16;
|
||||
uint32_t d32;
|
||||
uint64_t d64;
|
||||
|
||||
assert(pkt->result == Packet::Unknown);
|
||||
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
|
||||
accessAddr = pkt->getAddr() - pioAddr;
|
||||
|
||||
sector = accessAddr / SectorSize;
|
||||
|
||||
if (sector != curSector) {
|
||||
if (dirty) {
|
||||
bytes_read = image->write(diskData, curSector);
|
||||
assert(bytes_read == SectorSize);
|
||||
}
|
||||
bytes_read = image->read(diskData, sector);
|
||||
assert(bytes_read == SectorSize);
|
||||
curSector = sector;
|
||||
}
|
||||
dirty = true;
|
||||
|
||||
switch (pkt->getSize()) {
|
||||
case sizeof(uint8_t):
|
||||
diskData[accessAddr % SectorSize] = htobe(pkt->get<uint8_t>());
|
||||
DPRINTF(IdeDisk, "writing byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
|
||||
SectorSize]);
|
||||
break;
|
||||
case sizeof(uint16_t):
|
||||
d16 = htobe(pkt->get<uint16_t>());
|
||||
memcpy(diskData + (accessAddr % SectorSize), &d16, 2);
|
||||
DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16);
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
d32 = htobe(pkt->get<uint32_t>());
|
||||
memcpy(diskData + (accessAddr % SectorSize), &d32, 4);
|
||||
DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32);
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
d64 = htobe(pkt->get<uint64_t>());
|
||||
memcpy(diskData + (accessAddr % SectorSize), &d64, 8);
|
||||
DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64);
|
||||
break;
|
||||
default:
|
||||
panic("Invalid access size\n");
|
||||
}
|
||||
|
||||
pkt->result = Packet::Success;
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
void
|
||||
MmDisk::serialize(std::ostream &os)
|
||||
{
|
||||
// just write any dirty changes to the cow layer it will take care of
|
||||
// serialization
|
||||
int bytes_read;
|
||||
if (dirty) {
|
||||
bytes_read = image->write(diskData, curSector);
|
||||
assert(bytes_read == SectorSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(MmDisk)
|
||||
Param<Addr> pio_addr;
|
||||
|
|
|
@ -46,10 +46,7 @@ class MmDisk : public BasicPioDevice
|
|||
DiskImage *image;
|
||||
off_t curSector;
|
||||
bool dirty;
|
||||
union {
|
||||
uint8_t bytes[SectorSize];
|
||||
uint32_t words[SectorSize/4];
|
||||
};
|
||||
uint8_t diskData[SectorSize];
|
||||
|
||||
public:
|
||||
struct Params : public BasicPioDevice::Params
|
||||
|
@ -64,6 +61,8 @@ class MmDisk : public BasicPioDevice
|
|||
|
||||
virtual Tick read(PacketPtr pkt);
|
||||
virtual Tick write(PacketPtr pkt);
|
||||
|
||||
virtual void serialize(std::ostream &os);
|
||||
};
|
||||
|
||||
#endif //__DEV_SPARC_MM_DISK_HH__
|
||||
|
|
Loading…
Reference in a new issue