summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/isa/base.isa32
-rw-r--r--src/arch/sparc/isa/decoder.isa198
-rw-r--r--src/arch/sparc/isa/formats/basic.isa6
-rw-r--r--src/arch/sparc/isa/formats/branch.isa109
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa145
-rw-r--r--src/arch/sparc/isa/formats/priv.isa20
-rw-r--r--src/arch/sparc/isa/includes.isa6
-rw-r--r--src/arch/sparc/isa/operands.isa44
-rw-r--r--src/arch/sparc/regfile.hh29
9 files changed, 323 insertions, 266 deletions
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 02f7cf61a..b518265aa 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -86,6 +86,11 @@ output header {{
const SymbolTable *symtab) const;
void printReg(std::ostream &os, int reg) const;
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+
+ void printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const;
};
bool passesCondition(uint32_t codes, uint32_t condition);
@@ -150,6 +155,33 @@ output decoder {{
ccprintf(os, "\t%s ", mnemonic);
}
+ void SparcStaticInst::printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const
+ {
+ if(num <= 0)
+ return;
+ printReg(os, indexArray[0]);
+ for(int x = 1; x < num; x++)
+ {
+ os << ", ";
+ printReg(os, indexArray[x]);
+ }
+ }
+
+ void
+ SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
+ {
+ if(_numSrcRegs > reg)
+ printReg(os, _srcRegIdx[reg]);
+ }
+
+ void
+ SparcStaticInst::printDestReg(std::ostream &os, int reg) const
+ {
+ if(_numDestRegs > reg)
+ printReg(os, _destRegIdx[reg]);
+ }
+
void
SparcStaticInst::printReg(std::ostream &os, int reg) const
{
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index fa8832920..274d51fc5 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -39,30 +39,30 @@ decode OP default Unknown::unknown()
{
//Throw an illegal instruction acception
0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
- 0x1: decode BPCC
+ format BranchN
{
- format Branch19
+ 0x1: decode BPCC
{
- 0x0: bpcci({{
+ 0x0: bpcci(19, {{
if(passesCondition(Ccr<3:0>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x2: bpccx({{
+ 0x2: bpccx(19, {{
if(passesCondition(Ccr<7:4>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
}
+ 0x2: bicc(22, {{
+ if(passesCondition(Ccr<3:0>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
}
- 0x2: Branch22::bicc({{
- if(passesCondition(Ccr<3:0>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
0x3: decode RCOND2
{
format BranchSplit
@@ -110,7 +110,7 @@ decode OP default Unknown::unknown()
0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
0x6: Trap::fbfcc({{fault = new FpDisabled;}});
}
- 0x1: Branch30::call({{
+ 0x1: BranchN::call(30, {{
R15 = xc->readPC();
NNPC = R15 + disp;
}});
@@ -134,7 +134,7 @@ decode OP default Unknown::unknown()
Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>;
Y = Rd.sdw;
}});
- 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + Ccr<0:0>}});
+ 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
0x0D: udivx({{
if(Rs2_or_imm13 == 0) fault = new DivisionByZero;
else Rd.udw = Rs1.udw / Rs2_or_imm13;
@@ -208,7 +208,7 @@ decode OP default Unknown::unknown()
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
- Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
+ Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
{{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
{{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
@@ -272,8 +272,9 @@ decode OP default Unknown::unknown()
);
0x22: taddcctv({{
int64_t resTemp, val2 = Rs2_or_imm13;
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ Rd = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> ||
+ (Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>);
if(overflow) fault = new TagOverflow;}},
{{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
{{overflow}},
@@ -322,15 +323,21 @@ decode OP default Unknown::unknown()
0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
// XXX might want a format rdipr thing here
- 0x28: rdasr({{
+ 0x28: decode RS1 {
+ 0xF: decode I {
+ 0x0: Nop::stbar({{/*stuff*/}});
+ 0x1: Nop::membar({{/*stuff*/}});
+ }
+ default: rdasr({{
Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault);
- }});
- 0x29: rdhpr({{
+ }});
+ }
+ 0x29: HPriv::rdhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault);
}});
- 0x2A: rdpr({{
+ 0x2A: Priv::rdpr({{
// XXX Need to protect with format that traps non-priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault);
@@ -397,18 +404,152 @@ decode OP default Unknown::unknown()
0x0: BasicOperate::saved({{/*Boogy Boogy*/}});
0x1: BasicOperate::restored({{/*Boogy Boogy*/}});
}
- 0x32: wrpr({{
+ 0x32: Priv::wrpr({{
// XXX Need to protect with format that traps non-priv
// access
- xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x33: wrhpr({{
+ 0x33: HPriv::wrhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
- xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x34: Trap::fpop1({{fault = new FpDisabled;}});
+ 0x34: decode OPF{
+ 0x01: Trap::fmovs({{fault = new FpDisabled;}});
+ 0x02: Trap::fmovd({{fault = new FpDisabled;}});
+ 0x03: Trap::fmovq({{fault = new FpDisabled;}});
+ 0x05: Trap::fnegs({{fault = new FpDisabled;}});
+ 0x06: Trap::fnegd({{fault = new FpDisabled;}});
+ 0x07: Trap::fnegq({{fault = new FpDisabled;}});
+ 0x09: Trap::fabss({{fault = new FpDisabled;}});
+ 0x0A: Trap::fabsd({{fault = new FpDisabled;}});
+ 0x0B: Trap::fabsq({{fault = new FpDisabled;}});
+ 0x29: Trap::fsqrts({{fault = new FpDisabled;}});
+ 0x2A: Trap::fsqrtd({{fault = new FpDisabled;}});
+ 0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
+ 0x41: Trap::fadds({{fault = new FpDisabled;}});
+ 0x42: BasicOperate::faddd({{Frd = Frs1 + Frs2;}});
+ 0x43: Trap::faddq({{fault = new FpDisabled;}});
+ 0x45: Trap::fsubs({{fault = new FpDisabled;}});
+ 0x46: Trap::fsubd({{fault = new FpDisabled;}});
+ 0x47: Trap::fsubq({{fault = new FpDisabled;}});
+ 0x49: Trap::fmuls({{fault = new FpDisabled;}});
+ 0x4A: BasicOperate::fmuld({{Frd = Frs1.sf * Frs2.sf;}});
+ 0x4B: Trap::fmulq({{fault = new FpDisabled;}});
+ 0x4D: Trap::fdivs({{fault = new FpDisabled;}});
+ 0x4E: Trap::fdivd({{fault = new FpDisabled;}});
+ 0x4F: Trap::fdivq({{fault = new FpDisabled;}});
+ 0x69: Trap::fsmuld({{fault = new FpDisabled;}});
+ 0x6E: Trap::fdmulq({{fault = new FpDisabled;}});
+ 0x81: Trap::fstox({{fault = new FpDisabled;}});
+ 0x82: Trap::fdtox({{fault = new FpDisabled;}});
+ 0x83: Trap::fqtox({{fault = new FpDisabled;}});
+ 0x84: Trap::fxtos({{fault = new FpDisabled;}});
+ 0x88: Trap::fxtod({{fault = new FpDisabled;}});
+ 0x8C: Trap::fxtoq({{fault = new FpDisabled;}});
+ 0xC4: Trap::fitos({{fault = new FpDisabled;}});
+ 0xC6: Trap::fdtos({{fault = new FpDisabled;}});
+ 0xC7: Trap::fqtos({{fault = new FpDisabled;}});
+ 0xC8: Trap::fitod({{fault = new FpDisabled;}});
+ 0xC9: Trap::fstod({{fault = new FpDisabled;}});
+ 0xCB: Trap::fqtod({{fault = new FpDisabled;}});
+ 0xCC: Trap::fitoq({{fault = new FpDisabled;}});
+ 0xCD: Trap::fstoq({{fault = new FpDisabled;}});
+ 0xCE: Trap::fdtoq({{fault = new FpDisabled;}});
+ 0xD1: Trap::fstoi({{fault = new FpDisabled;}});
+ 0xD2: Trap::fdtoi({{fault = new FpDisabled;}});
+ 0xD3: Trap::fqtoi({{fault = new FpDisabled;}});
+ default: Trap::fpop1({{fault = new FpDisabled;}});
+ }
0x35: Trap::fpop2({{fault = new FpDisabled;}});
+ //This used to be just impdep1, but now it's a whole bunch
+ //of instructions
+ 0x36: decode OPF{
+ 0x00: Trap::edge8({{fault = new IllegalInstruction;}});
+ 0x01: Trap::edge8n({{fault = new IllegalInstruction;}});
+ 0x02: Trap::edge8l({{fault = new IllegalInstruction;}});
+ 0x03: Trap::edge8ln({{fault = new IllegalInstruction;}});
+ 0x04: Trap::edge16({{fault = new IllegalInstruction;}});
+ 0x05: Trap::edge16n({{fault = new IllegalInstruction;}});
+ 0x06: Trap::edge16l({{fault = new IllegalInstruction;}});
+ 0x07: Trap::edge16ln({{fault = new IllegalInstruction;}});
+ 0x08: Trap::edge32({{fault = new IllegalInstruction;}});
+ 0x09: Trap::edge32n({{fault = new IllegalInstruction;}});
+ 0x0A: Trap::edge32l({{fault = new IllegalInstruction;}});
+ 0x0B: Trap::edge32ln({{fault = new IllegalInstruction;}});
+ 0x10: Trap::array8({{fault = new IllegalInstruction;}});
+ 0x12: Trap::array16({{fault = new IllegalInstruction;}});
+ 0x14: Trap::array32({{fault = new IllegalInstruction;}});
+ 0x18: Trap::alignaddress({{fault = new IllegalInstruction;}});
+ 0x19: Trap::bmask({{fault = new IllegalInstruction;}});
+ 0x1A: Trap::alignaddresslittle({{fault = new IllegalInstruction;}});
+ 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}});
+ 0x22: Trap::fcmpne16({{fault = new IllegalInstruction;}});
+ 0x24: Trap::fcmple32({{fault = new IllegalInstruction;}});
+ 0x26: Trap::fcmpne32({{fault = new IllegalInstruction;}});
+ 0x28: Trap::fcmpgt16({{fault = new IllegalInstruction;}});
+ 0x2A: Trap::fcmpeq16({{fault = new IllegalInstruction;}});
+ 0x2C: Trap::fcmpgt32({{fault = new IllegalInstruction;}});
+ 0x2E: Trap::fcmpeq32({{fault = new IllegalInstruction;}});
+ 0x31: Trap::fmul8x16({{fault = new IllegalInstruction;}});
+ 0x33: Trap::fmul8x16au({{fault = new IllegalInstruction;}});
+ 0x35: Trap::fmul8x16al({{fault = new IllegalInstruction;}});
+ 0x36: Trap::fmul8sux16({{fault = new IllegalInstruction;}});
+ 0x37: Trap::fmul8ulx16({{fault = new IllegalInstruction;}});
+ 0x38: Trap::fmuld8sux16({{fault = new IllegalInstruction;}});
+ 0x39: Trap::fmuld8ulx16({{fault = new IllegalInstruction;}});
+ 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}});
+ 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}});
+ 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}});
+ 0x3E: Trap::pdist({{fault = new IllegalInstruction;}});
+ 0x48: Trap::faligndata({{fault = new IllegalInstruction;}});
+ 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}});
+ 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}});
+ 0x4D: Trap::fexpand({{fault = new IllegalInstruction;}});
+ 0x50: Trap::fpadd16({{fault = new IllegalInstruction;}});
+ 0x51: Trap::fpadd16s({{fault = new IllegalInstruction;}});
+ 0x52: Trap::fpadd32({{fault = new IllegalInstruction;}});
+ 0x53: Trap::fpadd32s({{fault = new IllegalInstruction;}});
+ 0x54: Trap::fpsub16({{fault = new IllegalInstruction;}});
+ 0x55: Trap::fpsub16s({{fault = new IllegalInstruction;}});
+ 0x56: Trap::fpsub32({{fault = new IllegalInstruction;}});
+ 0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}});
+ 0x60: BasicOperate::fzero({{Frd = 0;}});
+ 0x61: Trap::fzeros({{fault = new IllegalInstruction;}});
+ 0x62: Trap::fnor({{fault = new IllegalInstruction;}});
+ 0x63: Trap::fnors({{fault = new IllegalInstruction;}});
+ 0x64: Trap::fandnot2({{fault = new IllegalInstruction;}});
+ 0x65: Trap::fandnot2s({{fault = new IllegalInstruction;}});
+ 0x66: Trap::fnot2({{fault = new IllegalInstruction;}});
+ 0x67: Trap::fnot2s({{fault = new IllegalInstruction;}});
+ 0x68: Trap::fandnot1({{fault = new IllegalInstruction;}});
+ 0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}});
+ 0x6A: Trap::fnot1({{fault = new IllegalInstruction;}});
+ 0x6B: Trap::fnot1s({{fault = new IllegalInstruction;}});
+ 0x6C: Trap::fxor({{fault = new IllegalInstruction;}});
+ 0x6D: Trap::fxors({{fault = new IllegalInstruction;}});
+ 0x6E: Trap::fnand({{fault = new IllegalInstruction;}});
+ 0x6F: Trap::fnands({{fault = new IllegalInstruction;}});
+ 0x70: Trap::fand({{fault = new IllegalInstruction;}});
+ 0x71: Trap::fands({{fault = new IllegalInstruction;}});
+ 0x72: Trap::fxnor({{fault = new IllegalInstruction;}});
+ 0x73: Trap::fxnors({{fault = new IllegalInstruction;}});
+ 0x74: Trap::fsrc1({{fault = new IllegalInstruction;}});
+ 0x75: Trap::fsrc1s({{fault = new IllegalInstruction;}});
+ 0x76: Trap::fornot2({{fault = new IllegalInstruction;}});
+ 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}});
+ 0x78: Trap::fsrc2({{fault = new IllegalInstruction;}});
+ 0x79: Trap::fsrc2s({{fault = new IllegalInstruction;}});
+ 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}});
+ 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}});
+ 0x7C: Trap::for({{fault = new IllegalInstruction;}});
+ 0x7D: Trap::fors({{fault = new IllegalInstruction;}});
+ 0x7E: Trap::fone({{fault = new IllegalInstruction;}});
+ 0x7F: Trap::fones({{fault = new IllegalInstruction;}});
+ 0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
+ 0x81: Trap::siam({{fault = new IllegalInstruction;}});
+ }
+ 0x37: Trap::impdep2({{fault = new IllegalInstruction;}});
0x38: Branch::jmpl({{
Addr target = Rs1 + Rs2_or_imm13;
if(target & 0x3)
@@ -549,7 +690,7 @@ decode OP default Unknown::unknown()
NNPC = Tnpc + 4;
Tl = Tl - 1;
}});
- 0x1: BasicOperate::retry({{
+ 0x1: Priv::retry({{
if(Tl == 0)
return new IllegalInstruction;
Cwp = Tstate<4:0>;
@@ -645,12 +786,13 @@ decode OP default Unknown::unknown()
0x26: stqf({{fault = new FpDisabled;}});
0x27: stdf({{fault = new FpDisabled;}});
0x2D: Nop::prefetch({{ }});
- 0x30: ldfa({{return new FpDisabled;}});
+ 0x30: ldfa({{fault = new FpDisabled;}});
0x32: ldqfa({{fault = new FpDisabled;}});
0x33: lddfa({{fault = new FpDisabled;}});
0x34: stfa({{fault = new FpDisabled;}});
- 0x35: stqfa({{fault = new FpDisabled;}});
- 0x36: stdfa({{fault = new FpDisabled;}});
+ 0x36: stqfa({{fault = new FpDisabled;}});
+ //XXX need to work in the ASI thing
+ 0x37: Store::stdfa({{Mem = ((uint64_t)Frd);}}, {{64}});
0x3C: Cas::casa({{
uint64_t val = Mem.uw;
if(Rs2.uw == val)
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 60432cb6b..0a47a7ffe 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -63,7 +63,6 @@ def template BasicExecute {{
{
Fault fault = NoFault;
- %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
@@ -81,11 +80,6 @@ def template BasicDecode {{
return new %(class_name)s(machInst);
}};
-// Basic decode template, passing mnemonic in as string arg to constructor.
-def template BasicDecodeWithMnemonic {{
- return new %(class_name)s("%(mnemonic)s", machInst);
-}};
-
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 7d46ce739..8a3f05173 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -69,47 +69,18 @@ output header {{
};
/**
- * Base class for branches with 19 bit displacements.
+ * Base class for branches with n bit displacements.
*/
- class Branch19 : public BranchDisp
+ template<int bits>
+ class BranchNBits : public BranchDisp
{
protected:
// Constructor
- Branch19(const char *mnem, MachInst _machInst,
+ BranchNBits(const char *mnem, MachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext(DISP19 << 2, 21);
- }
- };
-
- /**
- * Base class for branches with 22 bit displacements.
- */
- class Branch22 : public BranchDisp
- {
- protected:
- // Constructor
- Branch22(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP22 << 2, 24);
- }
- };
-
- /**
- * Base class for branches with 30 bit displacements.
- */
- class Branch30 : public BranchDisp
- {
- protected:
- // Constructor
- Branch30(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP30 << 2, 32);
+ disp = sign_ext(_machInst << 2, bits + 2);
}
};
@@ -149,29 +120,23 @@ output header {{
}};
output decoder {{
+
+ template class BranchNBits<19>;
+
+ template class BranchNBits<22>;
+
+ template class BranchNBits<30>;
+
std::string Branch::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -182,27 +147,13 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
if(_numSrcRegs > 0)
response << ", ";
-
ccprintf(response, "0x%x", imm);
-
if (_numDestRegs > 0)
- {
response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -292,32 +243,10 @@ def format Branch(code, *opt_flags) {{
}};
// Primary format for branch instructions:
-def format Branch19(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch22(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch30(code, *opt_flags) {{
+def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, 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 1894ce541..27616216e 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -132,7 +132,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = (IMM22 << 10) & 0xFFFFFC00;
+ imm = (IMM22 & 0x3FFFFF) << 10;
}
std::string generateDisassembly(Addr pc,
@@ -157,12 +157,9 @@ output decoder {{
if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[1]);
+ printSrcReg(os, 1);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
-
+ printDestReg(os, 0);
return true;
}
return false;
@@ -173,32 +170,24 @@ output decoder {{
{
if(!strcmp(mnemonic, "or"))
{
- if(_srcRegIdx[0] == 0)
+ if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
{
if(imm == 0)
- {
printMnemonic(os, "clr");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
- }
else
{
printMnemonic(os, "mov");
- ccprintf(os, ", 0x%x, ", imm);
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
+ ccprintf(os, " 0x%x, ", imm);
}
+ printDestReg(os, 0);
+ return true;
}
else if(imm == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[0]);
+ printSrcReg(os, 0);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
+ printDestReg(os, 0);
return true;
}
}
@@ -210,25 +199,13 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -237,27 +214,16 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs - 1; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if(_numSrcRegs > 0)
- response << ", ";
- ccprintf(response, "0x%x", imm);
- if (_numDestRegs > 0)
- {
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numSrcRegs > 0)
+ response << ", ";
+ ccprintf(response, "0x%x", imm);
+ if(_numDestRegs > 0)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -267,10 +233,8 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
- if(_numSrcRegs > 0)
- response << ", ";
ccprintf(response, "%%hi(0x%x), ", imm);
- printReg(response, _destRegIdx[0]);
+ printDestReg(response, 0);
return response.str();
}
}};
@@ -316,38 +280,29 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
- uint8_t tmp_ccriccc;
- uint8_t tmp_ccriccv;
- uint8_t tmp_ccriccz;
- uint8_t tmp_ccriccn;
- uint8_t tmp_ccrxccc;
- uint8_t tmp_ccrxccv;
- uint8_t tmp_ccrxccz;
- uint8_t tmp_ccrxccn;
-
- tmp_ccriccn = (Rd >> 31) & 1;
- tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0);
- tmp_ccrxccn = (Rd >> 63) & 1;
- tmp_ccrxccz = (Rd == 0);
- tmp_ccriccv = %(ivValue)s & 1;
- tmp_ccriccc = %(icValue)s & 1;
- tmp_ccrxccv = %(xvValue)s & 1;
- tmp_ccrxccc = %(xcValue)s & 1;
-
- Ccr = tmp_ccriccc | tmp_ccriccv << 1 |
- tmp_ccriccz << 2 | tmp_ccriccn << 3|
- tmp_ccrxccc << 4 | tmp_ccrxccv << 5|
- tmp_ccrxccz << 6| tmp_ccrxccn << 7;
-
-
- DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn);
- DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz);
- DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn);
- DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz);
- DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv);
- DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc);
- DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv);
- DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc);
+ uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
+
+ _in = (Rd >> 31) & 1;
+ _iz = ((Rd & 0xFFFFFFFF) == 0);
+ _xn = (Rd >> 63) & 1;
+ _xz = (Rd == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+ _xv = %(xvValue)s & 1;
+ _xc = %(xcValue)s & 1;
+
+ Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
+ _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
+
+
+ DPRINTF(Sparc, "in = %%d\\n", _in);
+ DPRINTF(Sparc, "iz = %%d\\n", _iz);
+ DPRINTF(Sparc, "xn = %%d\\n", _xn);
+ DPRINTF(Sparc, "xz = %%d\\n", _xz);
+ DPRINTF(Sparc, "iv = %%d\\n", _iv);
+ DPRINTF(Sparc, "ic = %%d\\n", _ic);
+ DPRINTF(Sparc, "xv = %%d\\n", _xv);
+ DPRINTF(Sparc, "xc = %%d\\n", _xc);
'''
}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 7df59d736..d7ee01519 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -72,7 +72,11 @@ output decoder {{
std::string Priv::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Privileged Instruction";
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
}
}};
@@ -87,9 +91,10 @@ def template PrivExecute {{
if(%(check)s)
return new PrivilegedAction;
+ Fault fault = NoFault;
%(code)s;
%(op_wb)s;
- return NoFault;
+ return fault;
}
}};
@@ -116,10 +121,17 @@ let {{
// Primary format for integer operate instructions:
def format Priv(code, *opt_flags) {{
- checkCode = "((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>)"
+ checkCode = '''((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>) ||
+ ((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)'''
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, opt_flags)
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
}};
+def format HPriv(code, *opt_flags) {{
+ checkCode = "((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)"
+ (header_output, decoder_output,
+ exec_output, decode_block) = doPrivFormat(code,
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 40afb3722..3783051c4 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -36,7 +36,6 @@
output header {{
#include <sstream>
#include <iostream>
-#include <iomanip>
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
@@ -50,7 +49,6 @@ output decoder {{
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
@@ -59,14 +57,10 @@ using namespace SparcISA;
}};
output exec {{
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
-#ifdef FULL_SYSTEM
-//#include "sim/pseudo_inst.hh"
-#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 9e5c783e8..d250d3672 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -51,12 +51,12 @@ def operands {{
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- #'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
- #'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
- #'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
- 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
- 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 4),
- 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 4),
+ 'Frd': ('FloatReg', 'df', 'RD', 'IsFloating', 10),
+ 'Frs1': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
+ 'Frs2': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
+ 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
+ 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
+ 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 6),
@@ -65,24 +65,24 @@ def operands {{
'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
- 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12),
- 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17),
- 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26),
+ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
+ 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+ 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
- 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28),
- 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 28),
- 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 28),
- 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
- 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27),
+ 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43),
+ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44),
+ 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45),
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 47),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38),
- 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 12),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 48),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 49),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 50),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 51),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 52),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 53),
+ 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
- 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47)
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55)
}};
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index cbeb3c7b9..db48b2d78 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -55,14 +55,12 @@ namespace SparcISA
// NWINDOWS - number of register windows, can be 3 to 32
const int NWindows = 32;
-
const int AsrStart = 0;
const int PrStart = 32;
const int HprStart = 64;
const int MiscStart = 96;
const uint64_t Bit64 = (1ULL << 63);
-
class IntRegFile
{
protected:
@@ -182,7 +180,7 @@ namespace SparcISA
//Since the floating point registers overlap each other,
//A generic storage space is used. The float to be returned is
//pulled from the appropriate section of this region.
- char regSpace[SingleWidth / 8 * NumFloatRegs];
+ char regSpace[(SingleWidth / 8) * NumFloatRegs];
public:
@@ -200,15 +198,15 @@ namespace SparcISA
{
case SingleWidth:
float32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
float64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
float128_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -224,15 +222,15 @@ namespace SparcISA
{
case SingleWidth:
uint32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
return htog(result32);
case DoubleWidth:
uint64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
return htog(result64);
case QuadWidth:
uint64_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
return htog(result128);
default:
panic("Attempted to read a %d bit floating point register!", width);
@@ -247,15 +245,16 @@ namespace SparcISA
uint32_t result32;
uint64_t result64;
+ DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
switch(width)
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -277,11 +276,11 @@ namespace SparcISA
{
case SingleWidth:
result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
break;
case DoubleWidth:
result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
break;
case QuadWidth:
panic("Quad width FP not implemented.");
@@ -625,11 +624,9 @@ namespace SparcISA
hpstateFields.red = 1;
hpstateFields.hpriv = 1;
hpstateFields.tlz = 0; // this is a guess
-
hintp = 0; // no interrupts pending
hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
#else
/* //This sets up the initial state of the processor for usermode processes
pstateFields.priv = 0; //Process runs in user mode
@@ -687,6 +684,8 @@ namespace SparcISA
void copyMiscRegs(ThreadContext * tc);
+ protected:
+
bool isHyperPriv() { return hpstateFields.hpriv; }
bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
bool isNonPriv() { return !isPriv(); }