arch-power: Fix branch conditional instructions
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:46:43 +0000 (17:16 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:37 +0000 (14:02 +0530)
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 <sandipan@linux.ibm.com>
src/arch/power/isa/bitfields.isa
src/arch/power/isa/formats/branch.isa
src/arch/power/isa/formats/util.isa

index 3ea6d8c366863e3ec933ea81cb3869a6d2bbf9f4..771a822583f337d40235a135a0aa77fee09d6565 100644 (file)
@@ -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>;
 
index 6b046df0c47e7662e610f232c3e9a1f82ef78870..b107cb34a3348605e4d7d5b1b0564019ee9c674c 100644 (file)
@@ -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
index 34bebb0ed4fb1fa0c3c7d97e9a0c9d33063c8b82..99daeb34d120fb7541de2b233e8c590287bc7e78 100644 (file)
@@ -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,