summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <stever@eecs.umich.edu>2007-02-07 22:33:44 -0500
committerSteve Reinhardt <stever@eecs.umich.edu>2007-02-07 22:33:44 -0500
commit2ec4a6c07132488abab62f6236406707d4388b2f (patch)
tree752c6e2a67894f34fb173d534bc7432e0221b2d0
parent6b37bb67101803f12b6ed2bef714af583d03f814 (diff)
parentfdaff2b1088446325dcb3c270b350b3314dca99a (diff)
downloadgem5-2ec4a6c07132488abab62f6236406707d4388b2f.tar.xz
Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/newmem
into zizzer.eecs.umich.edu:/z/stever/bk/newmem-head --HG-- extra : convert_revision : c56b8160b403fde235636ca5b5b4cecd206ffa4c
-rw-r--r--src/arch/sparc/floatregfile.cc38
-rw-r--r--src/arch/sparc/interrupts.hh257
-rw-r--r--src/arch/sparc/isa/decoder.isa100
-rw-r--r--src/arch/sparc/isa/formats/basic.isa43
-rw-r--r--src/arch/sparc/isa/includes.isa9
-rw-r--r--src/arch/sparc/miscregfile.cc6
-rw-r--r--src/arch/sparc/tlb.cc4
-rw-r--r--src/cpu/exetrace.cc19
-rw-r--r--src/dev/sparc/mm_disk.cc103
-rw-r--r--src/dev/sparc/mm_disk.hh7
10 files changed, 367 insertions, 219 deletions
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
index 585782ddb..e1b5ea7c8 100644
--- a/src/arch/sparc/floatregfile.cc
+++ b/src/arch/sparc/floatregfile.cc
@@ -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;
diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh
index 3af4f6342..dc3b235fe 100644
--- a/src/arch/sparc/interrupts.hh
+++ b/src/arch/sparc/interrupts.hh
@@ -46,164 +46,167 @@ enum interrupts_t {
num_interrupt_types
};
- class Interrupts
- {
+class Interrupts
+{
- private:
+ private:
- bool interrupts[num_interrupt_types];
- int numPosted;
+ bool interrupts[num_interrupt_types];
+ int numPosted;
- public:
- Interrupts()
- {
- for (int i = 0; i < num_interrupt_types; ++i) {
- interrupts[i] = false;
- }
- numPosted = 0;
+ 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_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)
- {
-
- }
+ void post(int int_num, int index)
+ {
- void clear(int int_num, int index)
- {
+ }
- }
+ void clear(int int_num, int index)
+ {
- void clear_all()
- {
+ }
- }
+ 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;
- }
+ bool check_interrupts(ThreadContext * tc) const
+ {
+ if (numPosted)
+ return true;
+ else
+ return false;
+ }
- }
- } else {
- if (interrupts[trap_level_zero]) {
- if ((pstate & HPSTATE::tlz) && (tc->readMiscReg(MISCREG_TL) == 0)) {
- interrupts[trap_level_zero] = false;
- --numPosted;
- return new TrapLevelZero;
- }
- }
+ 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 (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[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 (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;
+ }
+ 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;
- //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);
}
+ return new InterruptLevelN(il);
}
}
- if (interrupts[resumable_error]) {
- interrupts[resumable_error] = false;
- --numPosted;
- return new ResumableError;
- }
+ }
+ 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 &section)
- {
- }
- };
-}
+ void unserialize(Checkpoint *cp, const std::string &section)
+ {
+ UNSERIALIZE_ARRAY(interrupts,num_interrupt_types);
+ UNSERIALIZE_SCALAR(numPosted);
+ }
+};
+} // namespace SPARC_ISA
#endif // __ARCH_SPARC_INTERRUPT_HH__
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 81443fecb..fb606c7cc 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -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;}});
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index e8762a205..017f43780 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -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)
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index a6dca9bf1..d2ef67154 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -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>
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 0fe3e96b2..8b612e8b4 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -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:
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index ebc8c0e7a..293f667d6 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -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);
}
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index e34ae3731..5108d7338 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -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;
diff --git a/src/dev/sparc/mm_disk.cc b/src/dev/sparc/mm_disk.cc
index 018415f6c..b8cabd0cf 100644
--- a/src/dev/sparc/mm_disk.cc
+++ b/src/dev/sparc/mm_disk.cc
@@ -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,11 +108,74 @@ 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;
Param<Tick> pio_latency;
diff --git a/src/dev/sparc/mm_disk.hh b/src/dev/sparc/mm_disk.hh
index 0a4626067..30028d2b6 100644
--- a/src/dev/sparc/mm_disk.hh
+++ b/src/dev/sparc/mm_disk.hh
@@ -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__