SPARC: Long overdue cleanup of the condition code handlers.
--HG-- extra : convert_revision : ddc53a622a8f908fa48788f3b570f33fcfc25fff
This commit is contained in:
parent
25b4874664
commit
b896ad584b
|
@ -193,37 +193,23 @@ decode OP default Unknown::unknown()
|
||||||
}
|
}
|
||||||
format IntOpCc {
|
format IntOpCc {
|
||||||
0x10: addcc({{
|
0x10: addcc({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = resTemp = Rs1 + val2;}},
|
Rd = res = op1 + op2;
|
||||||
{{(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:>}}
|
|
||||||
);
|
|
||||||
0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
|
0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
|
||||||
0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
|
0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
|
||||||
0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
|
0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
|
||||||
0x14: subcc({{
|
0x14: subcc({{
|
||||||
int64_t val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = Rs1 - val2;}},
|
Rd = res = op1 - op2;
|
||||||
{{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}},
|
}}, sub=True);
|
||||||
{{(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:>}}
|
|
||||||
);
|
|
||||||
0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
|
0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
|
||||||
0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
|
0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
|
||||||
0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
|
0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
|
||||||
0x18: addccc({{
|
0x18: addccc({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
int64_t carryin = Ccr<0:0>;
|
Rd = res = op1 + op2 + Ccr<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:>}}
|
|
||||||
);
|
|
||||||
0x1A: IntOpCcRes::umulcc({{
|
0x1A: IntOpCcRes::umulcc({{
|
||||||
uint64_t resTemp;
|
uint64_t resTemp;
|
||||||
Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>;
|
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>);
|
Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>);
|
||||||
Y = resTemp<63:32>;}});
|
Y = resTemp<63:32>;}});
|
||||||
0x1C: subccc({{
|
0x1C: subccc({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
int64_t carryin = Ccr<0:0>;
|
Rd = res = op1 - op2 - Ccr<0:>;
|
||||||
Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
|
}}, sub=True);
|
||||||
{{((~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:>}}
|
|
||||||
);
|
|
||||||
0x1D: IntOpCcRes::udivxcc({{
|
0x1D: IntOpCcRes::udivxcc({{
|
||||||
if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
|
if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero;
|
||||||
else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
|
else Rd = Rs1.udw / Rs2_or_imm13.udw;}});
|
||||||
0x1E: udivcc({{
|
0x1E: IntOpCcRes::udivcc({{
|
||||||
uint32_t resTemp, val2 = Rs2_or_imm13.udw;
|
uint32_t resTemp, val2 = Rs2_or_imm13.udw;
|
||||||
int32_t overflow = 0;
|
int32_t overflow = 0;
|
||||||
if(val2 == 0) fault = new DivisionByZero;
|
if(val2 == 0) fault = new DivisionByZero;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2;
|
resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2;
|
||||||
overflow = (resTemp<63:32> != 0);
|
overflow = (resTemp<63:32> != 0);
|
||||||
if(overflow) Rd = resTemp = 0xFFFFFFFF;
|
if(overflow) Rd = resTemp = 0xFFFFFFFF;
|
||||||
else Rd = resTemp;
|
else Rd = resTemp;
|
||||||
} }},
|
}
|
||||||
{{0}},
|
}}, iv={{overflow}});
|
||||||
{{overflow}},
|
0x1F: IntOpCcRes::sdivcc({{
|
||||||
{{0}},
|
int64_t val2 = Rs2_or_imm13.sdw<31:0>;
|
||||||
{{0}}
|
bool overflow = false, underflow = false;
|
||||||
);
|
if(val2 == 0) fault = new DivisionByZero;
|
||||||
0x1F: sdivcc({{
|
else
|
||||||
int64_t val2 = Rs2_or_imm13.sdw<31:0>;
|
{
|
||||||
bool overflow = false, underflow = false;
|
Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
|
||||||
if(val2 == 0) fault = new DivisionByZero;
|
overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
|
||||||
else
|
underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
|
||||||
{
|
if(overflow) Rd = 0x7FFFFFFF;
|
||||||
Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2;
|
else if(underflow) Rd = ULL(0xFFFFFFFF80000000);
|
||||||
overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max());
|
}
|
||||||
underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min());
|
}}, iv={{overflow || underflow}});
|
||||||
if(overflow) Rd = 0x7FFFFFFF;
|
|
||||||
else if(underflow) Rd = ULL(0xFFFFFFFF80000000);
|
|
||||||
} }},
|
|
||||||
{{0}},
|
|
||||||
{{overflow || underflow}},
|
|
||||||
{{0}},
|
|
||||||
{{0}}
|
|
||||||
);
|
|
||||||
0x20: taddcc({{
|
0x20: taddcc({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = resTemp = Rs1 + val2;
|
Rd = res = Rs1 + op2;
|
||||||
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
|
}}, iv={{
|
||||||
{{((Rs1<31:0> + val2<31:0>)<32:0>)}},
|
(op1 & mask(2)) || (op2 & mask(2)) ||
|
||||||
{{overflow}},
|
findOverflow(32, res, op1, op2)
|
||||||
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
|
}});
|
||||||
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
|
|
||||||
);
|
|
||||||
0x21: tsubcc({{
|
0x21: tsubcc({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = resTemp = Rs1 + val2;
|
Rd = res = Rs1 - op2;
|
||||||
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
|
}}, iv={{
|
||||||
{{(Rs1<31:0> + val2<31:0>)<32:0>}},
|
(op1 & mask(2)) || (op2 & mask(2)) ||
|
||||||
{{overflow}},
|
findOverflow(32, res, op1, ~op2)
|
||||||
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
|
}}, sub=True);
|
||||||
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
|
|
||||||
);
|
|
||||||
0x22: taddcctv({{
|
0x22: taddcctv({{
|
||||||
int64_t val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = Rs1 + val2;
|
Rd = res = op1 + op2;
|
||||||
int32_t overflow = Rs1<1:0> || val2<1:0> ||
|
bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
|
||||||
(Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>);
|
findOverflow(32, res, op1, op2);
|
||||||
if(overflow) fault = new TagOverflow;}},
|
if(overflow) fault = new TagOverflow;
|
||||||
{{((Rs1<31:0> + val2<31:0>)<32:0>)}},
|
}}, iv={{overflow}});
|
||||||
{{overflow}},
|
|
||||||
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
|
|
||||||
{{Rs1<63:> == val2<63:> && val2<63:> != Rd<63:>}}
|
|
||||||
);
|
|
||||||
0x23: tsubcctv({{
|
0x23: tsubcctv({{
|
||||||
int64_t resTemp, val2 = Rs2_or_imm13;
|
int64_t res, op1 = Rs1, op2 = Rs2_or_imm13;
|
||||||
Rd = resTemp = Rs1 + val2;
|
Rd = res = op1 - op2;
|
||||||
int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
|
bool overflow = (op1 & mask(2)) || (op2 & mask(2)) ||
|
||||||
if(overflow) fault = new TagOverflow;}},
|
findOverflow(32, res, op1, ~op2);
|
||||||
{{((Rs1<31:0> + val2<31:0>)<32:0>)}},
|
if(overflow) fault = new TagOverflow;
|
||||||
{{overflow}},
|
}}, iv={{overflow}}, sub=True);
|
||||||
{{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
|
|
||||||
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
|
|
||||||
);
|
|
||||||
0x24: mulscc({{
|
0x24: mulscc({{
|
||||||
int32_t savedLSB = Rs1<0:>;
|
int32_t savedLSB = Rs1<0:>;
|
||||||
|
|
||||||
//Step 1
|
//Step 1
|
||||||
int64_t multiplicand = Rs2_or_imm13;
|
int64_t multiplicand = Rs2_or_imm13;
|
||||||
//Step 2
|
//Step 2
|
||||||
int32_t partialP = Rs1<31:1> |
|
int32_t partialP = Rs1<31:1> |
|
||||||
((Ccr<3:3> ^ Ccr<1:1>) << 31);
|
((Ccr<3:3> ^ Ccr<1:1>) << 31);
|
||||||
//Step 3
|
//Step 3
|
||||||
int32_t added = Y<0:> ? multiplicand : 0;
|
int32_t added = Y<0:> ? multiplicand : 0;
|
||||||
Rd = partialP + added;
|
int64_t res, op1 = partialP, op2 = added;
|
||||||
//Steps 4 & 5
|
Rd = res = partialP + added;
|
||||||
Y = Y<31:1> | (savedLSB << 31);}},
|
//Steps 4 & 5
|
||||||
{{((partialP<31:0> + added<31:0>)<32:0>)}},
|
Y = Y<31:1> | (savedLSB << 31);
|
||||||
{{partialP<31:> == added<31:> && added<31:> != Rd<31:>}},
|
}});
|
||||||
{{((partialP >> 1) + (added >> 1) + (partialP & added & 0x1))<63:>}},
|
|
||||||
{{partialP<63:> == added<63:> && partialP<63:> != Rd<63:>}}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
format IntOp
|
format IntOp
|
||||||
{
|
{
|
||||||
|
|
|
@ -287,10 +287,10 @@ let {{
|
||||||
_iz = ((Rd & 0xFFFFFFFF) == 0);
|
_iz = ((Rd & 0xFFFFFFFF) == 0);
|
||||||
_xn = (Rd >> 63) & 1;
|
_xn = (Rd >> 63) & 1;
|
||||||
_xz = (Rd == 0);
|
_xz = (Rd == 0);
|
||||||
_iv = %(ivValue)s & 1;
|
_iv = %(iv)s & 1;
|
||||||
_ic = %(icValue)s & 1;
|
_ic = %(ic)s & 1;
|
||||||
_xv = %(xvValue)s & 1;
|
_xv = %(xv)s & 1;
|
||||||
_xc = %(xcValue)s & 1;
|
_xc = %(xc)s & 1;
|
||||||
|
|
||||||
Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
|
Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
|
||||||
_xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
|
_xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
|
||||||
|
@ -305,6 +305,15 @@ let {{
|
||||||
DPRINTF(Sparc, "xv = %%d\\n", _xv);
|
DPRINTF(Sparc, "xv = %%d\\n", _xv);
|
||||||
DPRINTF(Sparc, "xc = %%d\\n", _xc);
|
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:
|
// Primary format for integer operate instructions:
|
||||||
|
@ -318,7 +327,24 @@ def format IntOp(code, *opt_flags) {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Primary format for integer operate instructions:
|
// 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()
|
ccCode = calcCcCode % vars()
|
||||||
(header_output,
|
(header_output,
|
||||||
decoder_output,
|
decoder_output,
|
||||||
|
@ -328,11 +354,8 @@ def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Primary format for integer operate instructions:
|
// Primary format for integer operate instructions:
|
||||||
def format IntOpCcRes(code, *opt_flags) {{
|
def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{
|
||||||
ccCode = calcCcCode % {"icValue":"0",
|
ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv}
|
||||||
"ivValue":"0",
|
|
||||||
"xcValue":"0",
|
|
||||||
"xvValue":"0"}
|
|
||||||
(header_output,
|
(header_output,
|
||||||
decoder_output,
|
decoder_output,
|
||||||
exec_output,
|
exec_output,
|
||||||
|
|
|
@ -41,6 +41,7 @@ output header {{
|
||||||
#include "arch/sparc/faults.hh"
|
#include "arch/sparc/faults.hh"
|
||||||
#include "arch/sparc/isa_traits.hh"
|
#include "arch/sparc/isa_traits.hh"
|
||||||
#include "arch/sparc/regfile.hh"
|
#include "arch/sparc/regfile.hh"
|
||||||
|
#include "base/condcodes.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
#include "cpu/static_inst.hh"
|
#include "cpu/static_inst.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
|
Loading…
Reference in a new issue