mem.isa revision 2124
12810SN/A// -*- mode:c++ -*- 28856Sandreas.hansson@arm.com 38856Sandreas.hansson@arm.com// Copyright (c) 2003-2005 The Regents of The University of Michigan 48856Sandreas.hansson@arm.com// All rights reserved. 58856Sandreas.hansson@arm.com// 68856Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without 78856Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are 88856Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright 98856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer; 108856Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright 118856Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the 128856Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution; 138856Sandreas.hansson@arm.com// neither the name of the copyright holders nor the names of its 142810SN/A// contributors may be used to endorse or promote products derived from 152810SN/A// this software without specific prior written permission. 162810SN/A// 172810SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 182810SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 192810SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 202810SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 212810SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 222810SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 232810SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 242810SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 252810SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 262810SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 272810SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282810SN/A 292810SN/Aoutput header {{ 302810SN/A /** 312810SN/A * Base class for general Alpha memory-format instructions. 322810SN/A */ 332810SN/A class Memory : public AlphaStaticInst 342810SN/A { 352810SN/A protected: 362810SN/A 372810SN/A /// Memory request flags. See mem_req_base.hh. 382810SN/A unsigned memAccessFlags; 392810SN/A /// Pointer to EAComp object. 402810SN/A const StaticInstPtr eaCompPtr; 412810SN/A /// Pointer to MemAcc object. 422810SN/A const StaticInstPtr memAccPtr; 432810SN/A 442810SN/A /// Constructor 452810SN/A Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 462810SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 472810SN/A StaticInstPtr _memAccPtr = nullStaticInstPtr) 483348SN/A : AlphaStaticInst(mnem, _machInst, __opClass), 493348SN/A memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) 508232Snate@binkert.org { 519152Satgutier@umich.edu } 525338Sstever@gmail.com 535338Sstever@gmail.com std::string 548786Sgblack@eecs.umich.edu generateDisassembly(Addr pc, const SymbolTable *symtab) const; 552810SN/A 562810SN/A public: 572810SN/A 588856Sandreas.hansson@arm.com const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 598856Sandreas.hansson@arm.com const StaticInstPtr &memAccInst() const { return memAccPtr; } 608856Sandreas.hansson@arm.com }; 618922Swilliam.wang@arm.com 628914Sandreas.hansson@arm.com /** 638856Sandreas.hansson@arm.com * Base class for memory-format instructions using a 32-bit 648856Sandreas.hansson@arm.com * displacement (i.e. most of them). 654475SN/A */ 665034SN/A class MemoryDisp32 : public Memory 675034SN/A { 685314SN/A protected: 695314SN/A /// Displacement for EA calculation (signed). 704628SN/A int32_t disp; 715034SN/A 725034SN/A /// Constructor. 735034SN/A MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, 746122SSteve.Reinhardt@amd.com StaticInstPtr _eaCompPtr = nullStaticInstPtr, 758134SAli.Saidi@ARM.com StaticInstPtr _memAccPtr = nullStaticInstPtr) 764626SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), 774626SN/A disp(MEMDISP) 785034SN/A { 796122SSteve.Reinhardt@amd.com } 808883SAli.Saidi@ARM.com }; 818833Sdam.sunwoo@arm.com 824458SN/A 832810SN/A /** 842810SN/A * Base class for a few miscellaneous memory-format insts 853013SN/A * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. 868856Sandreas.hansson@arm.com * None of these instructions has a destination register either. 872810SN/A */ 883013SN/A class MemoryNoDisp : public Memory 898856Sandreas.hansson@arm.com { 902810SN/A protected: 912810SN/A /// Constructor 922810SN/A MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, 932810SN/A StaticInstPtr _eaCompPtr = nullStaticInstPtr, 948856Sandreas.hansson@arm.com StaticInstPtr _memAccPtr = nullStaticInstPtr) 952810SN/A : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) 963013SN/A { 978856Sandreas.hansson@arm.com } 983013SN/A 998856Sandreas.hansson@arm.com std::string 1008856Sandreas.hansson@arm.com generateDisassembly(Addr pc, const SymbolTable *symtab) const; 1012897SN/A }; 1024666SN/A}}; 1038922Swilliam.wang@arm.com 1042897SN/A 1052810SN/Aoutput decoder {{ 1062810SN/A std::string 1072844SN/A Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1082810SN/A { 1092858SN/A return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 1102858SN/A flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); 1118856Sandreas.hansson@arm.com } 1128922Swilliam.wang@arm.com 1138711Sandreas.hansson@arm.com std::string 1142858SN/A MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const 1152858SN/A { 1168922Swilliam.wang@arm.com return csprintf("%-10s (r%d)", mnemonic, RB); 1178922Swilliam.wang@arm.com } 1188922Swilliam.wang@arm.com}}; 1198922Swilliam.wang@arm.com 1208922Swilliam.wang@arm.comdef format LoadAddress(code) {{ 1218922Swilliam.wang@arm.com iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 1228922Swilliam.wang@arm.com header_output = BasicDeclare.subst(iop) 1238922Swilliam.wang@arm.com decoder_output = BasicConstructor.subst(iop) 1248922Swilliam.wang@arm.com decode_block = BasicDecode.subst(iop) 1258922Swilliam.wang@arm.com exec_output = BasicExecute.subst(iop) 1268922Swilliam.wang@arm.com}}; 1278922Swilliam.wang@arm.com 1288922Swilliam.wang@arm.com 1298922Swilliam.wang@arm.comdef template LoadStoreDeclare {{ 1308922Swilliam.wang@arm.com /** 1318922Swilliam.wang@arm.com * Static instruction class for "%(mnemonic)s". 1328922Swilliam.wang@arm.com */ 1338922Swilliam.wang@arm.com class %(class_name)s : public %(base_class)s 1348922Swilliam.wang@arm.com { 1354628SN/A protected: 1362858SN/A 1372810SN/A /** 1382810SN/A * "Fake" effective address computation class for "%(mnemonic)s". 1392810SN/A */ 1402810SN/A class EAComp : public %(base_class)s 1412810SN/A { 1424022SN/A public: 1434022SN/A /// Constructor 1444022SN/A EAComp(MachInst machInst); 1452810SN/A 1462810SN/A %(BasicExecDeclare)s 1478833Sdam.sunwoo@arm.com }; 1482810SN/A 1492810SN/A /** 1502810SN/A * "Fake" memory access instruction class for "%(mnemonic)s". 1512810SN/A */ 1528833Sdam.sunwoo@arm.com class MemAcc : public %(base_class)s 1538833Sdam.sunwoo@arm.com { 1548833Sdam.sunwoo@arm.com public: 1552810SN/A /// Constructor 1562810SN/A MemAcc(MachInst machInst); 1574871SN/A 1584871SN/A %(BasicExecDeclare)s 1594871SN/A }; 1604871SN/A 1614871SN/A public: 1624871SN/A 1634871SN/A /// Constructor. 1644871SN/A %(class_name)s(MachInst machInst); 1654871SN/A 1664871SN/A %(BasicExecDeclare)s 1672810SN/A 1682810SN/A %(InitiateAccDeclare)s 1692810SN/A 1708833Sdam.sunwoo@arm.com %(CompleteAccDeclare)s 1712810SN/A }; 1724871SN/A}}; 1738833Sdam.sunwoo@arm.com 1748833Sdam.sunwoo@arm.com 1758833Sdam.sunwoo@arm.comdef template InitiateAccDeclare {{ 1762810SN/A Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 1772810SN/A}}; 1782810SN/A 1792810SN/A 1808833Sdam.sunwoo@arm.comdef template CompleteAccDeclare {{ 1812810SN/A Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 1824871SN/A}}; 1838833Sdam.sunwoo@arm.com 1848833Sdam.sunwoo@arm.com 1858833Sdam.sunwoo@arm.comdef template LoadStoreConstructor {{ 1862810SN/A /** TODO: change op_class to AddrGenOp or something (requires 1872810SN/A * creating new member of OpClass enum in op_class.hh, updating 1884022SN/A * config files, etc.). */ 1894022SN/A inline %(class_name)s::EAComp::EAComp(MachInst machInst) 1904022SN/A : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 1912810SN/A { 1922810SN/A %(ea_constructor)s; 1938833Sdam.sunwoo@arm.com } 1942810SN/A 1952810SN/A inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) 1962810SN/A : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 1972810SN/A { 1988833Sdam.sunwoo@arm.com %(memacc_constructor)s; 1998833Sdam.sunwoo@arm.com } 2008833Sdam.sunwoo@arm.com 2012810SN/A inline %(class_name)s::%(class_name)s(MachInst machInst) 2022810SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 2032810SN/A new EAComp(machInst), new MemAcc(machInst)) 2042810SN/A { 2052810SN/A %(constructor)s; 2068833Sdam.sunwoo@arm.com } 2072810SN/A}}; 2084871SN/A 2098833Sdam.sunwoo@arm.com 2108833Sdam.sunwoo@arm.comdef template EACompExecute {{ 2118833Sdam.sunwoo@arm.com Fault * 2122810SN/A %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 2132810SN/A Trace::InstRecord *traceData) const 2142810SN/A { 2152810SN/A Addr EA; 2168833Sdam.sunwoo@arm.com Fault * fault = NoFault; 2172810SN/A 2184871SN/A %(fp_enable_check)s; 2198833Sdam.sunwoo@arm.com %(op_decl)s; 2208833Sdam.sunwoo@arm.com %(op_rd)s; 2218833Sdam.sunwoo@arm.com %(code)s; 2222810SN/A 2232810SN/A if (fault == NoFault) { 2244022SN/A %(op_wb)s; 2254022SN/A xc->setEA(EA); 2264022SN/A } 2272810SN/A 2282810SN/A return fault; 2298833Sdam.sunwoo@arm.com } 2302810SN/A}}; 2312810SN/A 2322810SN/Adef template LoadMemAccExecute {{ 2332810SN/A Fault * 2348833Sdam.sunwoo@arm.com %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 2358833Sdam.sunwoo@arm.com Trace::InstRecord *traceData) const 2368833Sdam.sunwoo@arm.com { 2372810SN/A Addr EA; 2382810SN/A Fault * fault = NoFault; 2392810SN/A 2402810SN/A %(fp_enable_check)s; 2412810SN/A %(op_decl)s; 2428833Sdam.sunwoo@arm.com %(op_rd)s; 2432810SN/A EA = xc->getEA(); 2444871SN/A 2458833Sdam.sunwoo@arm.com if (fault == NoFault) { 2468833Sdam.sunwoo@arm.com fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2478833Sdam.sunwoo@arm.com %(code)s; 2482810SN/A } 2492810SN/A 2502810SN/A if (fault == NoFault) { 2512810SN/A %(op_wb)s; 2528833Sdam.sunwoo@arm.com } 2532810SN/A 2544871SN/A return fault; 2558833Sdam.sunwoo@arm.com } 2568833Sdam.sunwoo@arm.com}}; 2578833Sdam.sunwoo@arm.com 2582810SN/A 2592810SN/Adef template LoadExecute {{ 2604022SN/A Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, 2614022SN/A Trace::InstRecord *traceData) const 2624022SN/A { 2632810SN/A Addr EA; 2642810SN/A Fault * fault = NoFault; 2652810SN/A 2662810SN/A %(fp_enable_check)s; 2672810SN/A %(op_decl)s; 2682810SN/A %(op_rd)s; 2698833Sdam.sunwoo@arm.com %(ea_code)s; 2702810SN/A 2718833Sdam.sunwoo@arm.com if (fault == NoFault) { 2728833Sdam.sunwoo@arm.com fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 2738833Sdam.sunwoo@arm.com %(memacc_code)s; 2742810SN/A } 2752810SN/A 2762810SN/A if (fault == NoFault) { 2772810SN/A %(op_wb)s; 2782810SN/A } 2798833Sdam.sunwoo@arm.com 2802810SN/A return fault; 2812810SN/A } 2828833Sdam.sunwoo@arm.com}}; 2838833Sdam.sunwoo@arm.com 2848833Sdam.sunwoo@arm.com 2852810SN/Adef template LoadInitiateAcc {{ 2862810SN/A Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 2872810SN/A Trace::InstRecord *traceData) const 2882810SN/A { 2898833Sdam.sunwoo@arm.com Addr EA; 2902810SN/A Fault * fault = NoFault; 2912810SN/A 2928833Sdam.sunwoo@arm.com %(fp_enable_check)s; 2938833Sdam.sunwoo@arm.com %(op_src_decl)s; 2948833Sdam.sunwoo@arm.com %(op_rd)s; 2952810SN/A %(ea_code)s; 2962810SN/A 2974022SN/A if (fault == NoFault) { 2984022SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 2994022SN/A } 3002810SN/A 3012810SN/A return fault; 3022810SN/A } 3032810SN/A}}; 3042810SN/A 3052810SN/A 3068833Sdam.sunwoo@arm.comdef template LoadCompleteAcc {{ 3072810SN/A Fault * %(class_name)s::completeAcc(uint8_t *data, 3088833Sdam.sunwoo@arm.com %(CPU_exec_context)s *xc, 3098833Sdam.sunwoo@arm.com Trace::InstRecord *traceData) const 3108833Sdam.sunwoo@arm.com { 3112810SN/A Fault * fault = NoFault; 3122810SN/A 3132810SN/A %(fp_enable_check)s; 3142810SN/A %(op_src_decl)s; 3152810SN/A %(op_dest_decl)s; 3168833Sdam.sunwoo@arm.com 3172810SN/A memcpy(&Mem, data, sizeof(Mem)); 3182810SN/A 3198833Sdam.sunwoo@arm.com if (fault == NoFault) { 3208833Sdam.sunwoo@arm.com %(memacc_code)s; 3218833Sdam.sunwoo@arm.com } 3222810SN/A 3232810SN/A if (fault == NoFault) { 3242810SN/A %(op_wb)s; 3252810SN/A } 3268833Sdam.sunwoo@arm.com 3272810SN/A return fault; 3282810SN/A } 3298833Sdam.sunwoo@arm.com}}; 3308833Sdam.sunwoo@arm.com 3318833Sdam.sunwoo@arm.com 3322810SN/Adef template StoreMemAccExecute {{ 3332810SN/A Fault * 3344022SN/A %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 3354022SN/A Trace::InstRecord *traceData) const 3364022SN/A { 3372810SN/A Addr EA; 3382810SN/A Fault * fault = NoFault; 3392810SN/A uint64_t write_result = 0; 3402810SN/A 3412810SN/A %(fp_enable_check)s; 3422810SN/A %(op_decl)s; 3432810SN/A %(op_rd)s; 3442810SN/A EA = xc->getEA(); 3458833Sdam.sunwoo@arm.com 3468833Sdam.sunwoo@arm.com if (fault == NoFault) { 3478833Sdam.sunwoo@arm.com %(code)s; 3488833Sdam.sunwoo@arm.com } 3492810SN/A 3502810SN/A if (fault == NoFault) { 3512810SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3522810SN/A memAccessFlags, &write_result); 3532810SN/A if (traceData) { traceData->setData(Mem); } 3548833Sdam.sunwoo@arm.com } 3552810SN/A 3562810SN/A if (fault == NoFault) { 3578833Sdam.sunwoo@arm.com %(postacc_code)s; 3588833Sdam.sunwoo@arm.com } 3598833Sdam.sunwoo@arm.com 3602810SN/A if (fault == NoFault) { 3612810SN/A %(op_wb)s; 3622810SN/A } 3632810SN/A 3648833Sdam.sunwoo@arm.com return fault; 3652810SN/A } 3662810SN/A}}; 3678833Sdam.sunwoo@arm.com 3688833Sdam.sunwoo@arm.com 3698833Sdam.sunwoo@arm.comdef template StoreExecute {{ 3702810SN/A Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, 3712810SN/A Trace::InstRecord *traceData) const 3722810SN/A { 3732810SN/A Addr EA; 3742810SN/A Fault * fault = NoFault; 3752810SN/A uint64_t write_result = 0; 3762810SN/A 3772810SN/A %(fp_enable_check)s; 3782810SN/A %(op_decl)s; 3792810SN/A %(op_rd)s; 3802810SN/A %(ea_code)s; 3812810SN/A 3822810SN/A if (fault == NoFault) { 3832810SN/A %(memacc_code)s; 3842810SN/A } 3852810SN/A 3862810SN/A if (fault == NoFault) { 3872810SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 3882810SN/A memAccessFlags, &write_result); 3892810SN/A if (traceData) { traceData->setData(Mem); } 3902810SN/A } 3912810SN/A 3922810SN/A if (fault == NoFault) { 3932810SN/A %(postacc_code)s; 3942810SN/A } 3952810SN/A 3962810SN/A if (fault == NoFault) { 3972810SN/A %(op_wb)s; 3982810SN/A } 3992810SN/A 4002810SN/A return fault; 4012810SN/A } 4022810SN/A}}; 4032810SN/A 4042810SN/Adef template StoreInitiateAcc {{ 4052810SN/A Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 4062826SN/A Trace::InstRecord *traceData) const 4074626SN/A { 4088833Sdam.sunwoo@arm.com Addr EA; 4094626SN/A Fault * fault = NoFault; 4104626SN/A uint64_t write_result = 0; 4118833Sdam.sunwoo@arm.com 4124626SN/A %(fp_enable_check)s; 4138833Sdam.sunwoo@arm.com %(op_src_decl)s; 4148833Sdam.sunwoo@arm.com %(op_dest_decl)s; 4158833Sdam.sunwoo@arm.com %(op_rd)s; 4164626SN/A %(ea_code)s; 4174626SN/A 4184626SN/A if (fault == NoFault) { 4194626SN/A %(memacc_code)s; 4204626SN/A } 4214626SN/A 4224626SN/A if (fault == NoFault) { 4234626SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 4248833Sdam.sunwoo@arm.com memAccessFlags, &write_result); 4254626SN/A if (traceData) { traceData->setData(Mem); } 4264626SN/A } 4274626SN/A 4284626SN/A return fault; 4298833Sdam.sunwoo@arm.com } 4308833Sdam.sunwoo@arm.com}}; 4318833Sdam.sunwoo@arm.com 4324626SN/A 4334626SN/Adef template StoreCompleteAcc {{ 4344626SN/A Fault * %(class_name)s::completeAcc(uint8_t *data, 4354626SN/A %(CPU_exec_context)s *xc, 4364626SN/A Trace::InstRecord *traceData) const 4378833Sdam.sunwoo@arm.com { 4384626SN/A Fault * fault = NoFault; 4394871SN/A uint64_t write_result = 0; 4408833Sdam.sunwoo@arm.com 4418833Sdam.sunwoo@arm.com %(fp_enable_check)s; 4428833Sdam.sunwoo@arm.com %(op_dest_decl)s; 4434626SN/A 4444626SN/A memcpy(&write_result, data, sizeof(write_result)); 4454626SN/A 4464626SN/A if (fault == NoFault) { 4478833Sdam.sunwoo@arm.com %(postacc_code)s; 4484626SN/A } 4494871SN/A 4508833Sdam.sunwoo@arm.com if (fault == NoFault) { 4518833Sdam.sunwoo@arm.com %(op_wb)s; 4528833Sdam.sunwoo@arm.com } 4534626SN/A 4544626SN/A return fault; 4554626SN/A } 4564626SN/A}}; 4574626SN/A 4584626SN/A 4594626SN/Adef template MiscMemAccExecute {{ 4608833Sdam.sunwoo@arm.com Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 4614626SN/A Trace::InstRecord *traceData) const 4624626SN/A { 4634626SN/A Addr EA; 4644626SN/A Fault * fault = NoFault; 4658833Sdam.sunwoo@arm.com 4668833Sdam.sunwoo@arm.com %(fp_enable_check)s; 4678833Sdam.sunwoo@arm.com %(op_decl)s; 4684626SN/A %(op_rd)s; 4694626SN/A EA = xc->getEA(); 4704626SN/A 4714626SN/A if (fault == NoFault) { 4724626SN/A %(code)s; 4738833Sdam.sunwoo@arm.com } 4744626SN/A 4754871SN/A return NoFault; 4768833Sdam.sunwoo@arm.com } 4778833Sdam.sunwoo@arm.com}}; 4788833Sdam.sunwoo@arm.com 4794626SN/Adef template MiscExecute {{ 4804626SN/A Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, 4814626SN/A Trace::InstRecord *traceData) const 4824626SN/A { 4838833Sdam.sunwoo@arm.com Addr EA; 4844626SN/A Fault * fault = NoFault; 4854871SN/A 4868833Sdam.sunwoo@arm.com %(fp_enable_check)s; 4878833Sdam.sunwoo@arm.com %(op_decl)s; 4888833Sdam.sunwoo@arm.com %(op_rd)s; 4894626SN/A %(ea_code)s; 4904626SN/A 4914626SN/A if (fault == NoFault) { 4924626SN/A %(memacc_code)s; 4934626SN/A } 4944626SN/A 4954626SN/A return NoFault; 4968833Sdam.sunwoo@arm.com } 4974626SN/A}}; 4984626SN/A 4994626SN/Adef template MiscInitiateAcc {{ 5004626SN/A Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 5018833Sdam.sunwoo@arm.com Trace::InstRecord *traceData) const 5028833Sdam.sunwoo@arm.com { 5038833Sdam.sunwoo@arm.com panic("Misc instruction does not support split access method!"); 5044626SN/A return NoFault; 5054626SN/A } 5064626SN/A}}; 5074626SN/A 5084626SN/A 5098833Sdam.sunwoo@arm.comdef template MiscCompleteAcc {{ 5104626SN/A Fault * %(class_name)s::completeAcc(uint8_t *data, 5114871SN/A %(CPU_exec_context)s *xc, 5128833Sdam.sunwoo@arm.com Trace::InstRecord *traceData) const 5138833Sdam.sunwoo@arm.com { 5148833Sdam.sunwoo@arm.com panic("Misc instruction does not support split access method!"); 5154626SN/A 5164626SN/A return NoFault; 5174626SN/A } 5184626SN/A}}; 5198833Sdam.sunwoo@arm.com 5204626SN/A// load instructions use Ra as dest, so check for 5214871SN/A// Ra == 31 to detect nops 5224871SN/Adef template LoadNopCheckDecode {{ 5238833Sdam.sunwoo@arm.com { 5248833Sdam.sunwoo@arm.com AlphaStaticInst *i = new %(class_name)s(machInst); 5258833Sdam.sunwoo@arm.com if (RA == 31) { 5264626SN/A i = makeNop(i); 5274626SN/A } 5284626SN/A return i; 5294626SN/A } 5304626SN/A}}; 5314626SN/A 5324626SN/A 5338833Sdam.sunwoo@arm.com// for some load instructions, Ra == 31 indicates a prefetch (not a nop) 5344626SN/Adef template LoadPrefetchCheckDecode {{ 5354626SN/A { 5364626SN/A if (RA != 31) { 5374626SN/A return new %(class_name)s(machInst); 5388833Sdam.sunwoo@arm.com } 5398833Sdam.sunwoo@arm.com else { 5408833Sdam.sunwoo@arm.com return new %(class_name)sPrefetch(machInst); 5414626SN/A } 5424626SN/A } 5434626SN/A}}; 5444626SN/A 5454626SN/A 5468833Sdam.sunwoo@arm.comlet {{ 5474626SN/Adef LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 5484871SN/A postacc_code = '', base_class = 'MemoryDisp32', 5494871SN/A decode_template = BasicDecode, exec_template_base = ''): 5508833Sdam.sunwoo@arm.com # Make sure flags are in lists (convert to lists if not). 5518833Sdam.sunwoo@arm.com mem_flags = makeList(mem_flags) 5528833Sdam.sunwoo@arm.com inst_flags = makeList(inst_flags) 5534626SN/A 5544626SN/A # add hook to get effective addresses into execution trace output. 5554626SN/A ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' 5564626SN/A 5574626SN/A # generate code block objects 5584626SN/A ea_cblk = CodeBlock(ea_code) 5594626SN/A memacc_cblk = CodeBlock(memacc_code) 5608833Sdam.sunwoo@arm.com postacc_cblk = CodeBlock(postacc_code) 5614626SN/A 5624626SN/A # Some CPU models execute the memory operation as an atomic unit, 5634626SN/A # while others want to separate them into an effective address 5644626SN/A # computation and a memory access operation. As a result, we need 5658833Sdam.sunwoo@arm.com # to generate three StaticInst objects. Note that the latter two 5668833Sdam.sunwoo@arm.com # are nested inside the larger "atomic" one. 5678833Sdam.sunwoo@arm.com 5684626SN/A # generate InstObjParams for EAComp object 5694626SN/A ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) 5704626SN/A 5714626SN/A # generate InstObjParams for MemAcc object 5724626SN/A memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) 5738833Sdam.sunwoo@arm.com # in the split execution model, the MemAcc portion is responsible 5744626SN/A # for the post-access code. 5754871SN/A memacc_iop.postacc_code = postacc_cblk.code 5764871SN/A 5774871SN/A # generate InstObjParams for InitiateAcc, CompleteAcc object 5788833Sdam.sunwoo@arm.com # The code used depends on the template being used 5798833Sdam.sunwoo@arm.com if (exec_template_base == 'Load'): 5808833Sdam.sunwoo@arm.com initiateacc_cblk = CodeBlock(ea_code + memacc_code) 5814626SN/A completeacc_cblk = CodeBlock(memacc_code + postacc_code) 5824626SN/A elif (exec_template_base == 'Store'): 5834626SN/A initiateacc_cblk = CodeBlock(ea_code + memacc_code) 5844626SN/A completeacc_cblk = CodeBlock(postacc_code) 5854626SN/A else: 5864626SN/A initiateacc_cblk = '' 5874626SN/A completeacc_cblk = '' 5884626SN/A 5894626SN/A initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, 5904626SN/A inst_flags) 5914626SN/A 5924626SN/A completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, 5934626SN/A inst_flags) 5944626SN/A 5954626SN/A if (exec_template_base == 'Load'): 5964626SN/A initiateacc_iop.ea_code = ea_cblk.code 5974626SN/A initiateacc_iop.memacc_code = memacc_cblk.code 5984626SN/A completeacc_iop.memacc_code = memacc_cblk.code 5994626SN/A completeacc_iop.postacc_code = postacc_cblk.code 6004626SN/A elif (exec_template_base == 'Store'): 6014626SN/A initiateacc_iop.ea_code = ea_cblk.code 6024626SN/A initiateacc_iop.memacc_code = memacc_cblk.code 6034626SN/A completeacc_iop.postacc_code = postacc_cblk.code 6044626SN/A 6054626SN/A # generate InstObjParams for unified execution 6064626SN/A cblk = CodeBlock(ea_code + memacc_code + postacc_code) 6074626SN/A iop = InstObjParams(name, Name, base_class, cblk, inst_flags) 6084626SN/A 6094626SN/A iop.ea_constructor = ea_cblk.constructor 6104626SN/A iop.ea_code = ea_cblk.code 6114626SN/A iop.memacc_constructor = memacc_cblk.constructor 6124626SN/A iop.memacc_code = memacc_cblk.code 6134626SN/A iop.postacc_code = postacc_cblk.code 6144626SN/A 6154626SN/A if mem_flags: 6164626SN/A s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' 6174626SN/A iop.constructor += s 6184626SN/A memacc_iop.constructor += s 6194626SN/A 6204626SN/A # select templates 6214626SN/A memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') 6224626SN/A fullExecTemplate = eval(exec_template_base + 'Execute') 6234626SN/A initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') 6244626SN/A completeAccTemplate = eval(exec_template_base + 'CompleteAcc') 6254626SN/A 6268833Sdam.sunwoo@arm.com # (header_output, decoder_output, decode_block, exec_output) 6278833Sdam.sunwoo@arm.com return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), 6288833Sdam.sunwoo@arm.com decode_template.subst(iop), 6298833Sdam.sunwoo@arm.com EACompExecute.subst(ea_iop) 6304626SN/A + memAccExecTemplate.subst(memacc_iop) 6314626SN/A + fullExecTemplate.subst(iop) 6324626SN/A + initiateAccTemplate.subst(initiateacc_iop) 6334626SN/A + completeAccTemplate.subst(completeacc_iop)) 6344626SN/A}}; 6358833Sdam.sunwoo@arm.com 6364626SN/A 6374626SN/Adef format LoadOrNop(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6388833Sdam.sunwoo@arm.com mem_flags = [], inst_flags = []) {{ 6398833Sdam.sunwoo@arm.com (header_output, decoder_output, decode_block, exec_output) = \ 6408833Sdam.sunwoo@arm.com LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6414626SN/A decode_template = LoadNopCheckDecode, 6424626SN/A exec_template_base = 'Load') 6434626SN/A}}; 6444626SN/A 6458833Sdam.sunwoo@arm.com 6464626SN/A// Note that the flags passed in apply only to the prefetch version 6474626SN/Adef format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6488833Sdam.sunwoo@arm.com mem_flags = [], pf_flags = [], inst_flags = []) {{ 6498833Sdam.sunwoo@arm.com # declare the load instruction object and generate the decode block 6508833Sdam.sunwoo@arm.com (header_output, decoder_output, decode_block, exec_output) = \ 6514626SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6524626SN/A decode_template = LoadPrefetchCheckDecode, 6534626SN/A exec_template_base = 'Load') 6544626SN/A 6554626SN/A # Declare the prefetch instruction object. 6564626SN/A 6574626SN/A # Make sure flag args are lists so we can mess with them. 6584626SN/A mem_flags = makeList(mem_flags) 6594626SN/A pf_flags = makeList(pf_flags) 6604626SN/A inst_flags = makeList(inst_flags) 6614626SN/A 6624626SN/A pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 6634626SN/A pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 6648833Sdam.sunwoo@arm.com 'IsDataPrefetch', 'MemReadOp'] 6658833Sdam.sunwoo@arm.com 6668833Sdam.sunwoo@arm.com (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ 6678833Sdam.sunwoo@arm.com LoadStoreBase(name, Name + 'Prefetch', ea_code, 6684626SN/A 'xc->prefetch(EA, memAccessFlags);', 6694626SN/A pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 6704626SN/A 6714626SN/A header_output += pf_header_output 6724626SN/A decoder_output += pf_decoder_output 6738833Sdam.sunwoo@arm.com exec_output += pf_exec_output 6744626SN/A}}; 6754626SN/A 6768833Sdam.sunwoo@arm.com 6778833Sdam.sunwoo@arm.comdef format Store(memacc_code, ea_code = {{ EA = Rb + disp; }}, 6788833Sdam.sunwoo@arm.com mem_flags = [], inst_flags = []) {{ 6794626SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6804626SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6814626SN/A exec_template_base = 'Store') 6824626SN/A}}; 6838833Sdam.sunwoo@arm.com 6844626SN/A 6854626SN/Adef format StoreCond(memacc_code, postacc_code, 6868833Sdam.sunwoo@arm.com ea_code = {{ EA = Rb + disp; }}, 6878833Sdam.sunwoo@arm.com mem_flags = [], inst_flags = []) {{ 6888833Sdam.sunwoo@arm.com (header_output, decoder_output, decode_block, exec_output) = \ 6894626SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6904626SN/A postacc_code, exec_template_base = 'Store') 6914626SN/A}}; 6924626SN/A 6934626SN/A 6944626SN/A// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb 6954626SN/Adef format MiscPrefetch(ea_code, memacc_code, 6964626SN/A mem_flags = [], inst_flags = []) {{ 6974626SN/A (header_output, decoder_output, decode_block, exec_output) = \ 6984626SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 6994626SN/A base_class = 'MemoryNoDisp', exec_template_base = 'Misc') 7004626SN/A}}; 7014626SN/A 7028833Sdam.sunwoo@arm.com 7038833Sdam.sunwoo@arm.com