summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/SConscript2
-rw-r--r--src/arch/sparc/faults.cc32
-rw-r--r--src/arch/sparc/intregfile.cc9
-rw-r--r--src/arch/sparc/intregfile.hh12
-rw-r--r--src/arch/sparc/isa/base.isa160
-rw-r--r--src/arch/sparc/isa/decoder.isa65
-rw-r--r--src/arch/sparc/isa/formats/basic.isa3
-rw-r--r--src/arch/sparc/isa/formats/branch.isa12
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa9
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa24
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa30
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa51
-rw-r--r--src/arch/sparc/isa/formats/nop.isa4
-rw-r--r--src/arch/sparc/isa/formats/priv.isa8
-rw-r--r--src/arch/sparc/isa/formats/trap.isa4
-rw-r--r--src/arch/sparc/isa/includes.isa7
-rw-r--r--src/arch/sparc/isa/operands.isa47
-rw-r--r--src/arch/sparc/isa_traits.hh4
-rw-r--r--src/arch/sparc/miscregfile.cc131
-rw-r--r--src/arch/sparc/miscregfile.hh28
-rw-r--r--src/arch/sparc/process.cc18
-rw-r--r--src/arch/sparc/regfile.cc82
-rw-r--r--src/arch/sparc/regfile.hh2
-rw-r--r--src/arch/sparc/sparc_traits.hh3
-rw-r--r--src/arch/sparc/syscallreturn.hh50
-rw-r--r--src/arch/sparc/system.cc7
-rw-r--r--src/arch/sparc/system.hh2
-rw-r--r--src/arch/sparc/tlb.cc5
28 files changed, 500 insertions, 311 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index c2ef97bfa..555bfba3d 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -50,12 +50,12 @@ base_sources = Split('''
intregfile.cc
miscregfile.cc
regfile.cc
+ remote_gdb.cc
''')
# Full-system sources
full_system_sources = Split('''
arguments.cc
- remote_gdb.cc
pagetable.cc
stacktrace.cc
system.cc
diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc
index 825ff40f6..a6f4343ae 100644
--- a/src/arch/sparc/faults.cc
+++ b/src/arch/sparc/faults.cc
@@ -302,10 +302,12 @@ void doREDFault(ThreadContext *tc, TrapType tt)
MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg CANSAVE = tc->readMiscReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscReg(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -387,10 +389,12 @@ void doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
MiscReg TSTATE = tc->readMiscReg(MISCREG_TSTATE);
MiscReg PSTATE = tc->readMiscReg(MISCREG_PSTATE);
MiscReg HPSTATE = tc->readMiscReg(MISCREG_HPSTATE);
- MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ //MiscReg CCR = tc->readMiscReg(MISCREG_CCR);
+ MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
MiscReg ASI = tc->readMiscReg(MISCREG_ASI);
MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
- MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ //MiscReg CANSAVE = tc->readMiscReg(MISCREG_CANSAVE);
+ MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
MiscReg GL = tc->readMiscReg(MISCREG_GL);
MiscReg PC = tc->readPC();
MiscReg NPC = tc->readNextPC();
@@ -656,19 +660,21 @@ void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
- // address is higher than the stack region or in the current stack region
- if (vaddr > p->stack_base || vaddr > p->stack_min)
- FaultBase::invoke(tc);
-
- // We've accessed the next page
- if (vaddr > p->stack_min - PageBytes) {
+ // We've accessed the next page of the stack, so extend the stack
+ // to cover it.
+ if(vaddr < p->stack_min && vaddr >= p->stack_min - PageBytes)
+ {
p->stack_min -= PageBytes;
- if (p->stack_base - p->stack_min > 8*1024*1024)
+ if(p->stack_base - p->stack_min > 8*1024*1024)
fatal("Over max stack size for one thread\n");
p->pTable->allocate(p->stack_min, PageBytes);
warn("Increasing stack size by one page.");
- } else {
- FaultBase::invoke(tc);
+ }
+ // Otherwise, we have an unexpected page fault. Report that fact,
+ // and what address was accessed to cause the fault.
+ else
+ {
+ panic("Page table fault when accessing virtual address %#x\n", vaddr);
}
}
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
index 60856d3fa..2c9d9b162 100644
--- a/src/arch/sparc/intregfile.cc
+++ b/src/arch/sparc/intregfile.cc
@@ -66,6 +66,7 @@ void IntRegFile::clear()
memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame);
for(int x = 0; x < 2 * NWindows; x++)
memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame);
+ memset(regs, 0, sizeof(IntReg) * NumIntRegs);
}
IntRegFile::IntRegFile()
@@ -78,6 +79,8 @@ IntRegFile::IntRegFile()
IntReg IntRegFile::readReg(int intReg)
{
+ DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]);
+ return regs[intReg];
IntReg val;
if(intReg < NumIntArchRegs)
val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
@@ -96,6 +99,12 @@ void IntRegFile::setReg(int intReg, const IntReg &val)
if(intReg)
{
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
+ regs[intReg] = val;
+ }
+ return;
+ if(intReg)
+ {
+ DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
if(intReg < NumIntArchRegs)
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
else if((intReg -= NumIntArchRegs) < NumMicroIntRegs)
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
index d66d0fcb7..665c7aa31 100644
--- a/src/arch/sparc/intregfile.hh
+++ b/src/arch/sparc/intregfile.hh
@@ -34,6 +34,7 @@
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/types.hh"
+#include "base/bitfield.hh"
#include <string>
@@ -47,22 +48,26 @@ namespace SparcISA
std::string getIntRegName(RegIndex);
const int NumIntArchRegs = 32;
- const int NumIntRegs = MaxGL * 8 + NWindows * 16 + NumMicroIntRegs;
+ const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs;
class IntRegFile
{
private:
friend class RegFile;
protected:
+ //The number of bits needed to index into each 8 register frame
static const int FrameOffsetBits = 3;
+ //The number of bits to choose between the 4 sets of 8 registers
static const int FrameNumBits = 2;
+ //The number of registers per "frame" (8)
static const int RegsPerFrame = 1 << FrameOffsetBits;
- static const int FrameNumMask =
+ //A mask to get the frame number
+ static const uint64_t FrameNumMask =
(FrameNumBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameNumBits) - 1;
- static const int FrameOffsetMask =
+ static const uint64_t FrameOffsetMask =
(FrameOffsetBits == sizeof(int)) ?
(unsigned int)(-1) :
(1 << FrameOffsetBits) - 1;
@@ -70,6 +75,7 @@ namespace SparcISA
IntReg regGlobals[MaxGL+1][RegsPerFrame];
IntReg regSegments[2 * NWindows][RegsPerFrame];
IntReg microRegs[NumMicroIntRegs];
+ IntReg regs[NumIntRegs];
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 5b65ec288..58a17f23e 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -189,23 +189,149 @@ output decoder {{
const int MaxOutput = 16;
const int MaxLocal = 24;
const int MaxInput = 32;
- const int MaxMicroReg = 33;
- if (reg == FramePointerReg)
- ccprintf(os, "%%fp");
- else if (reg == StackPointerReg)
- ccprintf(os, "%%sp");
- else if(reg < MaxGlobal)
- ccprintf(os, "%%g%d", reg);
- else if(reg < MaxOutput)
- ccprintf(os, "%%o%d", reg - MaxGlobal);
- else if(reg < MaxLocal)
- ccprintf(os, "%%l%d", reg - MaxOutput);
- else if(reg < MaxInput)
- ccprintf(os, "%%i%d", reg - MaxLocal);
- else if(reg < MaxMicroReg)
- ccprintf(os, "%%u%d", reg - MaxInput);
- else {
- ccprintf(os, "%%f%d", reg - MaxMicroReg);
+ const int MaxMicroReg = 40;
+ if (reg < FP_Base_DepTag) {
+ //If we used a register from the next or previous window,
+ //take out the offset.
+ while (reg >= MaxMicroReg)
+ reg -= MaxMicroReg;
+ if (reg == FramePointerReg)
+ ccprintf(os, "%%fp");
+ else if (reg == StackPointerReg)
+ ccprintf(os, "%%sp");
+ else if(reg < MaxGlobal)
+ ccprintf(os, "%%g%d", reg);
+ else if(reg < MaxOutput)
+ ccprintf(os, "%%o%d", reg - MaxGlobal);
+ else if(reg < MaxLocal)
+ ccprintf(os, "%%l%d", reg - MaxOutput);
+ else if(reg < MaxInput)
+ ccprintf(os, "%%i%d", reg - MaxLocal);
+ else if(reg < MaxMicroReg)
+ ccprintf(os, "%%u%d", reg - MaxInput);
+ //The fake int regs that are really control regs
+ else {
+ switch (reg - MaxMicroReg) {
+ case 1:
+ ccprintf(os, "%%y");
+ break;
+ case 2:
+ ccprintf(os, "%%ccr");
+ break;
+ case 3:
+ ccprintf(os, "%%cansave");
+ break;
+ case 4:
+ ccprintf(os, "%%canrestore");
+ break;
+ case 5:
+ ccprintf(os, "%%cleanwin");
+ break;
+ case 6:
+ ccprintf(os, "%%otherwin");
+ break;
+ case 7:
+ ccprintf(os, "%%wstate");
+ break;
+ }
+ }
+ } else if (reg < Ctrl_Base_DepTag) {
+ ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+ } else {
+ switch (reg - Ctrl_Base_DepTag) {
+ case MISCREG_ASI:
+ ccprintf(os, "%%asi");
+ break;
+ case MISCREG_FPRS:
+ ccprintf(os, "%%fprs");
+ break;
+ case MISCREG_PCR:
+ ccprintf(os, "%%pcr");
+ break;
+ case MISCREG_PIC:
+ ccprintf(os, "%%pic");
+ break;
+ case MISCREG_GSR:
+ ccprintf(os, "%%gsr");
+ break;
+ case MISCREG_SOFTINT:
+ ccprintf(os, "%%softint");
+ break;
+ case MISCREG_SOFTINT_SET:
+ ccprintf(os, "%%softint_set");
+ break;
+ case MISCREG_SOFTINT_CLR:
+ ccprintf(os, "%%softint_clr");
+ break;
+ case MISCREG_TICK_CMPR:
+ ccprintf(os, "%%tick_cmpr");
+ break;
+ case MISCREG_STICK:
+ ccprintf(os, "%%stick");
+ break;
+ case MISCREG_STICK_CMPR:
+ ccprintf(os, "%%stick_cmpr");
+ break;
+ case MISCREG_TPC:
+ ccprintf(os, "%%tpc");
+ break;
+ case MISCREG_TNPC:
+ ccprintf(os, "%%tnpc");
+ break;
+ case MISCREG_TSTATE:
+ ccprintf(os, "%%tstate");
+ break;
+ case MISCREG_TT:
+ ccprintf(os, "%%tt");
+ break;
+ case MISCREG_TICK:
+ ccprintf(os, "%%tick");
+ break;
+ case MISCREG_TBA:
+ ccprintf(os, "%%tba");
+ break;
+ case MISCREG_PSTATE:
+ ccprintf(os, "%%pstate");
+ break;
+ case MISCREG_TL:
+ ccprintf(os, "%%tl");
+ break;
+ case MISCREG_PIL:
+ ccprintf(os, "%%pil");
+ break;
+ case MISCREG_CWP:
+ ccprintf(os, "%%cwp");
+ break;
+ case MISCREG_GL:
+ ccprintf(os, "%%gl");
+ break;
+ case MISCREG_HPSTATE:
+ ccprintf(os, "%%hpstate");
+ break;
+ case MISCREG_HTSTATE:
+ ccprintf(os, "%%htstate");
+ break;
+ case MISCREG_HINTP:
+ ccprintf(os, "%%hintp");
+ break;
+ case MISCREG_HTBA:
+ ccprintf(os, "%%htba");
+ break;
+ case MISCREG_HSTICK_CMPR:
+ ccprintf(os, "%%hstick_cmpr");
+ break;
+ case MISCREG_HVER:
+ ccprintf(os, "%%hver");
+ break;
+ case MISCREG_STRAND_STS_REG:
+ ccprintf(os, "%%strand_sts_reg");
+ break;
+ case MISCREG_FSR:
+ ccprintf(os, "%%fsr");
+ break;
+ default:
+ ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
+ }
}
}
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 32256a04e..cc6eded1d 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -76,9 +76,15 @@ decode OP default Unknown::unknown()
}});
0x2: bpccx(19, {{
if(passesCondition(Ccr<7:4>, COND2))
+ {
+ //warn("Took branch!\n");
NNPC = xc->readPC() + disp;
+ }
else
+ {
+ //warn("Didn't take branch!\n");
handle_annul
+ }
}});
}
}
@@ -249,16 +255,14 @@ decode OP default Unknown::unknown()
{{((Rs1 & val2) | (~resTemp & (Rs1 | val2)))<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
- 0x1A: umulcc({{
+ 0x1A: IntOpCcRes::umulcc({{
uint64_t resTemp;
Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>;
- Y = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});
- 0x1B: smulcc({{
+ Y = resTemp<63:32>;}});
+ 0x1B: IntOpCcRes::smulcc({{
int64_t resTemp;
Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
- Y = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});
+ Y = resTemp<63:32>;}});
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
@@ -268,10 +272,9 @@ decode OP default Unknown::unknown()
{{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<63:>}},
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
);
- 0x1D: udivxcc({{
+ 0x1D: IntOpCcRes::udivxcc({{
if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
- else Rd = Rs1.udw / Rs2_or_imm13.udw;}}
- ,{{0}},{{0}},{{0}},{{0}});
+ else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
0x1E: udivcc({{
uint32_t resTemp, val2 = Rs2_or_imm13.udw;
int32_t overflow = 0;
@@ -888,16 +891,11 @@ decode OP default Unknown::unknown()
}
}});
0x39: Branch::return({{
- //If both MemAddressNotAligned and
- //a fill trap happen, it's not clear
- //which one should be returned.
Addr target = Rs1 + Rs2_or_imm13;
- if(target & 0x3)
- fault = new MemAddressNotAligned;
- else
- NNPC = target;
if(fault == NoFault)
{
+ //Check for fills which are higher priority than alignment
+ //faults.
if(Canrestore == 0)
{
if(Otherwin)
@@ -905,18 +903,15 @@ decode OP default Unknown::unknown()
else
fault = new FillNNormal(4*Wstate<2:0>);
}
+ //Check for alignment faults
+ else if(target & 0x3)
+ fault = new MemAddressNotAligned;
else
{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
+ NNPC = target;
Cwp = (Cwp - 1 + NWindows) % NWindows;
Cansave = Cansave + 1;
Canrestore = Canrestore - 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}
}});
@@ -934,7 +929,7 @@ decode OP default Unknown::unknown()
xc->syscall(R1);
#endif
}
- }});
+ }}, IsSerializeAfter, IsNonSpeculative);
0x2: Trap::tccx({{
if(passesCondition(Ccr<7:4>, COND2))
{
@@ -947,36 +942,27 @@ decode OP default Unknown::unknown()
xc->syscall(R1);
#endif
}
- }});
+ }}, IsSerializeAfter, IsNonSpeculative);
}
0x3B: Nop::flush({{/*Instruction memory flush*/}});
0x3C: save({{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
if(Cansave == 0)
{
if(Otherwin)
fault = new SpillNOther(4*Wstate<5:3>);
else
fault = new SpillNNormal(4*Wstate<2:0>);
- //Cwp = (Cwp + 2) % NWindows;
}
else if(Cleanwin - Canrestore == 0)
{
- //Cwp = (Cwp + 1) % NWindows;
fault = new CleanWindow;
}
else
{
Cwp = (Cwp + 1) % NWindows;
- Rd = Rs1 + Rs2_or_imm13;
+ Rd_next = Rs1 + Rs2_or_imm13;
Cansave = Cansave - 1;
Canrestore = Canrestore + 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}});
0x3D: restore({{
@@ -989,17 +975,10 @@ decode OP default Unknown::unknown()
}
else
{
- //CWP should be set directly so that it always happens
- //Also, this will allow writing to the new window and
- //reading from the old one
Cwp = (Cwp - 1 + NWindows) % NWindows;
- Rd = Rs1 + Rs2_or_imm13;
+ Rd_prev = Rs1 + Rs2_or_imm13;
Cansave = Cansave + 1;
Canrestore = Canrestore - 1;
- //This is here to make sure the CWP is written
- //no matter what. This ensures that the results
- //are written in the new window as well.
- xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
}
}});
0x3E: decode FCN {
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 56b201bd6..e8762a205 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -97,8 +97,7 @@ def template BasicDecodeWithMnemonic {{
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
- iop = InstObjParams(name, Name, 'SparcStaticInst',
- CodeBlock(code), flags)
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 5fb7ade2d..2db756320 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -170,7 +170,7 @@ output decoder {{
printMnemonic(response, mnemonic);
ccprintf(response, "0x%x", target);
- if(symtab->findNearestSymbol(target, symbol, symbolAddr))
+ if(symtab && symtab->findNearestSymbol(target, symbol, symbolAddr))
{
ccprintf(response, " <%s", symbol);
if(symbolAddr != target)
@@ -178,6 +178,10 @@ output decoder {{
else
ccprintf(response, ">");
}
+ else
+ {
+ ccprintf(response, "<%d>", target);
+ }
return response.str();
}
@@ -244,7 +248,6 @@ def format Branch(code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
new_opt_flags = []
for flag in opt_flags:
if flag == ',a':
@@ -252,7 +255,7 @@ def format BranchN(bits, code, *opt_flags) {{
Name += 'Annul'
else:
new_opt_flags += flag
- iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, new_opt_flags)
+ iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
@@ -262,8 +265,7 @@ def format BranchN(bits, code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchSplit(code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 9470fc55f..f877b8790 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -263,14 +263,15 @@ let {{
def doIntFormat(code, ccCode, name, Name, opt_flags):
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
- iop = InstObjParams(name, Name, 'IntOp', code,
- opt_flags, {"cc_code": ccCode})
+ iop = InstObjParams(name, Name, 'IntOp',
+ {"code": code, "cc_code": ccCode},
+ opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
- immCode, opt_flags, {"cc_code": ccCode})
+ {"code": immCode, "cc_code": ccCode}, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
@@ -341,7 +342,7 @@ def format IntOpCcRes(code, *opt_flags) {{
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
- code, opt_flags, {"cc_code": ''})
+ {"code": code, "cc_code": ''}, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index 55e9fba45..1d9075a57 100644
--- a/src/arch/sparc/isa/formats/mem/basicmem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -55,16 +55,20 @@ let {{
def doMemFormat(code, execute, faultCode, name, Name, asi, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
- iop = InstObjParams(name, Name, 'Mem', code,
- opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
- iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
- opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
+ iop = InstObjParams(name, Name, 'Mem',
+ {"code": code, "fault_check": faultCode,
+ "ea_code": addrCalcReg},
+ opt_flags)
+ iop_imm = InstObjParams(name, Name + "Imm", 'MemImm',
+ {"code": code, "fault_check": faultCode,
+ "ea_code": addrCalcImm},
+ opt_flags)
header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm,
- execute, faultCode, name, name + "Imm", Name, Name + "Imm",
- asi, opt_flags)
+ execute, faultCode, name, name + "Imm",
+ Name, Name + "Imm", asi, opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
@@ -72,7 +76,7 @@ def format LoadAlt(code, asi, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, LoadExecute,
+ decode_block) = doMemFormat(code, LoadFuncs,
AlternateASIPrivFaultCheck, name, Name, asi, opt_flags)
}};
@@ -80,7 +84,7 @@ def format StoreAlt(code, asi, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, StoreExecute,
+ decode_block) = doMemFormat(code, StoreFuncs,
AlternateASIPrivFaultCheck, name, Name, asi, opt_flags)
}};
@@ -89,7 +93,7 @@ def format Load(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- LoadExecute, '', name, Name, 0, opt_flags)
+ LoadFuncs, '', name, Name, 0, opt_flags)
}};
def format Store(code, *opt_flags) {{
@@ -97,5 +101,5 @@ def format Store(code, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- StoreExecute, '', name, Name, 0, opt_flags)
+ StoreFuncs, '', name, Name, 0, opt_flags)
}};
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
index c36fede2e..9795d2342 100644
--- a/src/arch/sparc/isa/formats/mem/blockmem.isa
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -456,14 +456,14 @@ let {{
else:
flag_code = "flags[IsDelayedCommit] = true;"
pcedCode = matcher.sub("Frd_%d" % microPc, code)
- iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
- opt_flags, {"ea_code": addrCalcReg,
+ iop = InstObjParams(name, Name, 'BlockMem',
+ {"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
- iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
- opt_flags, {"ea_code": addrCalcImm,
+ "set_flags": flag_code}, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm',
+ {"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
+ "set_flags": flag_code}, opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
@@ -496,18 +496,18 @@ let {{
else:
flag_code = "flags[IsDelayedCommit] = true; flags[IsFirstMicroOp] = true;"
pcedCode = matcher.sub("uReg0", code)
- iop = InstObjParams(name, Name, 'TwinMem', pcedCode,
- opt_flags, {"ea_code": addrCalcReg,
+ iop = InstObjParams(name, Name, 'TwinMem',
+ {"code": pcedCode, "ea_code": addrCalcReg,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
- iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm', pcedCode,
- opt_flags, {"ea_code": addrCalcImm,
+ "set_flags": flag_code}, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'TwinMemImm',
+ {"code": pcedCode, "ea_code": addrCalcImm,
"fault_check": faultCode, "micro_pc": microPc,
- "set_flags": flag_code})
+ "set_flags": flag_code}, opt_flags)
decoder_output += BlockMemMicroConstructor.subst(iop)
decoder_output += BlockMemMicroConstructor.subst(iop_imm)
exec_output += doDualSplitExecute(
- pcedCode, addrCalcReg, addrCalcImm, LoadExecute, faultCode,
+ pcedCode, addrCalcReg, addrCalcImm, LoadFuncs, faultCode,
makeMicroName(name, microPc),
makeMicroName(name + "Imm", microPc),
makeMicroName(Name, microPc),
@@ -527,7 +527,7 @@ def format BlockLoad(code, asi, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
- LoadExecute, name, Name, asi, opt_flags)
+ LoadFuncs, name, Name, asi, opt_flags)
}};
def format BlockStore(code, asi, *opt_flags) {{
@@ -539,7 +539,7 @@ def format BlockStore(code, asi, *opt_flags) {{
decoder_output,
exec_output,
decode_block) = doBlockMemFormat(code, faultCode,
- StoreExecute, name, Name, asi, opt_flags)
+ StoreFuncs, name, Name, asi, opt_flags)
}};
def format TwinLoad(code, asi, *opt_flags) {{
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
index 3b02f58de..dbaabdca4 100644
--- a/src/arch/sparc/isa/formats/mem/util.isa
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -145,7 +145,7 @@ def template LoadExecute {{
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -163,17 +163,19 @@ def template LoadExecute {{
return fault;
}
+}};
+def template LoadInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
Addr EA;
- uint%(mem_acc_size)s_t Mem;
%(fp_enable_check)s;
- %(ea_decl)s;
- %(ea_rd)s;
+ %(op_decl)s;
+ %(op_rd)s;
%(ea_code)s;
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -181,18 +183,20 @@ def template LoadExecute {{
}
return fault;
}
+}};
+def template LoadCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
Fault fault = NoFault;
- %(code_decl)s;
- %(code_rd)s;
+ %(op_decl)s;
+ %(op_rd)s;
Mem = pkt->get<typeof(Mem)>();
%(code)s;
if(fault == NoFault)
{
- %(code_wb)s;
+ %(op_wb)s;
}
return fault;
}
@@ -212,7 +216,7 @@ def template StoreExecute {{
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -231,7 +235,9 @@ def template StoreExecute {{
return fault;
}
+}};
+def template StoreInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
@@ -242,7 +248,7 @@ def template StoreExecute {{
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ DPRINTF(Sparc, "%s: The address is 0x%x\n", mnemonic, EA);
%(fault_check)s;
if(fault == NoFault)
{
@@ -260,7 +266,9 @@ def template StoreExecute {{
}
return fault;
}
+}};
+def template StoreCompleteAcc {{
Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
Trace::InstRecord * traceData) const
{
@@ -280,6 +288,8 @@ def template CompleteAccDeclare {{
//Here are some code snippets which check for various fault conditions
let {{
+ LoadFuncs = [LoadExecute, LoadInitiateAcc, LoadCompleteAcc]
+ StoreFuncs = [StoreExecute, StoreInitiateAcc, StoreCompleteAcc]
# The LSB can be zero, since it's really the MSB in doubles and quads
# and we're dealing with doubles
BlockAlignmentFaultCheck = '''
@@ -320,21 +330,11 @@ let {{
//and in the other they're distributed across two. Also note that for
//execute functions, the name of the base class doesn't matter.
let {{
- def doSplitExecute(code, execute, name, Name, asi, opt_flags, microParam):
+ def doSplitExecute(execute, name, Name, asi, opt_flags, microParam):
microParam["asi_val"] = asi;
- codeParam = microParam.copy()
- codeParam["ea_code"] = ''
- codeIop = InstObjParams(name, Name, '', code, opt_flags, codeParam)
- eaIop = InstObjParams(name, Name, '', microParam["ea_code"],
- opt_flags, microParam)
- iop = InstObjParams(name, Name, '', code, opt_flags, microParam)
- (iop.ea_decl,
- iop.ea_rd,
- iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
- (iop.code_decl,
- iop.code_rd,
- iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
- return execute.subst(iop)
+ iop = InstObjParams(name, Name, '', microParam, opt_flags)
+ (execf, initf, compf) = execute
+ return execf.subst(iop) + initf.subst(iop) + compf.subst(iop)
def doDualSplitExecute(code, eaRegCode, eaImmCode, execute,
@@ -343,8 +343,9 @@ let {{
for (eaCode, name, Name) in (
(eaRegCode, nameReg, NameReg),
(eaImmCode, nameImm, NameImm)):
- microParams = {"ea_code" : eaCode, "fault_check": faultCode}
- executeCode += doSplitExecute(code, execute, name, Name,
+ microParams = {"code": code, "ea_code": eaCode,
+ "fault_check": faultCode}
+ executeCode += doSplitExecute(execute, name, Name,
asi, opt_flags, microParams)
return executeCode
}};
diff --git a/src/arch/sparc/isa/formats/nop.isa b/src/arch/sparc/isa/formats/nop.isa
index 37ef2e8d0..de2ba2f54 100644
--- a/src/arch/sparc/isa/formats/nop.isa
+++ b/src/arch/sparc/isa/formats/nop.isa
@@ -88,9 +88,7 @@ def template NopExecute {{
// Primary format for integer operate instructions:
def format Nop(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Nop', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'Nop', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 3d47ca02f..36403afb4 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -235,8 +235,9 @@ let {{
name = mnem
regBase = 'WrPriv'
break
- iop = InstObjParams(name, Name, regBase, code,
- opt_flags, {"check": checkCode, "reg_name": regName})
+ iop = InstObjParams(name, Name, regBase,
+ {"code": code, "check": checkCode, "reg_name": regName},
+ opt_flags)
header_output = BasicDeclare.subst(iop)
if regName == '':
decoder_output = BasicConstructor.subst(iop)
@@ -245,7 +246,8 @@ let {{
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm',
- immCode, opt_flags, {"check": checkCode, "reg_name": regName})
+ {"code": immCode, "check": checkCode, "reg_name": regName},
+ opt_flags)
header_output += BasicDeclare.subst(imm_iop)
if regName == '':
decoder_output += BasicConstructor.subst(imm_iop)
diff --git a/src/arch/sparc/isa/formats/trap.isa b/src/arch/sparc/isa/formats/trap.isa
index 04d467cfe..9c118b227 100644
--- a/src/arch/sparc/isa/formats/trap.isa
+++ b/src/arch/sparc/isa/formats/trap.isa
@@ -83,9 +83,7 @@ def template TrapExecute {{
}};
def format Trap(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Trap', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'Trap', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 5d90fbdd2..474af3ad9 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -38,12 +38,13 @@ output header {{
#include <sstream>
#include <iostream>
-#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
-#include "mem/request.hh" // some constructors use MemReq flags
-#include "mem/packet.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/regfile.hh"
+#include "base/misc.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
+#include "mem/request.hh" // some constructors use MemReq flags
}};
output decoder {{
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index abb82f88c..2d1c3d3b9 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -56,15 +56,26 @@ def operands {{
# Int regs default to unsigned, but code should not count on this.
# For clarity, descriptions that depend on unsigned behavior should
# explicitly specify '.uq'.
+
'Rd': ('IntReg', 'udw', 'RD', 'IsInteger', 1),
+ # The Rd from the previous window
+ 'Rd_prev': ('IntReg', 'udw', 'RD + NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 2),
+ # The Rd from the next window
+ 'Rd_next': ('IntReg', 'udw', 'RD + 2 * NumIntArchRegs + NumMicroIntRegs', 'IsInteger', 3),
# For microcoded twin load instructions, RdTwin appears in the "code"
- # for the instruction and is replaced by RdLow or RdHigh by the format
+ # for the instruction is replaced by RdLow or RdHigh by the format
# before it's processed by the iop.
- 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 2),
- 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
- 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
- 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 6),
+ # The low (even) register of a two register pair
+ 'RdLow': ('IntReg', 'udw', 'RD & (~1)', 'IsInteger', 4),
+ # The high (odd) register of a two register pair
+ 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 5),
+ 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 6),
+ 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 7),
+ # A microcode register. Right now, this is the only one.
+ 'uReg0': ('IntReg', 'udw', 'NumIntArchRegs', 'IsInteger', 8),
+ # Because double and quad precision register numbers are decoded
+ # differently, they get different operands. The single precision versions
+ # have an s post pended to their name.
'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
# Each Frd_N refers to the Nth double precision register from Frd.
@@ -83,14 +94,17 @@ def operands {{
'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
+ # Registers which are used explicitly in instructions
'R0': ('IntReg', 'udw', '0', None, 6),
'R1': ('IntReg', 'udw', '1', None, 7),
'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
- 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
- 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+# 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
+# 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+ 'Y': ('IntReg', 'udw', 'NumIntArchRegs + 1', None, 40),
+ 'Ccr': ('IntReg', 'udw', 'NumIntArchRegs + 2', None, 41),
'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43),
'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44),
@@ -112,12 +126,17 @@ def operands {{
'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59),
'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60),
'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 62),
+# 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63),
+# 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64),
+# 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65),
+# 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66),
+# 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67),
+ 'Cansave': ('IntReg', 'udw', 'NumIntArchRegs + 3', None, 63),
+ 'Canrestore': ('IntReg', 'udw', 'NumIntArchRegs + 4', None, 64),
+ 'Cleanwin': ('IntReg', 'udw', 'NumIntArchRegs + 5', None, 65),
+ 'Otherwin': ('IntReg', 'udw', 'NumIntArchRegs + 6', None, 66),
+ 'Wstate': ('IntReg', 'udw', 'NumIntArchRegs + 7', None, 67),
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68),
'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69),
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 062cc8dd3..64ae6abd8 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -58,8 +58,8 @@ namespace SparcISA
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
- FP_Base_DepTag = 33,
- Ctrl_Base_DepTag = 97
+ FP_Base_DepTag = 32*3+8,
+ Ctrl_Base_DepTag = FP_Base_DepTag + 64
};
// semantically meaningful register indices
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index d9fcb0280..422bc2fbe 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -46,15 +46,16 @@ class Checkpoint;
string SparcISA::getMiscRegName(RegIndex index)
{
static::string miscRegName[NumMiscRegs] =
- {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic",
- "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
- "stick", "stick_cmpr",
- "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
- "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
- "wstate", "gl",
- "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
- "hstick_cmpr",
- "fsr"};
+ {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate",*/ "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr"};
+
return miscRegName[index];
}
@@ -65,8 +66,8 @@ enum RegMask
void MiscRegFile::clear()
{
- y = 0;
- ccr = 0;
+ //y = 0;
+ //ccr = 0;
asi = 0;
tick = ULL(1) << 63;
fprs = 0;
@@ -83,11 +84,11 @@ void MiscRegFile::clear()
tl = 0;
pil = 0;
cwp = 0;
- cansave = 0;
- canrestore = 0;
- cleanwin = 0;
- otherwin = 0;
- wstate = 0;
+ //cansave = 0;
+ //canrestore = 0;
+ //cleanwin = 0;
+ //otherwin = 0;
+ //wstate = 0;
gl = 0;
//In a T1, bit 11 is apparently always 1
hpstate = (1 << 11);
@@ -149,10 +150,10 @@ MiscReg MiscRegFile::readReg(int miscReg)
(uint64_t)priContext << 32 |
(uint64_t)secContext << 48;
- case MISCREG_Y:
- return y;
- case MISCREG_CCR:
- return ccr;
+ //case MISCREG_Y:
+ // return y;
+ //case MISCREG_CCR:
+ // return ccr;
case MISCREG_ASI:
return asi;
case MISCREG_FPRS:
@@ -195,16 +196,16 @@ MiscReg MiscRegFile::readReg(int miscReg)
return pil;
case MISCREG_CWP:
return cwp;
- case MISCREG_CANSAVE:
- return cansave;
- case MISCREG_CANRESTORE:
- return canrestore;
- case MISCREG_CLEANWIN:
- return cleanwin;
- case MISCREG_OTHERWIN:
- return otherwin;
- case MISCREG_WSTATE:
- return wstate;
+ //case MISCREG_CANSAVE:
+ // return cansave;
+ //case MISCREG_CANRESTORE:
+ // return canrestore;
+ //case MISCREG_CLEANWIN:
+ // return cleanwin;
+ //case MISCREG_OTHERWIN:
+ // return otherwin;
+ //case MISCREG_WSTATE:
+ // return wstate;
case MISCREG_GL:
return gl;
@@ -375,12 +376,12 @@ MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
void MiscRegFile::setReg(int miscReg, const MiscReg &val)
{
switch (miscReg) {
- case MISCREG_Y:
- y = val;
- break;
- case MISCREG_CCR:
- ccr = val;
- break;
+// case MISCREG_Y:
+// y = val;
+// break;
+// case MISCREG_CCR:
+// ccr = val;
+// break;
case MISCREG_ASI:
asi = val;
break;
@@ -441,21 +442,21 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
case MISCREG_CWP:
cwp = val;
break;
- case MISCREG_CANSAVE:
- cansave = val;
- break;
- case MISCREG_CANRESTORE:
- canrestore = val;
- break;
- case MISCREG_CLEANWIN:
- cleanwin = val;
- break;
- case MISCREG_OTHERWIN:
- otherwin = val;
- break;
- case MISCREG_WSTATE:
- wstate = val;
- break;
+// case MISCREG_CANSAVE:
+// cansave = val;
+// break;
+// case MISCREG_CANRESTORE:
+// canrestore = val;
+// break;
+// case MISCREG_CLEANWIN:
+// cleanwin = val;
+// break;
+// case MISCREG_OTHERWIN:
+// otherwin = val;
+// break;
+// case MISCREG_WSTATE:
+// wstate = val;
+// break;
case MISCREG_GL:
gl = val;
break;
@@ -676,23 +677,23 @@ void MiscRegFile::serialize(std::ostream & os)
{
SERIALIZE_SCALAR(pstate);
SERIALIZE_SCALAR(tba);
- SERIALIZE_SCALAR(y);
+// SERIALIZE_SCALAR(y);
SERIALIZE_SCALAR(pil);
SERIALIZE_SCALAR(gl);
SERIALIZE_SCALAR(cwp);
SERIALIZE_ARRAY(tt, MaxTL);
- SERIALIZE_SCALAR(ccr);
+// SERIALIZE_SCALAR(ccr);
SERIALIZE_SCALAR(asi);
SERIALIZE_SCALAR(tl);
SERIALIZE_ARRAY(tpc, MaxTL);
SERIALIZE_ARRAY(tnpc, MaxTL);
SERIALIZE_ARRAY(tstate, MaxTL);
SERIALIZE_SCALAR(tick);
- SERIALIZE_SCALAR(cansave);
- SERIALIZE_SCALAR(canrestore);
- SERIALIZE_SCALAR(otherwin);
- SERIALIZE_SCALAR(cleanwin);
- SERIALIZE_SCALAR(wstate);
+// SERIALIZE_SCALAR(cansave);
+// SERIALIZE_SCALAR(canrestore);
+// SERIALIZE_SCALAR(otherwin);
+// SERIALIZE_SCALAR(cleanwin);
+// SERIALIZE_SCALAR(wstate);
SERIALIZE_SCALAR(fsr);
SERIALIZE_SCALAR(fprs);
SERIALIZE_SCALAR(hpstate);
@@ -735,23 +736,23 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
{
UNSERIALIZE_SCALAR(pstate);
UNSERIALIZE_SCALAR(tba);
- UNSERIALIZE_SCALAR(y);
+// UNSERIALIZE_SCALAR(y);
UNSERIALIZE_SCALAR(pil);
UNSERIALIZE_SCALAR(gl);
UNSERIALIZE_SCALAR(cwp);
UNSERIALIZE_ARRAY(tt, MaxTL);
- UNSERIALIZE_SCALAR(ccr);
+// UNSERIALIZE_SCALAR(ccr);
UNSERIALIZE_SCALAR(asi);
UNSERIALIZE_SCALAR(tl);
UNSERIALIZE_ARRAY(tpc, MaxTL);
UNSERIALIZE_ARRAY(tnpc, MaxTL);
UNSERIALIZE_ARRAY(tstate, MaxTL);
UNSERIALIZE_SCALAR(tick);
- UNSERIALIZE_SCALAR(cansave);
- UNSERIALIZE_SCALAR(canrestore);
- UNSERIALIZE_SCALAR(otherwin);
- UNSERIALIZE_SCALAR(cleanwin);
- UNSERIALIZE_SCALAR(wstate);
+// UNSERIALIZE_SCALAR(cansave);
+// UNSERIALIZE_SCALAR(canrestore);
+// UNSERIALIZE_SCALAR(otherwin);
+// UNSERIALIZE_SCALAR(cleanwin);
+// UNSERIALIZE_SCALAR(wstate);
UNSERIALIZE_SCALAR(fsr);
UNSERIALIZE_SCALAR(fprs);
UNSERIALIZE_SCALAR(hpstate);
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 8a2e8e810..66c9f17df 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -47,8 +47,8 @@ namespace SparcISA
enum MiscRegIndex
{
/** Ancillary State Registers */
- MISCREG_Y, /* 0 */
- MISCREG_CCR,
+// MISCREG_Y,
+// MISCREG_CCR,
MISCREG_ASI,
MISCREG_TICK,
MISCREG_FPRS,
@@ -73,11 +73,11 @@ namespace SparcISA
MISCREG_TL,
MISCREG_PIL,
MISCREG_CWP,
- MISCREG_CANSAVE,
- MISCREG_CANRESTORE,
- MISCREG_CLEANWIN,
- MISCREG_OTHERWIN,
- MISCREG_WSTATE,
+// MISCREG_CANSAVE,
+// MISCREG_CANRESTORE,
+// MISCREG_CLEANWIN,
+// MISCREG_OTHERWIN,
+// MISCREG_WSTATE,
MISCREG_GL,
/** Hyper privileged registers */
@@ -171,8 +171,8 @@ namespace SparcISA
private:
/* ASR Registers */
- uint64_t y; // Y (used in obsolete multiplication)
- uint8_t ccr; // Condition Code Register
+ //uint64_t y; // Y (used in obsolete multiplication)
+ //uint8_t ccr; // Condition Code Register
uint8_t asi; // Address Space Identifier
uint64_t tick; // Hardware clock-tick counter
uint8_t fprs; // Floating-Point Register State
@@ -197,11 +197,11 @@ namespace SparcISA
uint8_t tl; // Trap Level
uint8_t pil; // Process Interrupt Register
uint8_t cwp; // Current Window Pointer
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t cleanwin; // Clean windows
- uint8_t otherwin; // Other windows
- uint8_t wstate; // Window State
+ //uint8_t cansave; // Savable windows
+ //uint8_t canrestore; // Restorable windows
+ //uint8_t cleanwin; // Clean windows
+ //uint8_t otherwin; // Other windows
+ //uint8_t wstate; // Window State
uint8_t gl; // Global level register
/** Hyperprivileged Registers */
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 405e408e5..1e639b9a5 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -95,17 +95,22 @@ SparcLiveProcess::startup()
*/
//No windows contain info from other programs
- threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0);
//There are no windows to pop
- threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0);
//All windows are available to save into
- threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2);
+ //threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2);
//All windows are "clean"
- threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows);
+ //threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows);
//Start with register window 0
threadContexts[0]->setMiscReg(MISCREG_CWP, 0);
//Always use spill and fill traps 0
- threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
+ //threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0);
+ threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0);
//Set the trap level to 0
threadContexts[0]->setMiscReg(MISCREG_TL, 0);
//Set the ASI register to something fixed
@@ -427,5 +432,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst));
threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst)));
+ //Align the "stack_min" to a page boundary.
+ stack_min = roundDown(stack_min, pageSize);
+
// num_processes++;
}
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
index b36133544..d39892e73 100644
--- a/src/arch/sparc/regfile.cc
+++ b/src/arch/sparc/regfile.cc
@@ -151,6 +151,74 @@ void RegFile::setIntReg(int intReg, const IntReg &val)
intRegFile.setReg(intReg, val);
}
+int SparcISA::flattenIntIndex(ThreadContext * tc, int reg)
+{
+ int gl = tc->readMiscReg(MISCREG_GL);
+ int cwp = tc->readMiscReg(MISCREG_CWP);
+ //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
+ int newReg;
+ //The total number of global registers
+ int numGlobals = (MaxGL + 1) * 8;
+ if(reg < 8)
+ {
+ //Global register
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else if(reg < NumIntArchRegs)
+ {
+ //Regular windowed register
+ //Put it in the window pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ else if(reg < NumIntArchRegs + NumMicroIntRegs)
+ {
+ //Microcode register
+ //Displace from the end of the regular registers
+ newReg = reg - NumIntArchRegs + numGlobals + NWindows * 16;
+ }
+ else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs)
+ {
+ reg -= (NumIntArchRegs + NumMicroIntRegs);
+ if(reg < 8)
+ {
+ //Global register from the next window
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else
+ {
+ //Windowed register from the previous window
+ //Put it in the window before the one pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ }
+ else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs)
+ {
+ reg -= (2 * NumIntArchRegs + NumMicroIntRegs);
+ if(reg < 8)
+ {
+ //Global register from the previous window
+ //Put it in the appropriate set of globals
+ newReg = reg + gl * 8;
+ }
+ else
+ {
+ //Windowed register from the next window
+ //Put it in the window after the one pointed to by cwp
+ newReg = numGlobals +
+ ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16));
+ }
+ }
+ else
+ panic("Tried to flatten invalid register index %d!\n", reg);
+ DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg);
+ return newReg;
+ //return intRegFile.flattenIndex(reg);
+}
+
void RegFile::serialize(std::ostream &os)
{
intRegFile.serialize(os);
@@ -220,8 +288,8 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
// ASRs
- dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
- dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
+// dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
+// dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
@@ -236,11 +304,11 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
- dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
- dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
- dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
- dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
- dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
+// dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
+// dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
+// dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
+// dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
+// dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
// Hyperprivilged registers
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index 0a09d0f66..d9af0757c 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -120,6 +120,8 @@ namespace SparcISA
void changeContext(RegContextParam param, RegContextVal val);
};
+ int flattenIntIndex(ThreadContext * tc, int reg);
+
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh
index a3d29ea8a..d89ec1119 100644
--- a/src/arch/sparc/sparc_traits.hh
+++ b/src/arch/sparc/sparc_traits.hh
@@ -41,7 +41,8 @@ namespace SparcISA
// Number of register windows, can legally be 3 to 32
const int NWindows = 8;
- const int NumMicroIntRegs = 1;
+ //const int NumMicroIntRegs = 1;
+ const int NumMicroIntRegs = 8;
// const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16;
// const int NumMicroIntRegs = 1;
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
index 75a063da1..d92b12790 100644
--- a/src/arch/sparc/syscallreturn.hh
+++ b/src/arch/sparc/syscallreturn.hh
@@ -33,58 +33,30 @@
#include <inttypes.h>
+#include "sim/syscallreturn.hh"
#include "arch/sparc/regfile.hh"
-
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
+#include "cpu/thread_context.hh"
namespace SparcISA
{
static inline void setSyscallReturn(SyscallReturn return_value,
- RegFile *regs)
+ ThreadContext * tc)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error, clear XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEE);
- regs->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) & 0xEE);
+ //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) & 0xEE);
+ tc->setIntReg(ReturnValueReg, return_value.value());
} else {
// got an error, set XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x11);
- regs->setIntReg(ReturnValueReg, return_value.value());
+ tc->setIntReg(NumIntArchRegs + 2,
+ tc->readIntReg(NumIntArchRegs + 2) | 0x11);
+ //tc->setMiscReg(MISCREG_CCR, tc->readMiscReg(MISCREG_CCR) | 0x11);
+ tc->setIntReg(ReturnValueReg, -return_value.value());
}
}
};
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index 800d47c15..2600213fd 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -191,13 +191,6 @@ SparcSystem::~SparcSystem()
delete partition_desc;
}
-bool
-SparcSystem::breakpoint()
-{
- panic("Need to implement");
- M5_DUMMY_RETURN
-}
-
void
SparcSystem::serialize(std::ostream &os)
{
diff --git a/src/arch/sparc/system.hh b/src/arch/sparc/system.hh
index c81b093e8..ac4d34279 100644
--- a/src/arch/sparc/system.hh
+++ b/src/arch/sparc/system.hh
@@ -68,8 +68,6 @@ class SparcSystem : public System
~SparcSystem();
- virtual bool breakpoint();
-
/**
* Serialization stuff
*/
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 6ed6f59b6..bc3c39294 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -176,8 +176,6 @@ insertAllLocked:
lookupTable.erase(new_entry->range);
- DPRINTF(TLB, "Using entry: %#X\n", new_entry);
-
assert(PTE.valid());
new_entry->range.va = va;
new_entry->range.size = PTE.size() - 1;
@@ -287,7 +285,6 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
usedEntries--;
}
freeList.push_front(i->second);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", i->second);
lookupTable.erase(i);
}
}
@@ -304,7 +301,6 @@ TLB::demapContext(int partition_id, int context_id)
tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true) {
freeList.push_front(&tlb[x]);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {
@@ -326,7 +322,6 @@ TLB::demapAll(int partition_id)
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
if (tlb[x].valid == true){
freeList.push_front(&tlb[x]);
- DPRINTF(TLB, "Freeing TLB entry : %#X\n", &tlb[x]);
}
tlb[x].valid = false;
if (tlb[x].used) {