Sandipan Das has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/40886 )
Change subject: arch-power: Refactor branch instructions
......................................................................
arch-power: Refactor branch instructions
This changes the base classes for branch instructions and
switches to two high-level classes for unconditional and
conditional branches. The conditional branches are further
classified based on whether they use an immediate field or
a register for determining the target address.
Decoding has also been consolidated using formats that can
generate code after determining if an instruction branches
to an absolute address or a PC-relative address, or if it
implicitly sets the return address by looking at the AA and
LK bits.
Change-Id: I5fa7db7b6693586b4ea3c71e5cad8a60753de29c
Signed-off-by: Sandipan Das <[email protected]>
---
M src/arch/power/insts/branch.cc
M src/arch/power/insts/branch.hh
M src/arch/power/isa/decoder.isa
M src/arch/power/isa/formats/branch.isa
M src/arch/power/isa/formats/util.isa
M src/arch/power/types.hh
6 files changed, 268 insertions(+), 331 deletions(-)
diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc
index 72e4412..26a3c74 100644
--- a/src/arch/power/insts/branch.cc
+++ b/src/arch/power/insts/branch.cc
@@ -52,21 +52,32 @@
return *cachedDisassembly;
}
+
PowerISA::PCState
-BranchPCRel::branchTarget(const PowerISA::PCState &pc) const
+BranchOp::branchTarget(const PowerISA::PCState &pc) const
{
- return (uint32_t)(pc.pc() + disp);
+ if (aaSet) {
+ return disp;
+ } else {
+ return pc.pc() + disp;
+ }
}
+
std::string
-BranchPCRel::generateDisassembly(
+BranchOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream ss;
+ Addr target;
ccprintf(ss, "%-10s ", mnemonic);
- Addr target = pc + disp;
+ if (aaSet) {
+ target = disp;
+ } else {
+ target = pc + disp;
+ }
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(target)) != symtab->end())
@@ -77,46 +88,35 @@
return ss.str();
}
+
PowerISA::PCState
-BranchNonPCRel::branchTarget(const PowerISA::PCState &pc) const
+BranchDispCondOp::branchTarget(const PowerISA::PCState &pc) const
{
- return targetAddr;
+ if (aaSet) {
+ return disp;
+ } else {
+ return pc.pc() + disp;
+ }
}
+
std::string
-BranchNonPCRel::generateDisassembly(
+BranchDispCondOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream ss;
+ Addr target;
ccprintf(ss, "%-10s ", mnemonic);
- Loader::SymbolTable::const_iterator it;
- if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
- ss << it->name;
- else
- ccprintf(ss, "%#x", targetAddr);
+ // Print BI and BO fields
+ ss << crBit << ", " << opts << ", ";
- return ss.str();
-}
-
-PowerISA::PCState
-BranchPCRelCond::branchTarget(const PowerISA::PCState &pc) const
-{
- return (uint32_t)(pc.pc() + disp);
-}
-
-std::string
-BranchPCRelCond::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
-{
- std::stringstream ss;
-
- ccprintf(ss, "%-10s ", mnemonic);
-
- ss << bo << ", " << bi << ", ";
-
- Addr target = pc + disp;
+ if (aaSet) {
+ target = disp;
+ } else {
+ target = pc + disp;
+ }
Loader::SymbolTable::const_iterator it;
if (symtab && (it = symtab->find(target)) != symtab->end())
@@ -127,47 +127,25 @@
return ss.str();
}
+
PowerISA::PCState
-BranchNonPCRelCond::branchTarget(const PowerISA::PCState &pc) const
+BranchRegCondOp::branchTarget(ThreadContext *tc) const
{
- return targetAddr;
+ Addr addr = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index());
+ return addr & -4ULL;
}
+
std::string
-BranchNonPCRelCond::generateDisassembly(
+BranchRegCondOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
- ss << bo << ", " << bi << ", ";
-
- Loader::SymbolTable::const_iterator it;
- if (symtab && (it = symtab->find(targetAddr)) != symtab->end())
- ss << it->name;
- else
- ccprintf(ss, "%#x", targetAddr);
-
- return ss.str();
-}
-
-PowerISA::PCState
-BranchRegCond::branchTarget(ThreadContext *tc) const
-{
- uint32_t regVal = tc->readIntReg(srcRegIdx(_numSrcRegs - 1).index());
- return regVal & 0xfffffffc;
-}
-
-std::string
-BranchRegCond::generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const
-{
- std::stringstream ss;
-
- ccprintf(ss, "%-10s ", mnemonic);
-
- ss << bo << ", " << bi << ", ";
+ // Print the BI and BO fields
+ ss << crBit << ", " << opts;
return ss.str();
}
diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh
index 435b4fd..8c311a2 100644
--- a/src/arch/power/insts/branch.hh
+++ b/src/arch/power/insts/branch.hh
@@ -63,25 +63,25 @@
disassemble(Addr pc, const Loader::SymbolTable *symtab) const;
};
+
/**
- * Base class for unconditional, PC-relative branches.
+ * Base class for unconditional, PC-relative or absolute address branches.
*/
-class BranchPCRel : public PCDependentDisassembly
+class BranchOp : public PCDependentDisassembly
{
protected:
- /// Displacement
- uint32_t disp;
+ bool aaSet;
+ bool lkSet;
+ uint64_t disp;
- /// Constructor.
- BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
- : PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(machInst.li << 2)
+ /// Constructor
+ BranchOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ aaSet(false),
+ lkSet(false),
+ disp(sext<26>(machInst.li << 2))
{
- // If bit 26 is 1 then sign extend
- if (disp & 0x2000000) {
- disp |= 0xfc000000;
- }
}
PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const
override;
@@ -93,104 +93,74 @@
Addr pc, const Loader::SymbolTable *symtab) const override;
};
-/**
- * Base class for unconditional, non PC-relative branches.
- */
-class BranchNonPCRel : public PCDependentDisassembly
-{
- protected:
-
- /// Target address
- uint32_t targetAddr;
-
- /// Constructor.
- BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass)
- : PCDependentDisassembly(mnem, _machInst, __opClass),
- targetAddr(machInst.li << 2)
- {
- // If bit 26 is 1 then sign extend
- if (targetAddr & 0x2000000) {
- targetAddr |= 0xfc000000;
- }
- }
-
- PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const
override;
-
- /// Explicitly import the otherwise hidden branchTarget
- using StaticInst::branchTarget;
-
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
-};
/**
* Base class for conditional branches.
*/
-class BranchCond : public PCDependentDisassembly
+class BranchCondOp : public PCDependentDisassembly
{
protected:
- /// Fields needed for conditions
- uint32_t bo;
- uint32_t bi;
+ bool lkSet;
+ uint32_t crBit;
+ uint32_t opts;
- /// Constructor.
- BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass)
- : PCDependentDisassembly(mnem, _machInst, __opClass),
- bo(machInst.bo),
- bi(machInst.bi)
+ /// Constructor
+ BranchCondOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ lkSet(false),
+ crBit(machInst.bi),
+ opts(machInst.bo)
{
}
inline bool
- ctrOk(uint32_t& ctr) const
+ checkCtr(uint64_t& ctr) const
{
- bool ctr_ok;
- if (bo & 4) {
- ctr_ok = true;
+ bool ctrOk;
+ if (opts & 0x4) {
+ ctrOk = true;
} else {
ctr--;
if (ctr != 0) {
- ctr_ok = ((bo & 2) == 0);
+ ctrOk = ((opts & 0x2) == 0);
} else {
- ctr_ok = ((bo & 2) != 0);
+ ctrOk = ((opts & 0x2) != 0);
}
}
- return ctr_ok;
+ return ctrOk;
}
inline bool
- condOk(uint32_t cr) const
+ checkCond(uint32_t cr) const
{
- bool cond_ok;
- if (bo & 16) {
- cond_ok = true;
+ bool condOk;
+ if (opts & 0x10) {
+ condOk = true;
} else {
- cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1));
+ condOk = (((cr >> (31 - crBit)) & 0x1) == ((opts >> 3) & 0x1));
}
- return cond_ok;
+ return condOk;
}
};
+
/**
- * Base class for conditional, PC-relative branches.
+ * Base class for conditional, PC-relative or absolute address branches.
*/
-class BranchPCRelCond : public BranchCond
+class BranchDispCondOp : public BranchCondOp
{
protected:
- /// Displacement
- uint32_t disp;
+ bool aaSet;
+ uint64_t disp;
- /// Constructor.
- BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass
__opClass)
- : BranchCond(mnem, _machInst, __opClass),
- disp(machInst.bd << 2)
+ /// Constructor
+ BranchDispCondOp(const char *mnem, MachInst _machInst, OpClass
__opClass)
+ : BranchCondOp(mnem, _machInst, __opClass),
+ aaSet(false),
+ disp(sext<16>(machInst.bd << 2))
{
- // If bit 16 is 1 then sign extend
- if (disp & 0x8000) {
- disp |= 0xffff0000;
- }
}
PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const
override;
@@ -202,46 +172,22 @@
Addr pc, const Loader::SymbolTable *symtab) const override;
};
+
/**
- * Base class for conditional, non PC-relative branches.
+ * Base class for conditional, register-based branches.
*/
-class BranchNonPCRelCond : public BranchCond
+class BranchRegCondOp : public BranchCondOp
{
protected:
- /// Target address
- uint32_t targetAddr;
+ // TODO: For now, the hint value (BH) is ignored and always considered
+ // to be zero. Instruction flags should vary depending on this.
+ uint32_t hint;
/// Constructor.
- BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass
__opClass)
- : BranchCond(mnem, _machInst, __opClass),
- targetAddr(machInst.bd << 2)
- {
- // If bit 16 is 1 then sign extend
- if (targetAddr & 0x8000) {
- targetAddr |= 0xffff0000;
- }
- }
-
- PowerISA::PCState branchTarget(const PowerISA::PCState &pc) const
override;
-
- /// Explicitly import the otherwise hidden branchTarget
- using StaticInst::branchTarget;
-
- std::string generateDisassembly(
- Addr pc, const Loader::SymbolTable *symtab) const override;
-};
-
-/**
- * Base class for conditional, register-based branches
- */
-class BranchRegCond : public BranchCond
-{
- protected:
-
- /// Constructor.
- BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass)
- : BranchCond(mnem, _machInst, __opClass)
+ BranchRegCondOp(const char *mnem, MachInst _machInst, OpClass
__opClass)
+ : BranchCondOp(mnem, _machInst, __opClass),
+ hint(machInst.bh)
{
}
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index 478b254..a58e947 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -36,42 +36,26 @@
//
decode PO default Unknown::unknown() {
- 18: decode AA {
-
- // Unconditionally branch relative to PC.
- format BranchPCRel {
- 0: b({{ NIA = (uint32_t)(CIA + disp); }});
- }
-
- // Unconditionally branch to fixed address.
- format BranchNonPCRel {
- 1: ba({{ NIA = targetAddr; }});
- }
+ // Unconditionally branch to a PC-relative or absoulute address.
+ format BranchOp {
+ 18: b({{ NIA = CIA + disp; }},
+ {{ NIA = disp; }});
}
- 16: decode AA {
-
- // Conditionally branch relative to PC based on CR and CTR.
- format BranchPCRelCondCtr {
- 0: bc({{ NIA = (uint32_t)(CIA + disp); }});
- }
-
- // Conditionally branch to fixed address based on CR and CTR.
- format BranchNonPCRelCondCtr {
- 1: bca({{ NIA = targetAddr; }});
- }
+ // Conditionally branch to a PC-relative or absoulute address based
+ // on CR and CTR.
+ format BranchDispCondOp {
+ 16: bc({{ NIA = CIA + disp; }},
+ {{ NIA = disp; }});
}
19: decode XL_XO {
- // Conditionally branch to address in LR based on CR and CTR.
- format BranchLrCondCtr {
- 16: bclr({{ NIA = LR & 0xfffffffc; }});
- }
-
- // Conditionally branch to address in CTR based on CR.
- format BranchCtrCond {
- 528: bcctr({{ NIA = CTR & 0xfffffffc; }});
+ // Conditionally branch to an address in a register based on
+ // either CR only or both CR and CTR.
+ format BranchRegCondOp {
+ 16: bclr({{ NIA = LR & -4ULL; }}, true, [ IsReturn ]);
+ 528: bcctr({{ NIA = CTR & -4ULL; }});
}
// Condition register manipulation instructions.
diff --git a/src/arch/power/isa/formats/branch.isa
b/src/arch/power/isa/formats/branch.isa
index 3481438..6b046df 100644
--- a/src/arch/power/isa/formats/branch.isa
+++ b/src/arch/power/isa/formats/branch.isa
@@ -39,10 +39,47 @@
// - Do not use bclrl as a subroutine call.
//
// Therefore, I've flagged all versions that update the link register (LR)
-// as calls, except bclrl (BranchLrCtrCond format) which is flagged as
+// as calls, except bclrl (BranchRegCondOp format) which is flagged as
// a return.
+// Instruction class constructor template when AA is set.
+def template BranchAaConstructor {{
+ %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ aaSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when LK is set.
+def template BranchLkConstructor {{
+ %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ lkSet = true;
+ }
+}};
+
+
+// Instruction class constructor template when both AA and LK are set.
+def template BranchAaLkConstructor {{
+ %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+ {
+ %(set_reg_idx_arr)s;
+ %(constructor)s;
+ aaSet = true;
+ lkSet = true;
+ }
+}};
+
+
let {{
# Simple code to update link register (LR).
@@ -50,57 +87,45 @@
}};
-// Instructions that unconditionally branch relative to the current PC.
-def format BranchPCRel(br_code, inst_flags = []) {{
+
+// Instructions that unconditionally branch either to an address relative
+// to the current PC or an absolute address.
+def format BranchOp(code, code_aa1, inst_flags = []) {{
inst_flags += ('IsUncondControl', 'IsDirectControl')
- basic_code = br_code
- # The version that does not update LR
+ # Setup the 4 code versions and add code to update LR if necessary
+ code_lk1 = code + updateLrCode
+ code_aa1_lk1 = code_aa1 + updateLrCode
+
+ # Generate the classes
(header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags,
- CheckLkDecode, BasicConstructor)
+ GenAluOp(name, Name, 'BranchOp', code, inst_flags,
+ CheckAaLkDecode, BasicConstructor)
+ (header_output_aa1, decoder_output_aa1, _, exec_output_aa1) = \
+ GenAluOp(name, Name + 'AaSet', 'BranchOp', code_aa1, inst_flags,
+ CheckAaLkDecode, BranchAaConstructor)
+ (header_output_lk1, decoder_output_lk1, _, exec_output_lk1) = \
+ GenAluOp(name, Name + 'LkSet', 'BranchOp', code_lk1, inst_flags,
+ CheckAaLkDecode, BranchLkConstructor)
+ (header_output_aa1_lk1, decoder_output_aa1_lk1, _,
exec_output_aa1_lk1) = \
+ GenAluOp(name, Name + 'AaSetLkSet', 'BranchOp', code_aa1_lk1,
+ inst_flags, CheckAaLkDecode, BranchAaLkConstructor)
- # The version that does the update
- update_code = basic_code + updateLrCode
- update_flags = inst_flags + [ 'IsCall' ]
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code,
- update_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
+ # Finally, add to the other outputs
+ header_output += \
+ header_output_aa1 + header_output_lk1 + header_output_aa1_lk1
+ decoder_output += \
+ decoder_output_aa1 + decoder_output_lk1 + decoder_output_aa1_lk1
+ exec_output += \
+ exec_output_aa1 + exec_output_lk1 + exec_output_aa1_lk1
}};
-// Instructions that unconditionally branch to a specific address.
-def format BranchNonPCRel(br_code, inst_flags = []) {{
- inst_flags += ('IsUncondControl', 'IsDirectControl')
- basic_code = br_code
-
- # The version that does not update LR
- (header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags,
- CheckLkDecode, BasicConstructor)
-
- # The version that does the update
- update_code = basic_code + updateLrCode
- update_flags = inst_flags + [ 'IsCall' ]
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code,
- update_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
-}};
let {{
# Check the condition register (CR) allows the branch to be taken.
def GetCondCode(br_code):
- cond_code = 'if(condOk(CR)) {\n'
+ cond_code = 'if (checkCond(CR)) {\n'
cond_code += ' ' + br_code + '\n'
cond_code += '} else {\n'
cond_code += ' NIA = NIA;\n'
@@ -109,12 +134,12 @@
# Check the condition register (CR) and count register (CTR) allow the
# branch to be taken. Also, in certain situations, decrement the count
-# register too. This takes place in ctrOk within BranchCond classes.
+# register too. This takes place in checkCtr within BranchCondOp classes.
def GetCtrCondCode(br_code):
- cond_code = 'uint32_t ctr = CTR;\n'
- cond_code += 'bool ctr_ok = ctrOk(ctr);\n'
- cond_code += 'bool cond_ok = condOk(CR);\n'
- cond_code += 'if(ctr_ok && cond_ok) {\n'
+ cond_code = 'uint64_t ctr = CTR;\n'
+ cond_code += 'bool ctrOk = checkCtr(ctr);\n'
+ cond_code += 'bool condOk = checkCond(CR);\n'
+ cond_code += 'if (ctrOk && condOk) {\n'
cond_code += ' ' + br_code + '\n'
cond_code += '} else {\n'
cond_code += ' NIA = NIA;\n'
@@ -124,97 +149,70 @@
}};
-// Instructions that conditionally branch relative to the current PC based
on
-// the condition register (CR) and count register (CTR).
-def format BranchPCRelCondCtr(br_code, inst_flags = []) {{
- inst_flags += ('IsCondControl', 'IsDirectControl')
- basic_code = GetCtrCondCode(br_code)
- # The version that does not update LR
- (header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags,
- CheckLkDecode, BasicConstructor)
-
- # The version that does the update
- update_code = basic_code + updateLrCode
- update_flags = inst_flags + [ 'IsCall' ]
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code,
- update_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
-}};
-
-// Instructions that conditionally branch to a specific address based on
the
+// Instructions that conditionally branch either to an address relative
+// to the current PC or an absolute address depending on the value of the
// condition register (CR) and count register (CTR).
-def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{
+def format BranchDispCondOp(code, code_aa1, inst_flags = []) {{
inst_flags += ('IsCondControl', 'IsDirectControl')
- basic_code = GetCtrCondCode(br_code)
- # The version that does not update LR
+ # Setup the 4 code versions and add code to update LR if necessary
+ code = GetCtrCondCode(code)
+ code_aa1 = GetCtrCondCode(code_aa1)
+ code_lk1 = code + updateLrCode
+ code_aa1_lk1 = code_aa1 + updateLrCode
+ inst_flags_lk1 = inst_flags + [ 'IsCall' ]
+
+ # Generate the classes
(header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags,
- CheckLkDecode, BasicConstructor)
+ GenAluOp(name, Name, 'BranchDispCondOp', code, inst_flags,
+ CheckAaLkDecode, BasicConstructor)
+ (header_output_aa1, decoder_output_aa1, _, exec_output_aa1) = \
+ GenAluOp(name, Name + 'AaSet', 'BranchDispCondOp', code_aa1,
+ inst_flags, CheckAaLkDecode, BranchAaConstructor)
+ (header_output_lk1, decoder_output_lk1, _, exec_output_lk1) = \
+ GenAluOp(name, Name + 'LkSet', 'BranchDispCondOp', code_lk1,
+ inst_flags_lk1, CheckAaLkDecode, BranchLkConstructor)
+ (header_output_aa1_lk1, decoder_output_aa1_lk1, _,
exec_output_aa1_lk1) = \
+ GenAluOp(name, Name + 'AaSetLkSet', 'BranchDispCondOp',
code_aa1_lk1,
+ inst_flags_lk1, CheckAaLkDecode, BranchAaLkConstructor)
- # The version that does the update
- update_code = basic_code + updateLrCode
- update_flags = inst_flags + [ 'IsCall' ]
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond',
update_code,
- update_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
+ # Finally, add to the other outputs
+ header_output += \
+ header_output_aa1 + header_output_lk1 + header_output_aa1_lk1
+ decoder_output += \
+ decoder_output_aa1 + decoder_output_lk1 + decoder_output_aa1_lk1
+ exec_output += \
+ exec_output_aa1 + exec_output_lk1 + exec_output_aa1_lk1
}};
-// Instructions that conditionally branch to the address in the link
register
-// (LR) based on the condition register (CR) and count register (CTR).
-def format BranchLrCondCtr(br_code, inst_flags = []) {{
- inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn')
- basic_code = GetCtrCondCode(br_code)
- # The version that does not update LR
- (header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
- CheckLkDecode, BasicConstructor)
-
- # The version that does the update
- update_code = basic_code + updateLrCode
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
- inst_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
-}};
-
-// Instructions that conditionally branch to the address in the count
register
-// (CTR) based on the condition register (CR).
-def format BranchCtrCond(br_code, inst_flags = []) {{
+// Instructions that conditionally branch to an address in a register
+// depending on the value of the condition register (CR) and count
+// register (CTR).
+def format BranchRegCondOp(code, checkCTR = 0, inst_flags = []) {{
inst_flags += ('IsCondControl', 'IsIndirectControl')
- basic_code = GetCondCode(br_code)
- # The version that does not update LR
+ # Setup the 2 code versions and add code to update LR if necessary
+ if checkCTR:
+ code = GetCtrCondCode(code)
+ else:
+ code = GetCondCode(code)
+ code_lk1 = code + updateLrCode
+ inst_flags_lk1 = inst_flags
+ if 'IsReturn' not in inst_flags:
+ inst_flags_lk1 += [ 'IsCall' ]
+
+ # Generate the classes
(header_output, decoder_output, decode_block, exec_output) = \
- GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags,
+ GenAluOp(name, Name, 'BranchRegCondOp', code, inst_flags,
CheckLkDecode, BasicConstructor)
+ (header_output_lk1, decoder_output_lk1, _, exec_output_lk1) = \
+ GenAluOp(name, Name + 'LkSet', 'BranchRegCondOp', code_lk1,
+ inst_flags_lk1, CheckLkDecode, BranchLkConstructor)
- # The version that does the update
- update_code = basic_code + updateLrCode
- update_flags = inst_flags + [ 'IsCall' ]
- (header_output_up, decoder_output_up, _, exec_output_up) = \
- GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code,
- update_flags, CheckLkDecode, BasicConstructor)
-
- # Add the outputs together
- header_output += header_output_up
- decoder_output += decoder_output_up
- exec_output += exec_output_up
+ # Finally, add to the other outputs
+ header_output += header_output_lk1
+ decoder_output += decoder_output_lk1
+ exec_output += exec_output_lk1
}};
diff --git a/src/arch/power/isa/formats/util.isa
b/src/arch/power/isa/formats/util.isa
index 1bb78e6..34bebb0 100644
--- a/src/arch/power/isa/formats/util.isa
+++ b/src/arch/power/isa/formats/util.isa
@@ -78,11 +78,38 @@
if (LK == 0) {
return new %(class_name)s(machInst);
} else {
- return new %(class_name)sUpdateLr(machInst);
+ return new %(class_name)sLkSet(machInst);
}
}
}};
+def template CheckAaDecode {{
+ {
+ if (AA == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sAaSet(machInst);
+ }
+ }
+}};
+
+def template CheckAaLkDecode {{
+ {
+ if (AA == 0) {
+ if (LK == 0) {
+ return new %(class_name)s(machInst);
+ } else {
+ return new %(class_name)sLkSet(machInst);
+ }
+ } else {
+ if (LK == 0) {
+ return new %(class_name)sAaSet(machInst);
+ } else {
+ return new %(class_name)sAaSetLkSet(machInst);
+ }
+ }
+ }
+}};
let {{
diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh
index e37659c..c7cc4d0 100644
--- a/src/arch/power/types.hh
+++ b/src/arch/power/types.hh
@@ -55,14 +55,18 @@
// Special purpose register identifier
Bitfield<20, 11> spr;
- Bitfield<25, 2> li;
- Bitfield<1> aa;
Bitfield<25, 23> bf;
- Bitfield<15, 2> bd;
- Bitfield<25, 21> bo;
- Bitfield<20, 16> bi;
Bitfield<20, 18> bfa;
+ // Branch instruction fields
+ Bitfield<1> aa;
+ Bitfield<15, 2> bd;
+ Bitfield<20, 16> bi;
+ Bitfield<12, 11> bh;
+ Bitfield<25, 21> bo;
+ Bitfield<25, 2> li;
+ Bitfield<0> lk;
+
// Record bits
Bitfield<0> rc31;
Bitfield<10> oe;
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40886
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I5fa7db7b6693586b4ea3c71e5cad8a60753de29c
Gerrit-Change-Number: 40886
Gerrit-PatchSet: 1
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s