SPARC: Clean up the branch instructions a bit.

--HG--
extra : convert_revision : 93d5cc68e4a327ee0492eeed7f3b56e98d2d83bb
This commit is contained in:
Gabe Black
2007-09-25 20:05:11 -07:00
parent 9ef0f6a7f1
commit 8d53fea210
3 changed files with 198 additions and 213 deletions

View 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)}});
}
}
}

View 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,

View 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)
def template BranchExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
NNPC = NPC + 8;
NPC = NPC + 4;
//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;
}
else
{
NPC = NPC;
NNPC = NNPC;
}
}'''
}};
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)
}};