1// -*- mode:c++ -*- 2 3// Copyright (c) 2007-2008 The Florida State University 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Stephen Hines 30 31//////////////////////////////////////////////////////////////////// 32// 33// Predicated Instruction Execution 34// 35 36output header {{ 37#include <iostream> 38
|
39 enum ArmPredicateBits {
40 COND_EQ = 0,
41 COND_NE, // 1
42 COND_CS, // 2
43 COND_CC, // 3
44 COND_MI, // 4
45 COND_PL, // 5
46 COND_VS, // 6
47 COND_VC, // 7
48 COND_HI, // 8
49 COND_LS, // 9
50 COND_GE, // 10
51 COND_LT, // 11
52 COND_GT, // 12
53 COND_LE, // 13
54 COND_AL, // 14
55 COND_NV // 15
56 };
57
|
39 inline uint32_t 40 rotate_imm(uint32_t immValue, uint32_t rotateValue) 41 { 42 return ((immValue >> (int)(rotateValue & 31)) | 43 (immValue << (32 - (int)(rotateValue & 31)))); 44 } 45
|
65 inline uint32_t nSet(uint32_t cpsr) { return cpsr & (1<<31); }
66 inline uint32_t zSet(uint32_t cpsr) { return cpsr & (1<<30); }
67 inline uint32_t cSet(uint32_t cpsr) { return cpsr & (1<<29); }
68 inline uint32_t vSet(uint32_t cpsr) { return cpsr & (1<<28); }
69
70 inline bool arm_predicate(uint32_t cpsr, uint32_t predBits)
71 {
72
73 enum ArmPredicateBits armPredBits = (enum ArmPredicateBits) predBits;
74 uint32_t result = 0;
75 switch (armPredBits)
76 {
77 case COND_EQ:
78 result = zSet(cpsr); break;
79 case COND_NE:
80 result = !zSet(cpsr); break;
81 case COND_CS:
82 result = cSet(cpsr); break;
83 case COND_CC:
84 result = !cSet(cpsr); break;
85 case COND_MI:
86 result = nSet(cpsr); break;
87 case COND_PL:
88 result = !nSet(cpsr); break;
89 case COND_VS:
90 result = vSet(cpsr); break;
91 case COND_VC:
92 result = !vSet(cpsr); break;
93 case COND_HI:
94 result = cSet(cpsr) && !zSet(cpsr); break;
95 case COND_LS:
96 result = !cSet(cpsr) || zSet(cpsr); break;
97 case COND_GE:
98 result = (!nSet(cpsr) && !vSet(cpsr)) || (nSet(cpsr) && vSet(cpsr)); break;
99 case COND_LT:
100 result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)); break;
101 case COND_GT:
102 result = (!nSet(cpsr) && !vSet(cpsr) && !zSet(cpsr)) || (nSet(cpsr) && vSet(cpsr) && !zSet(cpsr)); break;
103 case COND_LE:
104 result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)) || zSet(cpsr); break;
105 case COND_AL: result = 1; break;
106 case COND_NV: result = 0; break;
107 default:
108 fprintf(stderr, "Unhandled predicate condition: %d\n", armPredBits);
109 exit(1);
110 }
111 if (result)
112 return true;
113 else
114 return false;
115 }
116
117
|
46 /** 47 * Base class for predicated integer operations. 48 */ 49 class PredOp : public ArmStaticInst 50 {
|
123 protected:
|
51 protected: |
52
|
125 uint32_t condCode;
|
53 ArmISA::ConditionCode condCode; |
54
|
127 /// Constructor
128 PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
129 ArmStaticInst(mnem, _machInst, __opClass),
130 condCode(COND_CODE)
131 {
132 }
|
55 /// Constructor 56 PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 57 ArmStaticInst(mnem, _machInst, __opClass), 58 condCode((ArmISA::ConditionCode)COND_CODE) 59 { 60 } |
61
|
134 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
|
62 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; |
63 }; 64 65 /** 66 * Base class for predicated immediate operations. 67 */ 68 class PredImmOp : public PredOp 69 { 70 protected: 71 72 uint32_t imm; 73 uint32_t rotate; 74 uint32_t rotated_imm; 75 uint32_t rotated_carry; 76 77 /// Constructor 78 PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 79 PredOp(mnem, _machInst, __opClass), 80 imm(IMM), rotate(ROTATE << 1), rotated_imm(0), 81 rotated_carry(0) 82 { 83 rotated_imm = rotate_imm(imm, rotate); 84 if (rotate != 0) 85 rotated_carry = (rotated_imm >> 31) & 1; 86 } 87 88 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 89 }; 90 91 /** 92 * Base class for predicated integer operations. 93 */ 94 class PredIntOp : public PredOp 95 { 96 protected: 97 98 uint32_t shift_size; 99 uint32_t shift; 100 101 /// Constructor 102 PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 103 PredOp(mnem, _machInst, __opClass), 104 shift_size(SHIFT_SIZE), shift(SHIFT) 105 { 106 } 107 108 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 109 }; 110 111 /** 112 * Base class for predicated macro-operations. 113 */ 114 class PredMacroOp : public PredOp 115 { 116 protected: 117 118 uint32_t numMicroops; 119 StaticInstPtr * microOps; 120 121 /// Constructor 122 PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 123 PredOp(mnem, _machInst, __opClass), 124 numMicroops(0) 125 { 126 // We rely on the subclasses of this object to handle the 127 // initialization of the micro-operations, since they are 128 // all of variable length 129 flags[IsMacroop] = true; 130 } 131 132 ~PredMacroOp() 133 { 134 if (numMicroops) 135 delete [] microOps; 136 } 137 138 StaticInstPtr fetchMicroop(MicroPC microPC) 139 { 140 assert(microPC < numMicroops); 141 return microOps[microPC]; 142 } 143 144 %(BasicExecPanic)s 145 146 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 147 }; 148 149 /** 150 * Base class for predicated micro-operations. 151 */ 152 class PredMicroop : public PredOp 153 { 154 /// Constructor 155 PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : 156 PredOp(mnem, _machInst, __opClass) 157 { 158 flags[IsMicroop] = true; 159 } 160 }; 161 162}}; 163 164def template PredOpExecute {{ 165 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 166 { 167 Fault fault = NoFault; 168 169 %(fp_enable_check)s; 170 %(op_decl)s; 171 %(op_rd)s; 172 %(code)s; 173
|
246 if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode))
|
174 if (testPredicate(xc->readMiscReg(ArmISA::MISCREG_CPSR), condCode)) |
175 { 176 if (fault == NoFault) 177 { 178 %(op_wb)s; 179 } 180 } 181 else 182 return NoFault; 183 // Predicated false instructions should not return faults 184 185 return fault; 186 } 187}}; 188 189//Outputs to decoder.cc 190output decoder {{ 191 std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 192 { 193 std::stringstream ss; 194 195 ccprintf(ss, "%-10s ", mnemonic); 196 197 if (_numDestRegs > 0) { 198 printReg(ss, _destRegIdx[0]); 199 } 200 201 ss << ", "; 202 203 if (_numSrcRegs > 0) { 204 printReg(ss, _srcRegIdx[0]); 205 ss << ", "; 206 } 207 208 return ss.str(); 209 } 210 211 std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 212 { 213 std::stringstream ss; 214 215 ccprintf(ss, "%-10s ", mnemonic); 216 217 if (_numDestRegs > 0) { 218 printReg(ss, _destRegIdx[0]); 219 } 220 221 ss << ", "; 222 223 if (_numSrcRegs > 0) { 224 printReg(ss, _srcRegIdx[0]); 225 ss << ", "; 226 } 227 228 return ss.str(); 229 } 230 231 std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 232 { 233 std::stringstream ss; 234 235 ccprintf(ss, "%-10s ", mnemonic); 236 237 if (_numDestRegs > 0) { 238 printReg(ss, _destRegIdx[0]); 239 } 240 241 ss << ", "; 242 243 if (_numSrcRegs > 0) { 244 printReg(ss, _srcRegIdx[0]); 245 ss << ", "; 246 } 247 248 return ss.str(); 249 } 250 251 std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 252 { 253 std::stringstream ss; 254 255 ccprintf(ss, "%-10s ", mnemonic); 256 257 return ss.str(); 258 } 259 260}}; 261 262let {{ 263 264 calcCcCode = ''' 265 uint16_t _ic, _iv, _iz, _in; 266 267 _in = (resTemp >> 31) & 1; 268 _iz = (resTemp == 0); 269 _iv = %(ivValue)s & 1; 270 _ic = %(icValue)s & 1; 271 272 Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | 273 (Cpsr & 0x0FFFFFFF); 274 275 DPRINTF(Arm, "in = %%d\\n", _in); 276 DPRINTF(Arm, "iz = %%d\\n", _iz); 277 DPRINTF(Arm, "ic = %%d\\n", _ic); 278 DPRINTF(Arm, "iv = %%d\\n", _iv); 279 ''' 280 281}}; 282 283def format PredOp(code, *opt_flags) {{ 284 iop = InstObjParams(name, Name, 'PredOp', code, opt_flags) 285 header_output = BasicDeclare.subst(iop) 286 decoder_output = BasicConstructor.subst(iop) 287 decode_block = BasicDecode.subst(iop) 288 exec_output = PredOpExecute.subst(iop) 289}}; 290 291def format PredImmOp(code, *opt_flags) {{ 292 iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags) 293 header_output = BasicDeclare.subst(iop) 294 decoder_output = BasicConstructor.subst(iop) 295 decode_block = BasicDecode.subst(iop) 296 exec_output = PredOpExecute.subst(iop) 297}}; 298 299def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{ 300 ccCode = calcCcCode % vars() 301 code += ccCode; 302 iop = InstObjParams(name, Name, 'PredImmOp', 303 {"code": code, "cc_code": ccCode}, opt_flags) 304 header_output = BasicDeclare.subst(iop) 305 decoder_output = BasicConstructor.subst(iop) 306 decode_block = BasicDecode.subst(iop) 307 exec_output = PredOpExecute.subst(iop) 308}}; 309 310def format PredIntOp(code, *opt_flags) {{ 311 new_code = ArmGenericCodeSubs(code) 312 iop = InstObjParams(name, Name, 'PredIntOp', new_code, opt_flags) 313 header_output = BasicDeclare.subst(iop) 314 decoder_output = BasicConstructor.subst(iop) 315 decode_block = BasicDecode.subst(iop) 316 exec_output = PredOpExecute.subst(iop) 317}}; 318 319def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{ 320 ccCode = calcCcCode % vars() 321 code += ccCode; 322 new_code = ArmGenericCodeSubs(code) 323 iop = InstObjParams(name, Name, 'PredIntOp', 324 {"code": new_code, "cc_code": ccCode }, opt_flags) 325 header_output = BasicDeclare.subst(iop) 326 decoder_output = BasicConstructor.subst(iop) 327 decode_block = BasicDecode.subst(iop) 328 exec_output = PredOpExecute.subst(iop) 329}}; 330
|