1// -*- mode:c++ -*- 2 3// Copyright (c) 2010, 2014 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40def template BranchImmDeclare {{ 41class %(class_name)s : public %(base_class)s 42{ 43 public: 44 // Constructor 45 %(class_name)s(ExtMachInst machInst, int32_t _imm); 46 Fault execute(ExecContext *, Trace::InstRecord *) const override; 47}; 48}}; 49 50def template BranchImmConstructor {{ 51 %(class_name)s::%(class_name)s(ExtMachInst machInst, 52 int32_t _imm) 53 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm) 54 { 55 %(constructor)s; 56 if (!(condCode == COND_AL || condCode == COND_UC)) { 57 for (int x = 0; x < _numDestRegs; x++) { 58 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 59 } 60 flags[IsCondControl] = true; 61 } else { 62 flags[IsUncondControl] = true; 63 } 64 65 } 66}}; 67 68def template BranchImmCondDeclare {{ 69class %(class_name)s : public %(base_class)s 70{ 71 public: 72 // Constructor 73 %(class_name)s(ExtMachInst machInst, int32_t _imm, 74 ConditionCode _condCode); 75 Fault execute(ExecContext *, Trace::InstRecord *) const override; 76 ArmISA::PCState branchTarget( 77 const ArmISA::PCState &branchPC) const override; 78 79 /// Explicitly import the otherwise hidden branchTarget 80 using StaticInst::branchTarget; 81}; 82}}; 83 84def template BranchImmCondConstructor {{ 85 %(class_name)s::%(class_name)s(ExtMachInst machInst, 86 int32_t _imm, 87 ConditionCode _condCode) 88 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 89 _imm, _condCode) 90 { 91 %(constructor)s; 92 if (!(condCode == COND_AL || condCode == COND_UC)) { 93 for (int x = 0; x < _numDestRegs; x++) { 94 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 95 } 96 flags[IsCondControl] = true; 97 } else { 98 flags[IsUncondControl] = true; 99 } 100 } 101}}; 102 103def template BranchRegDeclare {{ 104class %(class_name)s : public %(base_class)s 105{ 106 public: 107 // Constructor 108 %(class_name)s(ExtMachInst machInst, IntRegIndex _op1); 109 Fault execute(ExecContext *, Trace::InstRecord *) const override; 110}; 111}}; 112 113def template BranchRegConstructor {{ 114 %(class_name)s::%(class_name)s(ExtMachInst machInst, 115 IntRegIndex _op1) 116 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1) 117 { 118 %(constructor)s; 119 if (!(condCode == COND_AL || condCode == COND_UC)) { 120 for (int x = 0; x < _numDestRegs; x++) { 121 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 122 } 123 flags[IsCondControl] = true; 124 } else { 125 flags[IsUncondControl] = true; 126 } 127 if (%(is_ras_pop)s) 128 flags[IsReturn] = true; 129 } 130}}; 131 132def template BranchRegCondDeclare {{ 133class %(class_name)s : public %(base_class)s 134{ 135 public: 136 // Constructor 137 %(class_name)s(ExtMachInst machInst, IntRegIndex _op1, 138 ConditionCode _condCode); 139 Fault execute(ExecContext *, Trace::InstRecord *) const override; 140}; 141}}; 142 143def template BranchRegCondConstructor {{ 144 %(class_name)s::%(class_name)s(ExtMachInst machInst, 145 IntRegIndex _op1, 146 ConditionCode _condCode) 147 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 148 _op1, _condCode) 149 { 150 %(constructor)s; 151 if (!(condCode == COND_AL || condCode == COND_UC)) { 152 for (int x = 0; x < _numDestRegs; x++) { 153 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 154 } 155 flags[IsCondControl] = true; 156 } else { 157 flags[IsUncondControl] = true; 158 } 159 if (%(is_ras_pop)s) 160 flags[IsReturn] = true; 161 } 162}}; 163 164def template BranchRegRegDeclare {{ 165class %(class_name)s : public %(base_class)s 166{ 167 public: 168 // Constructor 169 %(class_name)s(ExtMachInst machInst, 170 IntRegIndex _op1, IntRegIndex _op2); 171 Fault execute(ExecContext *, Trace::InstRecord *) const override; 172}; 173}}; 174 175def template BranchTableDeclare {{ 176class %(class_name)s : public %(base_class)s 177{ 178 public: 179 // Constructor 180 %(class_name)s(ExtMachInst machInst, 181 IntRegIndex _op1, IntRegIndex _op2); 182 Fault execute(ExecContext *, Trace::InstRecord *) const override; 183 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const override; 184 Fault completeAcc(PacketPtr, ExecContext *, 185 Trace::InstRecord *) const override; 186}; 187}}; 188 189def template BranchRegRegConstructor {{ 190 %(class_name)s::%(class_name)s(ExtMachInst machInst, 191 IntRegIndex _op1, 192 IntRegIndex _op2) 193 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _op1, _op2) 194 { 195 %(constructor)s; 196 if (!(condCode == COND_AL || condCode == COND_UC)) { 197 for (int x = 0; x < _numDestRegs; x++) { 198 _srcRegIdx[_numSrcRegs++] = _destRegIdx[x]; 199 } 200 flags[IsCondControl] = true; 201 } else { 202 flags[IsUncondControl] = true; 203 } 204 } 205}}; 206 207def template BranchImmRegDeclare {{ 208class %(class_name)s : public %(base_class)s 209{ 210 public: 211 // Constructor 212 %(class_name)s(ExtMachInst machInst, 213 int32_t imm, IntRegIndex _op1); 214 Fault execute(ExecContext *, Trace::InstRecord *) const override; 215 ArmISA::PCState branchTarget( 216 const ArmISA::PCState &branchPC) const override; 217 218 /// Explicitly import the otherwise hidden branchTarget 219 using StaticInst::branchTarget; 220}; 221}}; 222 223// Only used by CBNZ, CBZ which is conditional based on 224// a register value even though the instruction is always unconditional. 225def template BranchImmRegConstructor {{ 226 %(class_name)s::%(class_name)s(ExtMachInst machInst, 227 int32_t _imm, 228 IntRegIndex _op1) 229 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, _imm, _op1) 230 { 231 %(constructor)s; 232 flags[IsCondControl] = true; 233 } 234}}; 235 236def template BranchTarget {{ 237 238 ArmISA::PCState 239 %(class_name)s::branchTarget(const ArmISA::PCState &branchPC) const 240 { 241 %(op_decl)s; 242 %(op_rd)s; 243 244 ArmISA::PCState pcs = branchPC; 245 %(brTgtCode)s 246 pcs.advance(); 247 return pcs; 248 } 249}}; 250 251 252