pred.isa revision 6019
15425Sgblack@eecs.umich.edu// -*- mode:c++ -*- 25425Sgblack@eecs.umich.edu 35425Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Florida State University 47087Snate@binkert.org// All rights reserved. 57087Snate@binkert.org// 67087Snate@binkert.org// Redistribution and use in source and binary forms, with or without 77087Snate@binkert.org// modification, are permitted provided that the following conditions are 87087Snate@binkert.org// met: redistributions of source code must retain the above copyright 97087Snate@binkert.org// notice, this list of conditions and the following disclaimer; 107087Snate@binkert.org// redistributions in binary form must reproduce the above copyright 117087Snate@binkert.org// notice, this list of conditions and the following disclaimer in the 125425Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 137087Snate@binkert.org// neither the name of the copyright holders nor the names of its 147087Snate@binkert.org// contributors may be used to endorse or promote products derived from 157087Snate@binkert.org// this software without specific prior written permission. 167087Snate@binkert.org// 177087Snate@binkert.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 187087Snate@binkert.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 197087Snate@binkert.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 207087Snate@binkert.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215425Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 227087Snate@binkert.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235425Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245425Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255425Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265425Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275425Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285425Sgblack@eecs.umich.edu// 295425Sgblack@eecs.umich.edu// Authors: Stephen Hines 305425Sgblack@eecs.umich.edu 315425Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////// 325425Sgblack@eecs.umich.edu// 335425Sgblack@eecs.umich.edu// Predicated Instruction Execution 345425Sgblack@eecs.umich.edu// 355425Sgblack@eecs.umich.edu 365425Sgblack@eecs.umich.eduoutput header {{ 375425Sgblack@eecs.umich.edu#include <iostream> 385425Sgblack@eecs.umich.edu 395425Sgblack@eecs.umich.edu enum ArmPredicateBits { 405425Sgblack@eecs.umich.edu COND_EQ = 0, 415425Sgblack@eecs.umich.edu COND_NE, // 1 425425Sgblack@eecs.umich.edu COND_CS, // 2 435425Sgblack@eecs.umich.edu COND_CC, // 3 445425Sgblack@eecs.umich.edu COND_MI, // 4 455425Sgblack@eecs.umich.edu COND_PL, // 5 465425Sgblack@eecs.umich.edu COND_VS, // 6 475425Sgblack@eecs.umich.edu COND_VC, // 7 487965Sgblack@eecs.umich.edu COND_HI, // 8 497965Sgblack@eecs.umich.edu COND_LS, // 9 505425Sgblack@eecs.umich.edu COND_GE, // 10 515425Sgblack@eecs.umich.edu COND_LT, // 11 525425Sgblack@eecs.umich.edu COND_GT, // 12 535425Sgblack@eecs.umich.edu COND_LE, // 13 547965Sgblack@eecs.umich.edu COND_AL, // 14 557620Sgblack@eecs.umich.edu COND_NV // 15 567965Sgblack@eecs.umich.edu }; 577965Sgblack@eecs.umich.edu 587965Sgblack@eecs.umich.edu inline uint32_t 597965Sgblack@eecs.umich.edu rotate_imm(uint32_t immValue, uint32_t rotateValue) 605425Sgblack@eecs.umich.edu { 617965Sgblack@eecs.umich.edu return ((immValue >> (int)(rotateValue & 31)) | 627965Sgblack@eecs.umich.edu (immValue << (32 - (int)(rotateValue & 31)))); 637965Sgblack@eecs.umich.edu } 647965Sgblack@eecs.umich.edu 657965Sgblack@eecs.umich.edu inline uint32_t nSet(uint32_t cpsr) { return cpsr & (1<<31); } 667965Sgblack@eecs.umich.edu inline uint32_t zSet(uint32_t cpsr) { return cpsr & (1<<30); } 677965Sgblack@eecs.umich.edu inline uint32_t cSet(uint32_t cpsr) { return cpsr & (1<<29); } 687965Sgblack@eecs.umich.edu inline uint32_t vSet(uint32_t cpsr) { return cpsr & (1<<28); } 697965Sgblack@eecs.umich.edu 707965Sgblack@eecs.umich.edu inline bool arm_predicate(uint32_t cpsr, uint32_t predBits) 715425Sgblack@eecs.umich.edu { 725425Sgblack@eecs.umich.edu 735425Sgblack@eecs.umich.edu enum ArmPredicateBits armPredBits = (enum ArmPredicateBits) predBits; 745425Sgblack@eecs.umich.edu uint32_t result = 0; 755425Sgblack@eecs.umich.edu switch (armPredBits) 765425Sgblack@eecs.umich.edu { 775425Sgblack@eecs.umich.edu case COND_EQ: 785425Sgblack@eecs.umich.edu result = zSet(cpsr); break; 797620Sgblack@eecs.umich.edu case COND_NE: 805425Sgblack@eecs.umich.edu result = !zSet(cpsr); break; 8112236Sgabeblack@google.com case COND_CS: 825425Sgblack@eecs.umich.edu result = cSet(cpsr); break; 835425Sgblack@eecs.umich.edu case COND_CC: 845425Sgblack@eecs.umich.edu result = !cSet(cpsr); break; 855425Sgblack@eecs.umich.edu case COND_MI: 867965Sgblack@eecs.umich.edu result = nSet(cpsr); break; 8712234Sgabeblack@google.com case COND_PL: 885425Sgblack@eecs.umich.edu result = !nSet(cpsr); break; 895425Sgblack@eecs.umich.edu case COND_VS: 905425Sgblack@eecs.umich.edu result = vSet(cpsr); break; 915425Sgblack@eecs.umich.edu case COND_VC: 925425Sgblack@eecs.umich.edu result = !vSet(cpsr); break; 9310474Sandreas.hansson@arm.com case COND_HI: 9410474Sandreas.hansson@arm.com result = cSet(cpsr) && !zSet(cpsr); break; 957965Sgblack@eecs.umich.edu case COND_LS: 967965Sgblack@eecs.umich.edu result = !cSet(cpsr) || zSet(cpsr); break; 975425Sgblack@eecs.umich.edu case COND_GE: 985425Sgblack@eecs.umich.edu result = (!nSet(cpsr) && !vSet(cpsr)) || (nSet(cpsr) && vSet(cpsr)); break; 995425Sgblack@eecs.umich.edu case COND_LT: 1005425Sgblack@eecs.umich.edu result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)); break; 1015425Sgblack@eecs.umich.edu case COND_GT: 1027975Sgblack@eecs.umich.edu result = (!nSet(cpsr) && !vSet(cpsr) && !zSet(cpsr)) || (nSet(cpsr) && vSet(cpsr) && !zSet(cpsr)); break; 1037620Sgblack@eecs.umich.edu case COND_LE: 1045425Sgblack@eecs.umich.edu result = (nSet(cpsr) && !vSet(cpsr)) || (!nSet(cpsr) && vSet(cpsr)) || zSet(cpsr); break; 1055425Sgblack@eecs.umich.edu case COND_AL: result = 1; break; 1067965Sgblack@eecs.umich.edu case COND_NV: result = 0; break; 1075425Sgblack@eecs.umich.edu default: 1087626Sgblack@eecs.umich.edu fprintf(stderr, "Unhandled predicate condition: %d\n", armPredBits); 1095425Sgblack@eecs.umich.edu exit(1); 1105425Sgblack@eecs.umich.edu } 1115425Sgblack@eecs.umich.edu if (result) 1125425Sgblack@eecs.umich.edu return true; 1135425Sgblack@eecs.umich.edu else 1145425Sgblack@eecs.umich.edu return false; 1155425Sgblack@eecs.umich.edu } 1165425Sgblack@eecs.umich.edu 1175425Sgblack@eecs.umich.edu 1185425Sgblack@eecs.umich.edu /** 1195425Sgblack@eecs.umich.edu * Base class for predicated integer operations. 1205425Sgblack@eecs.umich.edu */ 1215425Sgblack@eecs.umich.edu class PredOp : public ArmStaticInst 1225425Sgblack@eecs.umich.edu { 1235425Sgblack@eecs.umich.edu protected: 1247620Sgblack@eecs.umich.edu 1257620Sgblack@eecs.umich.edu uint32_t condCode; 1265425Sgblack@eecs.umich.edu 1275425Sgblack@eecs.umich.edu /// Constructor 1285425Sgblack@eecs.umich.edu PredOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 1295425Sgblack@eecs.umich.edu ArmStaticInst(mnem, _machInst, __opClass), 1305425Sgblack@eecs.umich.edu condCode(COND_CODE) 1315425Sgblack@eecs.umich.edu { 1325425Sgblack@eecs.umich.edu } 1335425Sgblack@eecs.umich.edu 1345425Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1355425Sgblack@eecs.umich.edu }; 1365425Sgblack@eecs.umich.edu 1377965Sgblack@eecs.umich.edu /** 1385425Sgblack@eecs.umich.edu * Base class for predicated immediate operations. 1395425Sgblack@eecs.umich.edu */ 1405425Sgblack@eecs.umich.edu class PredImmOp : public PredOp 1415425Sgblack@eecs.umich.edu { 1425425Sgblack@eecs.umich.edu protected: 1435425Sgblack@eecs.umich.edu 1447965Sgblack@eecs.umich.edu uint32_t imm; 1459010Snilay@cs.wisc.edu uint32_t rotate; 1469211Snilay@cs.wisc.edu uint32_t rotated_imm; 1475425Sgblack@eecs.umich.edu uint32_t rotated_carry; 1485425Sgblack@eecs.umich.edu 1495425Sgblack@eecs.umich.edu /// Constructor 1505425Sgblack@eecs.umich.edu PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 1515425Sgblack@eecs.umich.edu PredOp(mnem, _machInst, __opClass), 1525425Sgblack@eecs.umich.edu imm(IMM), rotate(ROTATE << 1), rotated_imm(0), 1535425Sgblack@eecs.umich.edu rotated_carry(0) 1545425Sgblack@eecs.umich.edu { 1557965Sgblack@eecs.umich.edu rotated_imm = rotate_imm(imm, rotate); 1565425Sgblack@eecs.umich.edu if (rotate != 0) 1575425Sgblack@eecs.umich.edu rotated_carry = (rotated_imm >> 31) & 1; 1585425Sgblack@eecs.umich.edu } 1595425Sgblack@eecs.umich.edu 1605425Sgblack@eecs.umich.edu std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1615425Sgblack@eecs.umich.edu }; 1625425Sgblack@eecs.umich.edu 1635425Sgblack@eecs.umich.edu /** 1645425Sgblack@eecs.umich.edu * Base class for predicated integer operations. 1655425Sgblack@eecs.umich.edu */ 1665425Sgblack@eecs.umich.edu class PredIntOp : public PredOp 1677965Sgblack@eecs.umich.edu { 1687965Sgblack@eecs.umich.edu protected: 1697965Sgblack@eecs.umich.edu 1707965Sgblack@eecs.umich.edu uint32_t shift_size; 1715425Sgblack@eecs.umich.edu uint32_t shift; 172 173 /// Constructor 174 PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 175 PredOp(mnem, _machInst, __opClass), 176 shift_size(SHIFT_SIZE), shift(SHIFT) 177 { 178 } 179 180 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 181 }; 182 183 /** 184 * Base class for predicated macro-operations. 185 */ 186 class PredMacroOp : public PredOp 187 { 188 protected: 189 190 uint32_t numMicroops; 191 StaticInstPtr * microOps; 192 193 /// Constructor 194 PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : 195 PredOp(mnem, _machInst, __opClass), 196 numMicroops(0) 197 { 198 // We rely on the subclasses of this object to handle the 199 // initialization of the micro-operations, since they are 200 // all of variable length 201 flags[IsMacroop] = true; 202 } 203 204 ~PredMacroOp() 205 { 206 if (numMicroops) 207 delete [] microOps; 208 } 209 210 StaticInstPtr fetchMicroop(MicroPC microPC) 211 { 212 assert(microPC < numMicroops); 213 return microOps[microPC]; 214 } 215 216 %(BasicExecPanic)s 217 218 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 219 }; 220 221 /** 222 * Base class for predicated micro-operations. 223 */ 224 class PredMicroop : public PredOp 225 { 226 /// Constructor 227 PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : 228 PredOp(mnem, _machInst, __opClass) 229 { 230 flags[IsMicroop] = true; 231 } 232 }; 233 234}}; 235 236def template PredOpExecute {{ 237 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const 238 { 239 Fault fault = NoFault; 240 241 %(fp_enable_check)s; 242 %(op_decl)s; 243 %(op_rd)s; 244 %(code)s; 245 246 if (arm_predicate(xc->readMiscReg(ArmISA::CPSR), condCode)) 247 { 248 if (fault == NoFault) 249 { 250 %(op_wb)s; 251 } 252 } 253 else 254 return NoFault; 255 // Predicated false instructions should not return faults 256 257 return fault; 258 } 259}}; 260 261//Outputs to decoder.cc 262output decoder {{ 263 std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 264 { 265 std::stringstream ss; 266 267 ccprintf(ss, "%-10s ", mnemonic); 268 269 if (_numDestRegs > 0) { 270 printReg(ss, _destRegIdx[0]); 271 } 272 273 ss << ", "; 274 275 if (_numSrcRegs > 0) { 276 printReg(ss, _srcRegIdx[0]); 277 ss << ", "; 278 } 279 280 return ss.str(); 281 } 282 283 std::string PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 284 { 285 std::stringstream ss; 286 287 ccprintf(ss, "%-10s ", mnemonic); 288 289 if (_numDestRegs > 0) { 290 printReg(ss, _destRegIdx[0]); 291 } 292 293 ss << ", "; 294 295 if (_numSrcRegs > 0) { 296 printReg(ss, _srcRegIdx[0]); 297 ss << ", "; 298 } 299 300 return ss.str(); 301 } 302 303 std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 304 { 305 std::stringstream ss; 306 307 ccprintf(ss, "%-10s ", mnemonic); 308 309 if (_numDestRegs > 0) { 310 printReg(ss, _destRegIdx[0]); 311 } 312 313 ss << ", "; 314 315 if (_numSrcRegs > 0) { 316 printReg(ss, _srcRegIdx[0]); 317 ss << ", "; 318 } 319 320 return ss.str(); 321 } 322 323 std::string PredMacroOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 324 { 325 std::stringstream ss; 326 327 ccprintf(ss, "%-10s ", mnemonic); 328 329 return ss.str(); 330 } 331 332}}; 333 334let {{ 335 336 calcCcCode = ''' 337 uint16_t _ic, _iv, _iz, _in; 338 339 _in = (resTemp >> 31) & 1; 340 _iz = (resTemp == 0); 341 _iv = %(ivValue)s & 1; 342 _ic = %(icValue)s & 1; 343 344 Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | 345 (Cpsr & 0x0FFFFFFF); 346 347 DPRINTF(Arm, "in = %%d\\n", _in); 348 DPRINTF(Arm, "iz = %%d\\n", _iz); 349 DPRINTF(Arm, "ic = %%d\\n", _ic); 350 DPRINTF(Arm, "iv = %%d\\n", _iv); 351 ''' 352 353}}; 354 355def format PredOp(code, *opt_flags) {{ 356 iop = InstObjParams(name, Name, 'PredOp', code, opt_flags) 357 header_output = BasicDeclare.subst(iop) 358 decoder_output = BasicConstructor.subst(iop) 359 decode_block = BasicDecode.subst(iop) 360 exec_output = PredOpExecute.subst(iop) 361}}; 362 363def format PredImmOp(code, *opt_flags) {{ 364 iop = InstObjParams(name, Name, 'PredImmOp', code, opt_flags) 365 header_output = BasicDeclare.subst(iop) 366 decoder_output = BasicConstructor.subst(iop) 367 decode_block = BasicDecode.subst(iop) 368 exec_output = PredOpExecute.subst(iop) 369}}; 370 371def format PredImmOpCc(code, icValue, ivValue, *opt_flags) {{ 372 ccCode = calcCcCode % vars() 373 code += ccCode; 374 iop = InstObjParams(name, Name, 'PredImmOp', 375 {"code": code, "cc_code": ccCode}, opt_flags) 376 header_output = BasicDeclare.subst(iop) 377 decoder_output = BasicConstructor.subst(iop) 378 decode_block = BasicDecode.subst(iop) 379 exec_output = PredOpExecute.subst(iop) 380}}; 381 382def format PredIntOp(code, *opt_flags) {{ 383 new_code = ArmGenericCodeSubs(code) 384 iop = InstObjParams(name, Name, 'PredIntOp', new_code, opt_flags) 385 header_output = BasicDeclare.subst(iop) 386 decoder_output = BasicConstructor.subst(iop) 387 decode_block = BasicDecode.subst(iop) 388 exec_output = PredOpExecute.subst(iop) 389}}; 390 391def format PredIntOpCc(code, icValue, ivValue, *opt_flags) {{ 392 ccCode = calcCcCode % vars() 393 code += ccCode; 394 new_code = ArmGenericCodeSubs(code) 395 iop = InstObjParams(name, Name, 'PredIntOp', 396 {"code": new_code, "cc_code": ccCode }, opt_flags) 397 header_output = BasicDeclare.subst(iop) 398 decoder_output = BasicConstructor.subst(iop) 399 decode_block = BasicDecode.subst(iop) 400 exec_output = PredOpExecute.subst(iop) 401}}; 402 403