summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-09-25 20:05:11 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-09-25 20:05:11 -0700
commit8d53fea21004af9dc51c68643bf5714904da2e72 (patch)
treefa20b2407ecc9e5bb8b96a2939984b1eda363cbf /src/arch/sparc
parent9ef0f6a7f13a789bccfadf363861f5ff81709fc7 (diff)
downloadgem5-8d53fea21004af9dc51c68643bf5714904da2e72.tar.xz
SPARC: Clean up the branch instructions a bit.
--HG-- extra : convert_revision : 93d5cc68e4a327ee0492eeed7f3b56e98d2d83bb
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/isa/decoder.isa219
-rw-r--r--src/arch/sparc/isa/formats/basic.isa24
-rw-r--r--src/arch/sparc/isa/formats/branch.isa168
3 files changed, 198 insertions, 213 deletions
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 14c652606..9b7c195d7 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -45,116 +45,49 @@ decode OP default Unknown::unknown()
0x1: decode COND2
{
//Branch Always
- 0x8: decode A
- {
- 0x0: bpa(19, {{
- NNPC = xc->readPC() + disp;
- }});
- 0x1: bpa(19, {{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
- }}, ',a');
- }
+ 0x8: bpa(19, annul_code={{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }});
//Branch Never
- 0x0: decode A
- {
- 0x0: bpn(19, {{
- NNPC = NNPC;//Don't do anything
- }});
- 0x1: bpn(19, {{
- NNPC = NPC + 8;
- NPC = NPC + 4;
- }}, ',a');
- }
+ 0x0: bpn(19, {{;}},
+ annul_code={{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }});
default: decode BPCC
{
- 0x0: bpcci(19, {{
- if(passesCondition(Ccr<3:0>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x2: bpccx(19, {{
- if(passesCondition(Ccr<7:4>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
+ 0x0: bpcci(19, test={{passesCondition(Ccr<3:0>, COND2)}});
+ 0x2: bpccx(19, test={{passesCondition(Ccr<7:4>, COND2)}});
}
}
//bicc
0x2: decode COND2
{
//Branch Always
- 0x8: decode A
- {
- 0x0: ba(22, {{
- NNPC = xc->readPC() + disp;
- }});
- 0x1: ba(22, {{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
- }}, ',a');
- }
+ 0x8: ba(22, annul_code={{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }});
//Branch Never
- 0x0: decode A
- {
- 0x0: bn(22, {{
- NNPC = NNPC;//Don't do anything
- }});
- 0x1: bn(22, {{
- NNPC = NPC + 8;
- NPC = NPC + 4;
- }}, ',a');
- }
- default: bicc(22, {{
- if(passesCondition(Ccr<3:0>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
+ 0x0: bn(22, {{;}},
+ annul_code={{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }});
+ default: bicc(22, test={{passesCondition(Ccr<3:0>, COND2)}});
}
}
0x3: decode RCOND2
{
format BranchSplit
{
- 0x1: bpreq({{
- if(Rs1.sdw == 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x2: bprle({{
- if(Rs1.sdw <= 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x3: bprl({{
- if(Rs1.sdw < 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x5: bprne({{
- if(Rs1.sdw != 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x6: bprg({{
- if(Rs1.sdw > 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x7: bprge({{
- if(Rs1.sdw >= 0)
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
+ 0x1: bpreq(test={{Rs1.sdw == 0}});
+ 0x2: bprle(test={{Rs1.sdw <= 0}});
+ 0x3: bprl(test={{Rs1.sdw < 0}});
+ 0x5: bprne(test={{Rs1.sdw != 0}});
+ 0x6: bprg(test={{Rs1.sdw > 0}});
+ 0x7: bprge(test={{Rs1.sdw >= 0}});
}
}
//SETHI (or NOP if rd == 0 and imm == 0)
@@ -163,52 +96,25 @@ decode OP default Unknown::unknown()
0x5: decode COND2 {
format BranchN {
//Branch Always
- 0x8: decode A
- {
- 0x0: fbpa(22, {{
- NNPC = xc->readPC() + disp;
- }});
- 0x1: fbpa(22, {{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
- }}, ',a');
- }
+ 0x8: fbpa(22, annul_code={{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }});
//Branch Never
- 0x0: decode A
- {
- 0x0: fbpn(22, {{
- NNPC = NNPC;//Don't do anything
- }});
- 0x1: fbpn(22, {{
- NNPC = NPC + 8;
- NPC = NPC + 4;
- }}, ',a');
- }
+ 0x0: fbpn(22, {{;}},
+ annul_code={{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }});
default: decode BPCC {
- 0x0: fbpfcc0(19, {{
- if(passesFpCondition(Fsr<11:10>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x1: fbpfcc1(19, {{
- if(passesFpCondition(Fsr<33:32>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x2: fbpfcc2(19, {{
- if(passesFpCondition(Fsr<35:34>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
- 0x3: fbpfcc3(19, {{
- if(passesFpCondition(Fsr<37:36>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
+ 0x0: fbpfcc0(19, test=
+ {{passesFpCondition(Fsr<11:10>, COND2)}});
+ 0x1: fbpfcc1(19, test=
+ {{passesFpCondition(Fsr<33:32>, COND2)}});
+ 0x2: fbpfcc2(19, test=
+ {{passesFpCondition(Fsr<35:34>, COND2)}});
+ 0x3: fbpfcc3(19, test=
+ {{passesFpCondition(Fsr<37:36>, COND2)}});
}
}
}
@@ -216,33 +122,18 @@ decode OP default Unknown::unknown()
0x6: decode COND2 {
format BranchN {
//Branch Always
- 0x8: decode A
- {
- 0x0: fba(22, {{
- NNPC = xc->readPC() + disp;
- }});
- 0x1: fba(22, {{
- NPC = xc->readPC() + disp;
- NNPC = NPC + 4;
- }}, ',a');
- }
+ 0x8: fba(22, annul_code={{
+ NPC = xc->readPC() + disp;
+ NNPC = NPC + 4;
+ }});
//Branch Never
- 0x0: decode A
- {
- 0x0: fbn(22, {{
- NNPC = NNPC;//Don't do anything
- }});
- 0x1: fbn(22, {{
- NNPC = NPC + 8;
- NPC = NPC + 4;
- }}, ',a');
- }
- default: fbfcc(22, {{
- if(passesFpCondition(Fsr<11:10>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
+ 0x0: fbn(22, {{;}},
+ annul_code={{
+ NNPC = NPC + 8;
+ NPC = NPC + 4;
+ }});
+ default: fbfcc(22, test=
+ {{passesFpCondition(Fsr<11:10>, COND2)}});
}
}
}
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 5b0868132..cad759b3e 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -56,6 +56,20 @@ def template BasicDeclare {{
};
}};
+// Basic instruction class declaration template.
+def template BasicDeclareWithMnemonic {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ // Constructor.
+ %(class_name)s(const char * mnemonic, ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ };
+}};
+
// Basic instruction class constructor template.
def template BasicConstructor {{
inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
@@ -65,6 +79,16 @@ def template BasicConstructor {{
}
}};
+// Basic instruction class constructor template.
+def template BasicConstructorWithMnemonic {{
+ inline %(class_name)s::%(class_name)s(const char * mnemonic,
+ ExtMachInst machInst)
+ : %(base_class)s(mnemonic, machInst, %(op_class)s)
+ {
+ %(constructor)s;
+ }
+}};
+
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index f5ab940bb..faaee8842 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -183,7 +183,7 @@ output decoder {{
}
}};
-def template BranchExecute {{
+def template JumpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -206,65 +206,135 @@ def template BranchExecute {{
}
}};
-let {{
- handle_annul = '''
- {
- if(A)
- {
- NNPC = NPC + 8;
- NPC = NPC + 4;
- }
- else
+def template BranchExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
{
- NPC = NPC;
- NNPC = NNPC;
+ //Attempt to execute the instruction
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+
+ if (%(cond)s) {
+ %(code)s;
+ } else {
+ %(fail)s;
+ }
+
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
}
- }'''
+}};
+
+def template BranchDecode {{
+ if (A)
+ return new %(class_name)sAnnul("%(mnemonic)s,a", machInst);
+ else
+ return new %(class_name)s("%(mnemonic)s", machInst);
}};
// Primary format for branch instructions:
def format Branch(code, *opt_flags) {{
- (usesImm, code, immCode,
- rString, iString) = splitOutImm(code)
- iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
+ (usesImm, code, immCode,
+ rString, iString) = splitOutImm(code)
+ iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ exec_output = JumpExecute.subst(iop)
+ if usesImm:
+ imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
+ immCode, opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += JumpExecute.subst(imm_iop)
+ decode_block = ROrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
+}};
+
+let {{
+ def doBranch(name, Name, base, cond,
+ code, annul_code, fail, annul_fail, opt_flags):
+ iop = InstObjParams(name, Name, base,
+ {"code": code,
+ "fail": fail,
+ "cond": cond
+ },
+ opt_flags)
+ header_output = BasicDeclareWithMnemonic.subst(iop)
+ decoder_output = BasicConstructorWithMnemonic.subst(iop)
exec_output = BranchExecute.subst(iop)
- if usesImm:
- imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
- immCode, opt_flags)
- header_output += BasicDeclare.subst(imm_iop)
- decoder_output += BasicConstructor.subst(imm_iop)
- exec_output += BranchExecute.subst(imm_iop)
- decode_block = ROrImmDecode.subst(iop)
+ if annul_code == "None":
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
else:
- decode_block = BasicDecode.subst(iop)
+ decode_block = BranchDecode.subst(iop)
+
+ if annul_code != "None":
+ iop = InstObjParams(name + ',a', Name + 'Annul', base,
+ {"code": annul_code,
+ "fail": annul_fail,
+ "cond": cond
+ },
+ opt_flags)
+ header_output += BasicDeclareWithMnemonic.subst(iop)
+ decoder_output += BasicConstructorWithMnemonic.subst(iop)
+ exec_output += BranchExecute.subst(iop)
+ return (header_output, decoder_output, exec_output, decode_block)
+
+ def doCondBranch(name, Name, base, cond, code, opt_flags):
+ return doBranch(name, Name, base, cond, code, code,
+ 'NPC = NPC; NNPC = NNPC;',
+ 'NNPC = NPC + 8; NPC = NPC + 4',
+ opt_flags)
+
+ def doUncondBranch(name, Name, base, code, annul_code, opt_flags):
+ return doBranch(name, Name, base, "true", code, annul_code,
+ ";", ";", opt_flags)
+
+ default_branch_code = "NNPC = xc->readPC() + disp;"
}};
-// Primary format for branch instructions:
-def format BranchN(bits, code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- new_opt_flags = []
- for flag in opt_flags:
- if flag == ',a':
- name += ',a'
- Name += 'Annul'
- else:
- new_opt_flags += flag
- 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)
- decode_block = BasicDecode.subst(iop)
+// Format for branch instructions with n bit displacements:
+def format BranchN(bits, code=default_branch_code,
+ test=None, annul_code=None, *opt_flags) {{
+ if code == "default_branch_code":
+ code = default_branch_code
+ if test != "None":
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doCondBranch(name, Name,
+ "BranchNBits<%d>" % bits, test, code, opt_flags)
+ else:
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doUncondBranch(name, Name,
+ "BranchNBits<%d>" % bits, code, annul_code, opt_flags)
}};
-// Primary format for branch instructions:
-def format BranchSplit(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
+// Format for branch instructions with split displacements:
+def format BranchSplit(code=default_branch_code,
+ test=None, annul_code=None, *opt_flags) {{
+ if code == "default_branch_code":
+ code = default_branch_code
+ if test != "None":
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doCondBranch(name, Name,
+ "BranchSplit", test, code, opt_flags)
+ else:
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doUncondBranch(name, Name,
+ "BranchSplit", code, annul_code, opt_flags)
}};