diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-09-25 20:05:11 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-09-25 20:05:11 -0700 |
commit | 8d53fea21004af9dc51c68643bf5714904da2e72 (patch) | |
tree | fa20b2407ecc9e5bb8b96a2939984b1eda363cbf /src/arch | |
parent | 9ef0f6a7f13a789bccfadf363861f5ff81709fc7 (diff) | |
download | gem5-8d53fea21004af9dc51c68643bf5714904da2e72.tar.xz |
SPARC: Clean up the branch instructions a bit.
--HG--
extra : convert_revision : 93d5cc68e4a327ee0492eeed7f3b56e98d2d83bb
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 219 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/basic.isa | 24 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/branch.isa | 168 |
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) }}; |