diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-09-25 20:08:34 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-09-25 20:08:34 -0700 |
commit | b896ad584b14470048a518ba331dee8f53f90a12 (patch) | |
tree | 8227ca4ea1948f2adf35e61d84382447299f1039 | |
parent | 25b48746642a0b5df15bdf193272a155ca7c9422 (diff) | |
download | gem5-b896ad584b14470048a518ba331dee8f53f90a12.tar.xz |
SPARC: Long overdue cleanup of the condition code handlers.
--HG--
extra : convert_revision : ddc53a622a8f908fa48788f3b570f33fcfc25fff
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 189 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 43 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 1 |
3 files changed, 108 insertions, 125 deletions
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 9b7c195d7..1caf6ba25 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -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 { diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index f877b8790..55af7e5b3 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -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, diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index e9cd660b5..135bd58c3 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -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" |