mem.isa revision 6302
12SN/A// -*- mode:c++ -*- 21762SN/A 37897Shestness@cs.utexas.edu// Copyright (c) 2007-2008 The Florida State University 42SN/A// All rights reserved. 52SN/A// 62SN/A// Redistribution and use in source and binary forms, with or without 72SN/A// modification, are permitted provided that the following conditions are 82SN/A// met: redistributions of source code must retain the above copyright 92SN/A// notice, this list of conditions and the following disclaimer; 102SN/A// redistributions in binary form must reproduce the above copyright 112SN/A// notice, this list of conditions and the following disclaimer in the 122SN/A// documentation and/or other materials provided with the distribution; 132SN/A// neither the name of the copyright holders nor the names of its 142SN/A// contributors may be used to endorse or promote products derived from 152SN/A// this software without specific prior written permission. 162SN/A// 172SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292665Ssaidi@eecs.umich.edu// Authors: Stephen Hines 302665Ssaidi@eecs.umich.edu 312665Ssaidi@eecs.umich.edu//////////////////////////////////////////////////////////////////// 327897Shestness@cs.utexas.edu// 332SN/A// Memory-format instructions 342SN/A// 352SN/A 362SN/Adef template LoadStoreDeclare {{ 372SN/A /** 382SN/A * Static instruction class for "%(mnemonic)s". 3975SN/A */ 402SN/A class %(class_name)s : public %(base_class)s 412439SN/A { 422439SN/A protected: 43603SN/A 442986Sgblack@eecs.umich.edu /** 45603SN/A * "Fake" effective address computation class for "%(mnemonic)s". 464762Snate@binkert.org */ 472520SN/A class EAComp : public %(base_class)s 484762Snate@binkert.org { 492378SN/A public: 506658Snate@binkert.org /// Constructor 512378SN/A EAComp(ExtMachInst machInst); 52722SN/A 532378SN/A %(BasicExecDeclare)s 54312SN/A }; 551634SN/A 562680Sktlim@umich.edu /** 571634SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 582521SN/A */ 592378SN/A class MemAcc : public %(base_class)s 602378SN/A { 61803SN/A public: 627723SAli.Saidi@ARM.com /// Constructor 637723SAli.Saidi@ARM.com MemAcc(ExtMachInst machInst); 643960Sgblack@eecs.umich.edu 652378SN/A %(BasicExecDeclare)s 666658Snate@binkert.org }; 672SN/A 682SN/A public: 692SN/A 70603SN/A /// Constructor. 712901Ssaidi@eecs.umich.edu %(class_name)s(ExtMachInst machInst); 722902Ssaidi@eecs.umich.edu 732902Ssaidi@eecs.umich.edu %(BasicExecDeclare)s 744762Snate@binkert.org 754762Snate@binkert.org %(InitiateAccDeclare)s 764762Snate@binkert.org 774762Snate@binkert.org %(CompleteAccDeclare)s 784762Snate@binkert.org }; 794762Snate@binkert.org}}; 802901Ssaidi@eecs.umich.edu 812901Ssaidi@eecs.umich.edu 822901Ssaidi@eecs.umich.edudef template InitiateAccDeclare {{ 832901Ssaidi@eecs.umich.edu Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 842901Ssaidi@eecs.umich.edu}}; 854762Snate@binkert.org 862901Ssaidi@eecs.umich.edu 872521SN/Adef template CompleteAccDeclare {{ 882SN/A Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 892SN/A}}; 902680Sktlim@umich.edu 915714Shsul@eecs.umich.edu 921806SN/Adef template EACompConstructor {{ 936221Snate@binkert.org inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) 945713Shsul@eecs.umich.edu : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 955713Shsul@eecs.umich.edu { 965713Shsul@eecs.umich.edu %(constructor)s; 975713Shsul@eecs.umich.edu } 985714Shsul@eecs.umich.edu}}; 991806SN/A 1006227Snate@binkert.org 1015714Shsul@eecs.umich.edudef template MemAccConstructor {{ 1021806SN/A inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) 103180SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 1046029Ssteve.reinhardt@amd.com { 1056029Ssteve.reinhardt@amd.com %(constructor)s; 1066029Ssteve.reinhardt@amd.com } 1076029Ssteve.reinhardt@amd.com}}; 1088460SAli.Saidi@ARM.com 1098460SAli.Saidi@ARM.com 1108460SAli.Saidi@ARM.comdef template LoadStoreConstructor {{ 1118460SAli.Saidi@ARM.com inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 1128460SAli.Saidi@ARM.com : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 1138460SAli.Saidi@ARM.com new EAComp(machInst), new MemAcc(machInst)) 1148460SAli.Saidi@ARM.com { 1158460SAli.Saidi@ARM.com %(constructor)s; 1162378SN/A } 1172378SN/A}}; 1182378SN/A 1192378SN/A 1202520SN/Adef template EACompExecute {{ 1212520SN/A Fault 1227723SAli.Saidi@ARM.com %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 1237723SAli.Saidi@ARM.com Trace::InstRecord *traceData) const 1242520SN/A { 1251885SN/A Addr EA; 1261070SN/A Fault fault = NoFault; 127954SN/A 1281070SN/A %(op_decl)s; 1291070SN/A %(op_rd)s; 1301070SN/A %(ea_code)s; 1311070SN/A 1321070SN/A if (%(predicate_test)s) 1331070SN/A { 1341070SN/A if (fault == NoFault) { 1351070SN/A %(op_wb)s; 1361070SN/A xc->setEA(EA); 1371070SN/A } 1381070SN/A } 1391070SN/A 1407580SAli.Saidi@arm.com return fault; 1417580SAli.Saidi@arm.com } 1427580SAli.Saidi@arm.com}}; 1437580SAli.Saidi@arm.com 1447580SAli.Saidi@arm.comdef template LoadMemAccExecute {{ 1457580SAli.Saidi@arm.com Fault 1467580SAli.Saidi@arm.com %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 1477580SAli.Saidi@arm.com Trace::InstRecord *traceData) const 1482378SN/A { 1492378SN/A Addr EA; 1507770SAli.Saidi@ARM.com Fault fault = NoFault; 1512378SN/A 1524997Sgblack@eecs.umich.edu %(op_decl)s; 1537770SAli.Saidi@ARM.com %(op_rd)s; 1544997Sgblack@eecs.umich.edu EA = xc->getEA(); 1554997Sgblack@eecs.umich.edu 1564997Sgblack@eecs.umich.edu if (%(predicate_test)s) 1574997Sgblack@eecs.umich.edu { 1587770SAli.Saidi@ARM.com if (fault == NoFault) { 1594997Sgblack@eecs.umich.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 1604997Sgblack@eecs.umich.edu %(memacc_code)s; 1615795Ssaidi@eecs.umich.edu } 1625795Ssaidi@eecs.umich.edu 1635795Ssaidi@eecs.umich.edu if (fault == NoFault) { 1645795Ssaidi@eecs.umich.edu %(op_wb)s; 1655795Ssaidi@eecs.umich.edu } 1665795Ssaidi@eecs.umich.edu } 1672378SN/A 1682378SN/A return fault; 1692378SN/A } 1701885SN/A}}; 1714762Snate@binkert.org 1727914SBrad.Beckmann@amd.com 1737914SBrad.Beckmann@amd.comdef template LoadExecute {{ 1747914SBrad.Beckmann@amd.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1757914SBrad.Beckmann@amd.com Trace::InstRecord *traceData) const 1767914SBrad.Beckmann@amd.com { 1777914SBrad.Beckmann@amd.com Addr EA; 1787914SBrad.Beckmann@amd.com Fault fault = NoFault; 1797914SBrad.Beckmann@amd.com 1807914SBrad.Beckmann@amd.com %(op_decl)s; 1817914SBrad.Beckmann@amd.com %(op_rd)s; 1827914SBrad.Beckmann@amd.com %(ea_code)s; 1837914SBrad.Beckmann@amd.com 1847914SBrad.Beckmann@amd.com if (%(predicate_test)s) 1857914SBrad.Beckmann@amd.com { 1867914SBrad.Beckmann@amd.com if (fault == NoFault) { 1877914SBrad.Beckmann@amd.com fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 1887914SBrad.Beckmann@amd.com %(memacc_code)s; 1897914SBrad.Beckmann@amd.com } 1907914SBrad.Beckmann@amd.com 1917914SBrad.Beckmann@amd.com if (fault == NoFault) { 1927914SBrad.Beckmann@amd.com %(op_wb)s; 1937914SBrad.Beckmann@amd.com } 1947914SBrad.Beckmann@amd.com } 1957914SBrad.Beckmann@amd.com 1967914SBrad.Beckmann@amd.com return fault; 1977914SBrad.Beckmann@amd.com } 1987914SBrad.Beckmann@amd.com}}; 1997914SBrad.Beckmann@amd.com 2007914SBrad.Beckmann@amd.com 2017914SBrad.Beckmann@amd.comdef template LoadInitiateAcc {{ 2027914SBrad.Beckmann@amd.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 2037914SBrad.Beckmann@amd.com Trace::InstRecord *traceData) const 2047914SBrad.Beckmann@amd.com { 2057914SBrad.Beckmann@amd.com Addr EA; 2067914SBrad.Beckmann@amd.com Fault fault = NoFault; 2077914SBrad.Beckmann@amd.com 2087914SBrad.Beckmann@amd.com %(op_src_decl)s; 2097914SBrad.Beckmann@amd.com %(op_rd)s; 2107914SBrad.Beckmann@amd.com %(ea_code)s; 2117914SBrad.Beckmann@amd.com 2127914SBrad.Beckmann@amd.com if (%(predicate_test)s) 2137914SBrad.Beckmann@amd.com { 2142901Ssaidi@eecs.umich.edu if (fault == NoFault) { 2152424SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 2161885SN/A } 2171885SN/A } 2181885SN/A 2191885SN/A return fault; 2201885SN/A } 2212158SN/A}}; 2221885SN/A 2231885SN/A 2241885SN/Adef template LoadCompleteAcc {{ 2251885SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 2261885SN/A %(CPU_exec_context)s *xc, 2271885SN/A Trace::InstRecord *traceData) const 2282989Ssaidi@eecs.umich.edu { 2291885SN/A Fault fault = NoFault; 2301913SN/A 2311885SN/A %(op_decl)s; 2321885SN/A %(op_rd)s; 2331885SN/A 2341885SN/A if (%(predicate_test)s) 2351885SN/A { 2361885SN/A // ARM instructions will not have a pkt if the predicate is false 2371885SN/A Mem = pkt->get<typeof(Mem)>(); 2381885SN/A 2391885SN/A if (fault == NoFault) { 2401885SN/A %(memacc_code)s; 2411885SN/A } 2422989Ssaidi@eecs.umich.edu 2431885SN/A if (fault == NoFault) { 2441885SN/A %(op_wb)s; 2451885SN/A } 2461885SN/A } 2472378SN/A 24877SN/A return fault; 2496658Snate@binkert.org } 2501070SN/A}}; 2513960Sgblack@eecs.umich.edu 2521070SN/A 2531070SN/Adef template StoreMemAccExecute {{ 2544762Snate@binkert.org Fault 2551070SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2562158SN/A Trace::InstRecord *traceData) const 2572158SN/A { 2581070SN/A Addr EA; 2592158SN/A Fault fault = NoFault; 2601070SN/A 2612SN/A %(op_decl)s; 2622SN/A %(op_rd)s; 2637733SAli.Saidi@ARM.com 2641129SN/A if (%(predicate_test)s) 2652158SN/A { 2662158SN/A EA = xc->getEA(); 2671070SN/A 2682378SN/A if (fault == NoFault) { 2692378SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 2701070SN/A memAccessFlags, NULL); 2711070SN/A if (traceData) { traceData->setData(Mem); } 2721070SN/A } 2731070SN/A 2741070SN/A if (fault == NoFault) { 2751070SN/A %(op_wb)s; 2761070SN/A } 2771070SN/A } 2781070SN/A 2791070SN/A return fault; 2801070SN/A } 2811070SN/A}}; 2821070SN/A 2831070SN/A 2841070SN/Adef template StoreExecute {{ 2851070SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 2861070SN/A Trace::InstRecord *traceData) const 2871070SN/A { 2882378SN/A Addr EA; 2892378SN/A Fault fault = NoFault; 2902378SN/A 2912378SN/A %(op_decl)s; 2922378SN/A %(op_rd)s; 2932378SN/A %(ea_code)s; 2945718Shsul@eecs.umich.edu 2955713Shsul@eecs.umich.edu if (%(predicate_test)s) 2961070SN/A { 2971070SN/A if (fault == NoFault) { 2981070SN/A %(memacc_code)s; 2997897Shestness@cs.utexas.edu } 3002SN/A 30177SN/A if (fault == NoFault) { 3027897Shestness@cs.utexas.edu fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3037897Shestness@cs.utexas.edu memAccessFlags, NULL); 3047897Shestness@cs.utexas.edu if (traceData) { traceData->setData(Mem); } 3052SN/A } 3062SN/A 3072SN/A if (fault == NoFault) { 3082SN/A %(op_wb)s; 3092SN/A } 3102SN/A } 3112SN/A 3122SN/A return fault; 3132SN/A } 3142SN/A}}; 3152158SN/A 3162158SN/Adef template StoreInitiateAcc {{ 3172SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 3182SN/A Trace::InstRecord *traceData) const 3192SN/A { 320 Addr EA; 321 Fault fault = NoFault; 322 323 %(op_decl)s; 324 %(op_rd)s; 325 %(ea_code)s; 326 327 if (%(predicate_test)s) 328 { 329 if (fault == NoFault) { 330 %(memacc_code)s; 331 } 332 333 if (fault == NoFault) { 334 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 335 memAccessFlags, NULL); 336 if (traceData) { traceData->setData(Mem); } 337 } 338 339 // Need to write back any potential address register update 340 if (fault == NoFault) { 341 %(op_wb)s; 342 } 343 } 344 345 return fault; 346 } 347}}; 348 349 350def template StoreCompleteAcc {{ 351 Fault %(class_name)s::completeAcc(PacketPtr pkt, 352 %(CPU_exec_context)s *xc, 353 Trace::InstRecord *traceData) const 354 { 355 Fault fault = NoFault; 356 357 %(op_decl)s; 358 %(op_rd)s; 359 360 if (%(predicate_test)s) 361 { 362 if (fault == NoFault) { 363 %(op_wb)s; 364 } 365 } 366 367 return fault; 368 } 369}}; 370 371def template StoreCondCompleteAcc {{ 372 Fault %(class_name)s::completeAcc(PacketPtr pkt, 373 %(CPU_exec_context)s *xc, 374 Trace::InstRecord *traceData) const 375 { 376 Fault fault = NoFault; 377 378 %(op_dest_decl)s; 379 380 if (%(predicate_test)s) 381 { 382 if (fault == NoFault) { 383 %(op_wb)s; 384 } 385 } 386 387 return fault; 388 } 389}}; 390 391 392def template MiscMemAccExecute {{ 393 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 394 Trace::InstRecord *traceData) const 395 { 396 Addr EA; 397 Fault fault = NoFault; 398 399 %(op_decl)s; 400 %(op_rd)s; 401 402 if (%(predicate_test)s) 403 { 404 EA = xc->getEA(); 405 406 if (fault == NoFault) { 407 %(memacc_code)s; 408 } 409 } 410 411 return NoFault; 412 } 413}}; 414 415def template MiscExecute {{ 416 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 417 Trace::InstRecord *traceData) const 418 { 419 Addr EA; 420 Fault fault = NoFault; 421 422 %(op_decl)s; 423 %(op_rd)s; 424 %(ea_code)s; 425 426 if (%(predicate_test)s) 427 { 428 if (fault == NoFault) { 429 %(memacc_code)s; 430 } 431 } 432 433 return NoFault; 434 } 435}}; 436 437def template MiscInitiateAcc {{ 438 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 439 Trace::InstRecord *traceData) const 440 { 441 panic("Misc instruction does not support split access method!"); 442 return NoFault; 443 } 444}}; 445 446 447def template MiscCompleteAcc {{ 448 Fault %(class_name)s::completeAcc(PacketPtr pkt, 449 %(CPU_exec_context)s *xc, 450 Trace::InstRecord *traceData) const 451 { 452 panic("Misc instruction does not support split access method!"); 453 454 return NoFault; 455 } 456}}; 457 458let {{ 459 def buildPUBWLCase(p, u, b, w, l): 460 return (p << 4) + (u << 3) + (b << 2) + (w << 1) + (l << 0) 461 462 def buildMode3Inst(p, u, i, w, type, code, mnem): 463 op = ("-", "+")[u] 464 offset = ("%s Rm", "%s hilo")[i] % op 465 ea_code = "EA = Rn %s;" % ("", offset)[p] 466 if p == 0 or w == 1: 467 code += "Rn = Rn %s;" % offset 468 suffix = "_P%dU%dI%dW%d" % (p, u, i, w) 469 return LoadStoreBase(mnem, mnem.capitalize() + suffix, 470 ea_code, code, mem_flags = [], inst_flags = [], 471 exec_template_base = type.capitalize()) 472}}; 473 474def format AddrMode3(l0Type, l0Code, l1Type, l1Code) {{ 475 l0Code = ArmGenericCodeSubs(l0Code); 476 l1Code = ArmGenericCodeSubs(l1Code); 477 478 header_output = decoder_output = exec_output = "" 479 decode_block = "switch(PUBWL) {\n" 480 (l0Mnem, l1Mnem) = name.split("_"); 481 482 # Loop over all the values of p, u, i, w and l and build instructions and 483 # a decode block for them. 484 for (l, type, code, mnem) in ((0, l0Type, l0Code, l0Mnem), 485 (1, l1Type, l1Code, l1Mnem)): 486 for p in (0, 1): 487 wset = (0, 1) 488 if (p == 0): 489 wset = (0,) 490 for u in (0, 1): 491 for i in (0, 1): 492 for w in wset: 493 (new_header_output, 494 new_decoder_output, 495 new_decode_block, 496 new_exec_output) = buildMode3Inst(p, u, i, w, 497 type, code, mnem) 498 header_output += new_header_output 499 decoder_output += new_decoder_output 500 exec_output += new_exec_output 501 decode_block += ''' 502 case %#x: 503 {%s} 504 break; 505 ''' % (buildPUBWLCase(p,u,i,w,l), new_decode_block) 506 507 decode_block += ''' 508 default: 509 return new Unknown(machInst); 510 break; 511 }''' 512}}; 513 514def format ArmLoadMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 515 mem_flags = [], inst_flags = []) {{ 516 ea_code = ArmGenericCodeSubs(ea_code) 517 memacc_code = ArmGenericCodeSubs(memacc_code) 518 (header_output, decoder_output, decode_block, exec_output) = \ 519 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 520 decode_template = BasicDecode, 521 exec_template_base = 'Load') 522}}; 523 524def format ArmStoreMemory(memacc_code, ea_code = {{ EA = Rn + disp; }}, 525 mem_flags = [], inst_flags = []) {{ 526 ea_code = ArmGenericCodeSubs(ea_code) 527 memacc_code = ArmGenericCodeSubs(memacc_code) 528 (header_output, decoder_output, decode_block, exec_output) = \ 529 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 530 exec_template_base = 'Store') 531}}; 532 533