SPARC: Clean up the branch instructions a bit.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 26 Sep 2007 03:05:11 +0000 (20:05 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 26 Sep 2007 03:05:11 +0000 (20:05 -0700)
--HG--
extra : convert_revision : 93d5cc68e4a327ee0492eeed7f3b56e98d2d83bb

src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats/basic.isa
src/arch/sparc/isa/formats/branch.isa

index 14c652606bc6fe48228f7409b92e7195ea4dada0..9b7c195d771a708588fa839c39c1aa92f906ffd1 100644 (file)
@@ -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)}});
             }
         }
     }
index 5b0868132ce33c75003def3b212c4df4fb81d882..cad759b3efda859661d12c1bd29dc0fabe2b5381 100644 (file)
@@ -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,
index f5ab940bbcea9dd462e965f4cce68ecb95917201..faaee8842873b28f64445fb6e9f7618adcaa7f14 100644 (file)
@@ -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)
 }};