SPARC: Long overdue cleanup of the condition code handlers.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 26 Sep 2007 03:08:34 +0000 (20:08 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 26 Sep 2007 03:08:34 +0000 (20:08 -0700)
--HG--
extra : convert_revision : ddc53a622a8f908fa48788f3b570f33fcfc25fff

src/arch/sparc/isa/decoder.isa
src/arch/sparc/isa/formats/integerop.isa
src/arch/sparc/isa/includes.isa

index 9b7c195d771a708588fa839c39c1aa92f906ffd1..1caf6ba25ae7d092d00a188f420ac7c8b92c1378 100644 (file)
@@ -193,37 +193,23 @@ decode OP default Unknown::unknown()
         }
         format IntOpCc {
             0x10: addcc({{
-                int64_t resTemp, val2 = Rs2_or_imm13;
-                Rd = resTemp = Rs1 + val2;}},
-                {{(Rs1<31:0> + val2<31:0>)<32:>}},
-                {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
-                {{(Rs1<63:1> + val2<63:1> + (Rs1 & val2)<0:>)<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 + op2;
+                }});
             0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
             0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
             0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
             0x14: subcc({{
-                int64_t val2 = Rs2_or_imm13;
-                Rd = Rs1 - val2;}},
-                {{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}},
-                {{(Rs1<31:> != val2<31:>) && (Rs1<31:> != Rd<31:>)}},
-                {{(~(Rs1<63:1> + (~val2)<63:1> +
-                    (Rs1 | ~val2)<0:>))<63:>}},
-                {{Rs1<63:> != val2<63:> && Rs1<63:> != Rd<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 - op2;
+                }}, sub=True);
             0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
             0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
             0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
             0x18: addccc({{
-                int64_t resTemp, val2 = Rs2_or_imm13;
-                int64_t carryin = Ccr<0:0>;
-                Rd = resTemp = Rs1 + val2 + carryin;}},
-                {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
-                {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
-                {{((Rs1 & val2) | (~resTemp & (Rs1 | val2)))<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 + op2 + Ccr<0:>;
+                }});
             0x1A: IntOpCcRes::umulcc({{
                 uint64_t resTemp;
                 Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>;
@@ -233,107 +219,80 @@ decode OP default Unknown::unknown()
                 Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
                 Y = resTemp<63:32>;}});
             0x1C: subccc({{
-                int64_t resTemp, val2 = Rs2_or_imm13;
-                int64_t carryin = Ccr<0:0>;
-                Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
-                {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<31:>}},
-                {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
-                {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<63:>}},
-                {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 - op2 - Ccr<0:>;
+                }}, sub=True);
             0x1D: IntOpCcRes::udivxcc({{
                 if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
                 else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
-            0x1E: udivcc({{
-                uint32_t resTemp, val2 = Rs2_or_imm13.udw;
-                int32_t overflow = 0;
-                if(val2 == 0) fault = new DivisionByZero;
-                else
-                {
-                    resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2;
-                    overflow = (resTemp<63:32> != 0);
-                    if(overflow) Rd = resTemp = 0xFFFFFFFF;
-                    else Rd = resTemp;
-                } }},
-                {{0}},
-                {{overflow}},
-                {{0}},
-                {{0}}
-            );
-            0x1F: sdivcc({{
-                int64_t val2 = Rs2_or_imm13.sdw<31:0>;
-                bool overflow = false, underflow = false;
-                if(val2 == 0) fault = new DivisionByZero;
-                else
-                {
-                    Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
-                    overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
-                    underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
-                    if(overflow) Rd = 0x7FFFFFFF;
-                    else if(underflow) Rd = ULL(0xFFFFFFFF80000000);
-                } }},
-                {{0}},
-                {{overflow || underflow}},
-                {{0}},
-                {{0}}
-            );
+            0x1E: IntOpCcRes::udivcc({{
+                    uint32_t resTemp, val2 = Rs2_or_imm13.udw;
+                    int32_t overflow = 0;
+                    if(val2 == 0) fault = new DivisionByZero;
+                    else
+                    {
+                        resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2;
+                        overflow = (resTemp<63:32> != 0);
+                        if(overflow) Rd = resTemp = 0xFFFFFFFF;
+                        else Rd = resTemp;
+                    }
+                }}, iv={{overflow}});
+            0x1F: IntOpCcRes::sdivcc({{
+                    int64_t val2 = Rs2_or_imm13.sdw<31:0>;
+                    bool overflow = false, underflow = false;
+                    if(val2 == 0) fault = new DivisionByZero;
+                    else
+                    {
+                        Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
+                        overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
+                        underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
+                        if(overflow) Rd = 0x7FFFFFFF;
+                        else if(underflow) Rd = ULL(0xFFFFFFFF80000000);
+                    }
+                }}, iv={{overflow || underflow}});
             0x20: taddcc({{
-                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:>);}},
-                {{((Rs1<31:0> + val2<31:0>)<32:0>)}},
-                {{overflow}},
-                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = Rs1 + op2;
+                }}, iv={{
+                    (op1 & mask(2)) || (op2 & mask(2)) ||
+                    findOverflow(32, res, op1, op2)
+                }});
             0x21: tsubcc({{
-                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:>);}},
-                {{(Rs1<31:0> + val2<31:0>)<32:0>}},
-                {{overflow}},
-                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = Rs1 - op2;
+                }}, iv={{
+                    (op1 & mask(2)) || (op2 & mask(2)) ||
+                    findOverflow(32, res, op1, ~op2)
+                }}, sub=True);
             0x22: taddcctv({{
-                int64_t val2 = Rs2_or_imm13;
-                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<31:0> + val2<31:0>)<32:0>)}},
-                {{overflow}},
-                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != Rd<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 + op2;
+                    bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
+                        findOverflow(32, res, op1, op2);
+                    if(overflow) fault = new TagOverflow;
+                }}, iv={{overflow}});
             0x23: tsubcctv({{
-                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:>);
-                if(overflow) fault = new TagOverflow;}},
-                {{((Rs1<31:0> + val2<31:0>)<32:0>)}},
-                {{overflow}},
-                {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
-                {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
-            );
+                    int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
+                    Rd = res = op1 - op2;
+                    bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
+                        findOverflow(32, res, op1, ~op2);
+                    if(overflow) fault = new TagOverflow;
+                }}, iv={{overflow}}, sub=True);
             0x24: mulscc({{
-                int32_t savedLSB = Rs1<0:>;
+                    int32_t savedLSB = Rs1<0:>;
 
-                //Step 1
-                int64_t multiplicand = Rs2_or_imm13;
-                //Step 2
-                int32_t partialP = Rs1<31:1> |
-                    ((Ccr<3:3> ^ Ccr<1:1>) << 31);
-                //Step 3
-                int32_t added = Y<0:> ? multiplicand : 0;
-                Rd = partialP + added;
-                //Steps 4 & 5
-                Y = Y<31:1> | (savedLSB << 31);}},
-                {{((partialP<31:0> + added<31:0>)<32:0>)}},
-                {{partialP<31:> == added<31:> && added<31:> != Rd<31:>}},
-                {{((partialP >> 1) + (added >> 1) + (partialP & added & 0x1))<63:>}},
-                {{partialP<63:> == added<63:> && partialP<63:> != Rd<63:>}}
-            );
+                    //Step 1
+                    int64_t multiplicand = Rs2_or_imm13;
+                    //Step 2
+                    int32_t partialP = Rs1<31:1> |
+                        ((Ccr<3:3> ^ Ccr<1:1>) << 31);
+                    //Step 3
+                    int32_t added = Y<0:> ? multiplicand : 0;
+                    int64_t res, op1 = partialP, op2 = added;
+                    Rd = res = partialP + added;
+                    //Steps 4 & 5
+                    Y = Y<31:1> | (savedLSB << 31);
+                }});
         }
         format IntOp
         {
index f877b87902d8cf23f5d9614f7c44171c2ddc06c2..55af7e5b392f57edf1511594c5570b8b49bd6ef7 100644 (file)
@@ -287,10 +287,10 @@ let {{
         _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;
+        _iv = %(iv)s & 1;
+        _ic = %(ic)s & 1;
+        _xv = %(xv)s & 1;
+        _xc = %(xc)s & 1;
 
         Ccr =  _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
                _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
@@ -305,6 +305,15 @@ let {{
         DPRINTF(Sparc, "xv = %%d\\n", _xv);
         DPRINTF(Sparc, "xc = %%d\\n", _xc);
         '''
+
+    default_ic = "findCarry(32, res, op1, op2)"
+    default_iv = "findOverflow(32, res, op1, op2)"
+    default_xc = "findCarry(64, res, op1, op2)"
+    default_xv = "findOverflow(64, res, op1, op2)"
+    default_sub_ic = "!findCarry(32, res, op1, ~op2)"
+    default_sub_iv = "findOverflow(32, res, op1, ~op2)"
+    default_sub_xc = "!findCarry(64, res, op1, ~op2)"
+    default_sub_xv = "findOverflow(64, res, op1, ~op2)"
 }};
 
 // Primary format for integer operate instructions:
@@ -318,7 +327,24 @@ def format IntOp(code, *opt_flags) {{
 }};
 
 // Primary format for integer operate instructions:
-def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
+def format IntOpCc(code, ic=default_ic, iv=default_iv,
+                         xc=default_xc, xv=default_xv,
+                         sub=False, *opt_flags) {{
+
+    if sub == "False":
+        (def_ic, def_iv, def_xc, def_xv) = \
+            (default_ic, default_iv, default_xc, default_xv)
+    else:
+        (def_ic, def_iv, def_xc, def_xv) = \
+            (default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv)
+    if ic == "default_ic":
+        ic = def_ic
+    if iv == "default_iv":
+        iv = def_iv
+    if xc == "default_xc":
+        xc = def_xc
+    if xv == "default_xv":
+        xv = def_xv
     ccCode = calcCcCode % vars()
     (header_output,
      decoder_output,
@@ -328,11 +354,8 @@ def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
 }};
 
 // Primary format for integer operate instructions:
-def format IntOpCcRes(code, *opt_flags) {{
-    ccCode = calcCcCode % {"icValue":"0",
-                        "ivValue":"0",
-                        "xcValue":"0",
-                        "xvValue":"0"}
+def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{
+    ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv}
     (header_output,
      decoder_output,
      exec_output,
index e9cd660b5453e72110c6aa6bea3742ef4dd69512..135bd58c3dac304157224200c1a74fff3118401f 100644 (file)
@@ -41,6 +41,7 @@ output header {{
 #include "arch/sparc/faults.hh"
 #include "arch/sparc/isa_traits.hh"
 #include "arch/sparc/regfile.hh"
+#include "base/condcodes.hh"
 #include "base/misc.hh"
 #include "cpu/static_inst.hh"
 #include "mem/packet.hh"