From 902009db2b93ac74be8954cfbfd5fb15dc472d0c Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:16:43 +0530 Subject: [PATCH] arch-power: Fix branch conditional instructions Among the register-based conditional branch instructions, the ones using CTR should not decrement CTR when the bit corresponding to this action is set in the BO field of the instruction. In this case, the instruction should be considered invalid. This fixes the following instructions. * Branch Conditional to Count Register (bcctr[l]) Change-Id: Ib2dbf2bc36fced580b4b7f7b76783f68361f6bbf Signed-off-by: Sandipan Das --- src/arch/power/isa/bitfields.isa | 1 + src/arch/power/isa/formats/branch.isa | 20 ++++++++++++++------ src/arch/power/isa/formats/util.isa | 12 ++++++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa index 3ea6d8c36..771a82258 100644 --- a/src/arch/power/isa/bitfields.isa +++ b/src/arch/power/isa/bitfields.isa @@ -69,6 +69,7 @@ def bitfield SPR <20:11>; def bitfield FXM <19:12>; // Branch fields +def bitfield BO <25:21>; def bitfield LK <0>; def bitfield AA <1>; diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa index 6b046df0c..b107cb34a 100644 --- a/src/arch/power/isa/formats/branch.isa +++ b/src/arch/power/isa/formats/branch.isa @@ -204,12 +204,20 @@ def format BranchRegCondOp(code, checkCTR = 0, inst_flags = []) {{ inst_flags_lk1 += [ 'IsCall' ] # Generate the classes - (header_output, decoder_output, decode_block, exec_output) = \ - 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) + if checkCTR: + (header_output, decoder_output, decode_block, exec_output) = \ + 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) + else: + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCondOp', code, inst_flags, + CheckBoLkDecode, BasicConstructor) + (header_output_lk1, decoder_output_lk1, _, exec_output_lk1) = \ + GenAluOp(name, Name + 'LkSet', 'BranchRegCondOp', code_lk1, + inst_flags_lk1, CheckBoLkDecode, BranchLkConstructor) # Finally, add to the other outputs header_output += header_output_lk1 diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa index 34bebb0ed..99daeb34d 100644 --- a/src/arch/power/isa/formats/util.isa +++ b/src/arch/power/isa/formats/util.isa @@ -111,6 +111,18 @@ def template CheckAaLkDecode {{ } }}; +def template CheckBoLkDecode {{ + { + if (!(BO & 0x4)) { + return new Unknown(machInst); + } else if (LK == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sLkSet(machInst); + } + } +}}; + let {{ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, -- 2.30.2