mem.isa revision 7712
111251Sradhika.jagtap@ARM.com// -*- mode:c++ -*- 211251Sradhika.jagtap@ARM.com 311251Sradhika.jagtap@ARM.com// Copyright (c) 2003-2005 The Regents of The University of Michigan 411251Sradhika.jagtap@ARM.com// All rights reserved. 511251Sradhika.jagtap@ARM.com// 611251Sradhika.jagtap@ARM.com// Redistribution and use in source and binary forms, with or without 711251Sradhika.jagtap@ARM.com// modification, are permitted provided that the following conditions are 811251Sradhika.jagtap@ARM.com// met: redistributions of source code must retain the above copyright 911251Sradhika.jagtap@ARM.com// notice, this list of conditions and the following disclaimer; 1011251Sradhika.jagtap@ARM.com// redistributions in binary form must reproduce the above copyright 1111251Sradhika.jagtap@ARM.com// notice, this list of conditions and the following disclaimer in the 1211251Sradhika.jagtap@ARM.com// documentation and/or other materials provided with the distribution; 1311251Sradhika.jagtap@ARM.com// neither the name of the copyright holders nor the names of its 1411251Sradhika.jagtap@ARM.com// contributors may be used to endorse or promote products derived from 1511251Sradhika.jagtap@ARM.com// this software without specific prior written permission. 1611251Sradhika.jagtap@ARM.com// 1711251Sradhika.jagtap@ARM.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1811251Sradhika.jagtap@ARM.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1911251Sradhika.jagtap@ARM.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2011251Sradhika.jagtap@ARM.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2111251Sradhika.jagtap@ARM.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2211251Sradhika.jagtap@ARM.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2311251Sradhika.jagtap@ARM.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2411251Sradhika.jagtap@ARM.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2511251Sradhika.jagtap@ARM.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2611251Sradhika.jagtap@ARM.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2711251Sradhika.jagtap@ARM.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2811251Sradhika.jagtap@ARM.com// 2911251Sradhika.jagtap@ARM.com// Authors: Steve Reinhardt 3011251Sradhika.jagtap@ARM.com// Kevin Lim 3111251Sradhika.jagtap@ARM.com 3211251Sradhika.jagtap@ARM.com//////////////////////////////////////////////////////////////////// 3311251Sradhika.jagtap@ARM.com// 3411251Sradhika.jagtap@ARM.com// Memory-format instructions: LoadAddress, Load, Store 3511251Sradhika.jagtap@ARM.com// 3611251Sradhika.jagtap@ARM.com 3711251Sradhika.jagtap@ARM.comoutput header {{ 3811251Sradhika.jagtap@ARM.com /** 3911251Sradhika.jagtap@ARM.com * Base class for general Alpha memory-format instructions. 4011251Sradhika.jagtap@ARM.com */ 4111251Sradhika.jagtap@ARM.com class Memory : public AlphaStaticInst 4211251Sradhika.jagtap@ARM.com { 4311251Sradhika.jagtap@ARM.com protected: 4411682Sandreas.hansson@arm.com 4511251Sradhika.jagtap@ARM.com /// Memory request flags. See mem_req_base.hh. 4611682Sandreas.hansson@arm.com Request::Flags memAccessFlags; 4711682Sandreas.hansson@arm.com 4811682Sandreas.hansson@arm.com /// Constructor 4911682Sandreas.hansson@arm.com Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 5011682Sandreas.hansson@arm.com : AlphaStaticInst(mnem, _machInst, __opClass) 5111251Sradhika.jagtap@ARM.com { 5211251Sradhika.jagtap@ARM.com } 5311251Sradhika.jagtap@ARM.com 5411251Sradhika.jagtap@ARM.com std::string 5511251Sradhika.jagtap@ARM.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 5611251Sradhika.jagtap@ARM.com }; 5711251Sradhika.jagtap@ARM.com 5811251Sradhika.jagtap@ARM.com /** 5911251Sradhika.jagtap@ARM.com * Base class for memory-format instructions using a 32-bit 6011251Sradhika.jagtap@ARM.com * displacement (i.e. most of them). 6111251Sradhika.jagtap@ARM.com */ 6211251Sradhika.jagtap@ARM.com class MemoryDisp32 : public Memory 6311251Sradhika.jagtap@ARM.com { 6411251Sradhika.jagtap@ARM.com protected: 6511251Sradhika.jagtap@ARM.com /// Displacement for EA calculation (signed). 6611251Sradhika.jagtap@ARM.com int32_t disp; 6711251Sradhika.jagtap@ARM.com 6812014Sgabeblack@google.com /// Constructor. 6911251Sradhika.jagtap@ARM.com MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 7012014Sgabeblack@google.com : Memory(mnem, _machInst, __opClass), 7111251Sradhika.jagtap@ARM.com disp(MEMDISP) 7211251Sradhika.jagtap@ARM.com { 7311251Sradhika.jagtap@ARM.com } 7411251Sradhika.jagtap@ARM.com }; 7511251Sradhika.jagtap@ARM.com 7611251Sradhika.jagtap@ARM.com 7711251Sradhika.jagtap@ARM.com /** 7811251Sradhika.jagtap@ARM.com * Base class for a few miscellaneous memory-format insts 7911251Sradhika.jagtap@ARM.com * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 8011251Sradhika.jagtap@ARM.com * None of these instructions has a destination register either. 8111251Sradhika.jagtap@ARM.com */ 8211251Sradhika.jagtap@ARM.com class MemoryNoDisp : public Memory 8311251Sradhika.jagtap@ARM.com { 8411251Sradhika.jagtap@ARM.com protected: 8511251Sradhika.jagtap@ARM.com /// Constructor 8611251Sradhika.jagtap@ARM.com MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) 8711251Sradhika.jagtap@ARM.com : Memory(mnem, _machInst, __opClass) 8811251Sradhika.jagtap@ARM.com { 8911251Sradhika.jagtap@ARM.com } 9011251Sradhika.jagtap@ARM.com 9111251Sradhika.jagtap@ARM.com std::string 9211251Sradhika.jagtap@ARM.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 9311251Sradhika.jagtap@ARM.com }; 9411251Sradhika.jagtap@ARM.com}}; 9511251Sradhika.jagtap@ARM.com 9611251Sradhika.jagtap@ARM.com 9711251Sradhika.jagtap@ARM.comoutput decoder {{ 9811251Sradhika.jagtap@ARM.com std::string 9911251Sradhika.jagtap@ARM.com Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 10011251Sradhika.jagtap@ARM.com { 10111251Sradhika.jagtap@ARM.com return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 10211251Sradhika.jagtap@ARM.com flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 10311251Sradhika.jagtap@ARM.com } 10411251Sradhika.jagtap@ARM.com 10511251Sradhika.jagtap@ARM.com std::string 10611251Sradhika.jagtap@ARM.com MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 10712430Schenzou@uchicago.edu { 10812430Schenzou@uchicago.edu return csprintf("%-10s (r%d)", mnemonic, RB); 10912430Schenzou@uchicago.edu } 11012430Schenzou@uchicago.edu}}; 11112430Schenzou@uchicago.edu 11211251Sradhika.jagtap@ARM.comdef format LoadAddress(code) {{ 11311251Sradhika.jagtap@ARM.com iop = InstObjParams(name, Name, 'MemoryDisp32', code) 11411251Sradhika.jagtap@ARM.com header_output = BasicDeclare.subst(iop) 11511251Sradhika.jagtap@ARM.com decoder_output = BasicConstructor.subst(iop) 11611251Sradhika.jagtap@ARM.com decode_block = BasicDecode.subst(iop) 11711251Sradhika.jagtap@ARM.com exec_output = BasicExecute.subst(iop) 11811251Sradhika.jagtap@ARM.com}}; 11911251Sradhika.jagtap@ARM.com 12011251Sradhika.jagtap@ARM.com 12111251Sradhika.jagtap@ARM.comdef template LoadStoreDeclare {{ 12211251Sradhika.jagtap@ARM.com /** 12311251Sradhika.jagtap@ARM.com * Static instruction class for "%(mnemonic)s". 12411251Sradhika.jagtap@ARM.com */ 125 class %(class_name)s : public %(base_class)s 126 { 127 public: 128 129 /// Constructor. 130 %(class_name)s(ExtMachInst machInst); 131 132 %(BasicExecDeclare)s 133 134 %(EACompDeclare)s 135 136 %(InitiateAccDeclare)s 137 138 %(CompleteAccDeclare)s 139 }; 140}}; 141 142 143def template EACompDeclare {{ 144 Fault eaComp(%(CPU_exec_context)s *, Trace::InstRecord *) const; 145}}; 146 147def template InitiateAccDeclare {{ 148 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 149}}; 150 151 152def template CompleteAccDeclare {{ 153 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, 154 Trace::InstRecord *) const; 155}}; 156 157def template LoadStoreConstructor {{ 158 inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 159 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 160 { 161 %(constructor)s; 162 } 163}}; 164 165def template EACompExecute {{ 166 Fault %(class_name)s::eaComp(%(CPU_exec_context)s *xc, 167 Trace::InstRecord *traceData) const 168 { 169 Addr EA; 170 Fault fault = NoFault; 171 172 %(fp_enable_check)s; 173 %(op_decl)s; 174 %(op_rd)s; 175 %(ea_code)s; 176 177 if (fault == NoFault) { 178 %(op_wb)s; 179 xc->setEA(EA); 180 } 181 182 return fault; 183 } 184}}; 185 186 187def template LoadExecute {{ 188 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 189 Trace::InstRecord *traceData) const 190 { 191 Addr EA; 192 Fault fault = NoFault; 193 194 %(fp_enable_check)s; 195 %(op_decl)s; 196 %(op_rd)s; 197 %(ea_code)s; 198 199 if (fault == NoFault) { 200 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 201 %(memacc_code)s; 202 } 203 204 if (fault == NoFault) { 205 %(op_wb)s; 206 } 207 208 return fault; 209 } 210}}; 211 212 213def template LoadInitiateAcc {{ 214 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 215 Trace::InstRecord *traceData) const 216 { 217 Addr EA; 218 Fault fault = NoFault; 219 220 %(fp_enable_check)s; 221 %(op_src_decl)s; 222 %(op_rd)s; 223 %(ea_code)s; 224 225 if (fault == NoFault) { 226 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 227 } 228 229 return fault; 230 } 231}}; 232 233 234def template LoadCompleteAcc {{ 235 Fault %(class_name)s::completeAcc(PacketPtr pkt, 236 %(CPU_exec_context)s *xc, 237 Trace::InstRecord *traceData) const 238 { 239 Fault fault = NoFault; 240 241 %(fp_enable_check)s; 242 %(op_decl)s; 243 244 Mem = pkt->get<typeof(Mem)>(); 245 246 if (fault == NoFault) { 247 %(memacc_code)s; 248 } 249 250 if (fault == NoFault) { 251 %(op_wb)s; 252 } 253 254 return fault; 255 } 256}}; 257 258 259def template StoreExecute {{ 260 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 261 Trace::InstRecord *traceData) const 262 { 263 Addr EA; 264 Fault fault = NoFault; 265 266 %(fp_enable_check)s; 267 %(op_decl)s; 268 %(op_rd)s; 269 %(ea_code)s; 270 271 if (fault == NoFault) { 272 %(memacc_code)s; 273 } 274 275 if (fault == NoFault) { 276 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 277 memAccessFlags, NULL); 278 } 279 280 if (fault == NoFault) { 281 %(postacc_code)s; 282 } 283 284 if (fault == NoFault) { 285 %(op_wb)s; 286 } 287 288 return fault; 289 } 290}}; 291 292def template StoreCondExecute {{ 293 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 294 Trace::InstRecord *traceData) const 295 { 296 Addr EA; 297 Fault fault = NoFault; 298 uint64_t write_result = 0; 299 300 %(fp_enable_check)s; 301 %(op_decl)s; 302 %(op_rd)s; 303 %(ea_code)s; 304 305 if (fault == NoFault) { 306 %(memacc_code)s; 307 } 308 309 if (fault == NoFault) { 310 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 311 memAccessFlags, &write_result); 312 } 313 314 if (fault == NoFault) { 315 %(postacc_code)s; 316 } 317 318 if (fault == NoFault) { 319 %(op_wb)s; 320 } 321 322 return fault; 323 } 324}}; 325 326def template StoreInitiateAcc {{ 327 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 328 Trace::InstRecord *traceData) const 329 { 330 Addr EA; 331 Fault fault = NoFault; 332 333 %(fp_enable_check)s; 334 %(op_decl)s; 335 %(op_rd)s; 336 %(ea_code)s; 337 338 if (fault == NoFault) { 339 %(memacc_code)s; 340 } 341 342 if (fault == NoFault) { 343 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 344 memAccessFlags, NULL); 345 } 346 347 return fault; 348 } 349}}; 350 351 352def template StoreCompleteAcc {{ 353 Fault %(class_name)s::completeAcc(PacketPtr pkt, 354 %(CPU_exec_context)s *xc, 355 Trace::InstRecord *traceData) const 356 { 357 return NoFault; 358 } 359}}; 360 361 362def template StoreCondCompleteAcc {{ 363 Fault %(class_name)s::completeAcc(PacketPtr pkt, 364 %(CPU_exec_context)s *xc, 365 Trace::InstRecord *traceData) const 366 { 367 Fault fault = NoFault; 368 369 %(fp_enable_check)s; 370 %(op_dest_decl)s; 371 372 uint64_t write_result = pkt->req->getExtraData(); 373 374 if (fault == NoFault) { 375 %(postacc_code)s; 376 } 377 378 if (fault == NoFault) { 379 %(op_wb)s; 380 } 381 382 return fault; 383 } 384}}; 385 386 387def template MiscExecute {{ 388 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 389 Trace::InstRecord *traceData) const 390 { 391 Addr EA; 392 Fault fault = NoFault; 393 394 %(fp_enable_check)s; 395 %(op_decl)s; 396 %(op_rd)s; 397 %(ea_code)s; 398 399 if (fault == NoFault) { 400 %(memacc_code)s; 401 } 402 403 return NoFault; 404 } 405}}; 406 407def template MiscInitiateAcc {{ 408 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 409 Trace::InstRecord *traceData) const 410 { 411 warn("initiateAcc undefined: Misc instruction does not support split " 412 "access method!"); 413 return NoFault; 414 } 415}}; 416 417 418def template MiscCompleteAcc {{ 419 Fault %(class_name)s::completeAcc(PacketPtr pkt, 420 %(CPU_exec_context)s *xc, 421 Trace::InstRecord *traceData) const 422 { 423 warn("completeAcc undefined: Misc instruction does not support split " 424 "access method!"); 425 426 return NoFault; 427 } 428}}; 429 430 431// load instructions use Ra as dest, so check for 432// Ra == 31 to detect nops 433def template LoadNopCheckDecode {{ 434 { 435 AlphaStaticInst *i = new %(class_name)s(machInst); 436 if (RA == 31) { 437 i = makeNop(i); 438 } 439 return i; 440 } 441}}; 442 443 444// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 445def template LoadPrefetchCheckDecode {{ 446 { 447 if (RA != 31) { 448 return new %(class_name)s(machInst); 449 } 450 else { 451 return new %(class_name)sPrefetch(machInst); 452 } 453 } 454}}; 455 456 457let {{ 458def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 459 postacc_code = '', base_class = 'MemoryDisp32', 460 decode_template = BasicDecode, exec_template_base = ''): 461 # Make sure flags are in lists (convert to lists if not). 462 mem_flags = makeList(mem_flags) 463 inst_flags = makeList(inst_flags) 464 465 # Some CPU models execute the memory operation as an atomic unit, 466 # while others want to separate them into an effective address 467 # computation and a memory access operation. As a result, we need 468 # to generate three StaticInst objects. Note that the latter two 469 # are nested inside the larger "atomic" one. 470 471 # Generate InstObjParams for each of the three objects. Note that 472 # they differ only in the set of code objects contained (which in 473 # turn affects the object's overall operand list). 474 iop = InstObjParams(name, Name, base_class, 475 { 'ea_code':ea_code, 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 476 inst_flags) 477 memacc_iop = InstObjParams(name, Name, base_class, 478 { 'memacc_code':memacc_code, 'postacc_code':postacc_code }, 479 inst_flags) 480 481 if mem_flags: 482 mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] 483 s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 484 iop.constructor += s 485 memacc_iop.constructor += s 486 487 # select templates 488 489 # The InitiateAcc template is the same for StoreCond templates as the 490 # corresponding Store template.. 491 StoreCondInitiateAcc = StoreInitiateAcc 492 493 fullExecTemplate = eval(exec_template_base + 'Execute') 494 initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 495 completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 496 497 # (header_output, decoder_output, decode_block, exec_output) 498 return (LoadStoreDeclare.subst(iop), 499 LoadStoreConstructor.subst(iop), 500 decode_template.subst(iop), 501 fullExecTemplate.subst(iop) 502 + EACompExecute.subst(iop) 503 + initiateAccTemplate.subst(iop) 504 + completeAccTemplate.subst(iop)) 505}}; 506 507def format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 508 mem_flags = [], inst_flags = []) {{ 509 (header_output, decoder_output, decode_block, exec_output) = \ 510 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 511 decode_template = LoadNopCheckDecode, 512 exec_template_base = 'Load') 513}}; 514 515 516// Note that the flags passed in apply only to the prefetch version 517def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 518 mem_flags = [], pf_flags = [], inst_flags = []) {{ 519 # declare the load instruction object and generate the decode block 520 (header_output, decoder_output, decode_block, exec_output) = \ 521 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 522 decode_template = LoadPrefetchCheckDecode, 523 exec_template_base = 'Load') 524 525 # Declare the prefetch instruction object. 526 527 # Make sure flag args are lists so we can mess with them. 528 mem_flags = makeList(mem_flags) 529 pf_flags = makeList(pf_flags) 530 inst_flags = makeList(inst_flags) 531 532 pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] 533 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 534 'IsDataPrefetch', 'MemReadOp'] 535 536 (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 537 LoadStoreBase(name, Name + 'Prefetch', ea_code, 538 'xc->prefetch(EA, memAccessFlags);', 539 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 540 541 header_output += pf_header_output 542 decoder_output += pf_decoder_output 543 exec_output += pf_exec_output 544}}; 545 546 547def format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 548 mem_flags = [], inst_flags = []) {{ 549 (header_output, decoder_output, decode_block, exec_output) = \ 550 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 551 exec_template_base = 'Store') 552}}; 553 554 555def format StoreCond(memacc_code, postacc_code, 556 ea_code = {{ EA = Rb + disp; }}, 557 mem_flags = [], inst_flags = []) {{ 558 (header_output, decoder_output, decode_block, exec_output) = \ 559 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 560 postacc_code, exec_template_base = 'StoreCond') 561}}; 562 563 564// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 565def format MiscPrefetch(ea_code, memacc_code, 566 mem_flags = [], inst_flags = []) {{ 567 (header_output, decoder_output, decode_block, exec_output) = \ 568 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 569 base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 570}}; 571 572 573