mem.isa revision 6691:cd68b6ecd68d
19793Sakash.bagdia@arm.com// -*- mode:c++ -*- 28706Sandreas.hansson@arm.com 38706Sandreas.hansson@arm.com// Copyright (c) 2009 The University of Edinburgh 48706Sandreas.hansson@arm.com// All rights reserved. 58706Sandreas.hansson@arm.com// 68706Sandreas.hansson@arm.com// Redistribution and use in source and binary forms, with or without 78706Sandreas.hansson@arm.com// modification, are permitted provided that the following conditions are 88706Sandreas.hansson@arm.com// met: redistributions of source code must retain the above copyright 98706Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer; 108706Sandreas.hansson@arm.com// redistributions in binary form must reproduce the above copyright 118706Sandreas.hansson@arm.com// notice, this list of conditions and the following disclaimer in the 128706Sandreas.hansson@arm.com// documentation and/or other materials provided with the distribution; 135369Ssaidi@eecs.umich.edu// neither the name of the copyright holders nor the names of its 143005Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from 153005Sstever@eecs.umich.edu// this software without specific prior written permission. 163005Sstever@eecs.umich.edu// 173005Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 183005Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193005Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 203005Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 213005Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 223005Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 233005Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 243005Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 253005Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 263005Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 273005Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 283005Sstever@eecs.umich.edu// 293005Sstever@eecs.umich.edu// Authors: Timothy M. Jones 303005Sstever@eecs.umich.edu 313005Sstever@eecs.umich.edu//////////////////////////////////////////////////////////////////// 323005Sstever@eecs.umich.edu// 333005Sstever@eecs.umich.edu// Memory-format instructions 343005Sstever@eecs.umich.edu// 353005Sstever@eecs.umich.edu 363005Sstever@eecs.umich.edudef template LoadStoreDeclare {{ 373005Sstever@eecs.umich.edu /** 383005Sstever@eecs.umich.edu * Static instruction class for "%(mnemonic)s". 393005Sstever@eecs.umich.edu */ 403005Sstever@eecs.umich.edu class %(class_name)s : public %(base_class)s 412710SN/A { 422710SN/A public: 433005Sstever@eecs.umich.edu 442889SN/A /// Constructor. 456654Snate@binkert.org %(class_name)s(ExtMachInst machInst); 466654Snate@binkert.org 479907Snilay@cs.wisc.edu %(BasicExecDeclare)s 486654Snate@binkert.org 492667SN/A %(InitiateAccDeclare)s 506654Snate@binkert.org 516654Snate@binkert.org %(CompleteAccDeclare)s 526654Snate@binkert.org }; 535457Ssaidi@eecs.umich.edu}}; 546654Snate@binkert.org 558169SLisa.Hsu@amd.com 568169SLisa.Hsu@amd.comdef template InitiateAccDeclare {{ 578920Snilay@cs.wisc.edu Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 588169SLisa.Hsu@amd.com}}; 593395Shsul@eecs.umich.edu 606981SLisa.Hsu@amd.com 619836Sandreas.hansson@arm.comdef template CompleteAccDeclare {{ 623448Shsul@eecs.umich.edu Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 635369Ssaidi@eecs.umich.edu}}; 643394Shsul@eecs.umich.edu 659197Snilay@cs.wisc.edu 669197Snilay@cs.wisc.edudef template LoadStoreConstructor {{ 679197Snilay@cs.wisc.edu inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 689197Snilay@cs.wisc.edu : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 699197Snilay@cs.wisc.edu { 709197Snilay@cs.wisc.edu %(constructor)s; 719197Snilay@cs.wisc.edu } 729197Snilay@cs.wisc.edu}}; 739197Snilay@cs.wisc.edu 749197Snilay@cs.wisc.edu 759197Snilay@cs.wisc.edudef template LoadExecute {{ 769197Snilay@cs.wisc.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 779197Snilay@cs.wisc.edu Trace::InstRecord *traceData) const 789197Snilay@cs.wisc.edu { 799197Snilay@cs.wisc.edu Addr EA; 809197Snilay@cs.wisc.edu Fault fault = NoFault; 819197Snilay@cs.wisc.edu 829197Snilay@cs.wisc.edu %(op_decl)s; 839197Snilay@cs.wisc.edu %(op_rd)s; 849197Snilay@cs.wisc.edu %(ea_code)s; 859197Snilay@cs.wisc.edu 869197Snilay@cs.wisc.edu if (fault == NoFault) { 879197Snilay@cs.wisc.edu fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 889907Snilay@cs.wisc.edu %(memacc_code)s; 899197Snilay@cs.wisc.edu } 909197Snilay@cs.wisc.edu 919217Snilay@cs.wisc.edu if (fault == NoFault) { 929197Snilay@cs.wisc.edu %(op_wb)s; 939197Snilay@cs.wisc.edu } 949197Snilay@cs.wisc.edu 959197Snilay@cs.wisc.edu return fault; 969197Snilay@cs.wisc.edu } 979197Snilay@cs.wisc.edu}}; 989197Snilay@cs.wisc.edu 999197Snilay@cs.wisc.edu 1009197Snilay@cs.wisc.edudef template LoadInitiateAcc {{ 1019197Snilay@cs.wisc.edu Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 1029197Snilay@cs.wisc.edu Trace::InstRecord *traceData) const 1039197Snilay@cs.wisc.edu { 1049197Snilay@cs.wisc.edu Addr EA; 1059197Snilay@cs.wisc.edu Fault fault = NoFault; 1069197Snilay@cs.wisc.edu 1079197Snilay@cs.wisc.edu %(op_src_decl)s; 1089197Snilay@cs.wisc.edu %(op_rd)s; 1099197Snilay@cs.wisc.edu %(ea_code)s; 1109197Snilay@cs.wisc.edu 1119197Snilay@cs.wisc.edu if (fault == NoFault) { 1122957SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 1138920Snilay@cs.wisc.edu xc->setEA(EA); 1148920Snilay@cs.wisc.edu } 1152957SN/A 1168862Snilay@cs.wisc.edu return fault; 1178862Snilay@cs.wisc.edu } 1188467Snilay@cs.wisc.edu}}; 1192957SN/A 1202957SN/A 1212957SN/Adef template LoadCompleteAcc {{ 1222957SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 1232957SN/A %(CPU_exec_context)s *xc, 1242957SN/A Trace::InstRecord *traceData) const 1258167SLisa.Hsu@amd.com { 1269197Snilay@cs.wisc.edu Addr EA; 1278167SLisa.Hsu@amd.com Fault fault = NoFault; 1285369Ssaidi@eecs.umich.edu uint%(mem_acc_size)d_t val; 1298167SLisa.Hsu@amd.com 1308167SLisa.Hsu@amd.com %(op_decl)s; 1318167SLisa.Hsu@amd.com %(op_rd)s; 1328167SLisa.Hsu@amd.com 1338167SLisa.Hsu@amd.com EA = xc->getEA(); 1348167SLisa.Hsu@amd.com 1358167SLisa.Hsu@amd.com val = pkt->get<uint%(mem_acc_size)d_t>(); 1368168SLisa.Hsu@amd.com *((uint%(mem_acc_size)d_t*)&Mem) = val; 13710037SARM gem5 Developers 13810037SARM gem5 Developers if (fault == NoFault) { 13910037SARM gem5 Developers %(memacc_code)s; 14010037SARM gem5 Developers } 14110037SARM gem5 Developers 1428168SLisa.Hsu@amd.com if (fault == NoFault) { 14310037SARM gem5 Developers %(op_wb)s; 14410037SARM gem5 Developers } 1458167SLisa.Hsu@amd.com 1468167SLisa.Hsu@amd.com return fault; 14710118Snilay@cs.wisc.edu } 14810118Snilay@cs.wisc.edu}}; 1495369Ssaidi@eecs.umich.edu 1508920Snilay@cs.wisc.edu 1519197Snilay@cs.wisc.edudef template StoreExecute {{ 1528920Snilay@cs.wisc.edu Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 1538920Snilay@cs.wisc.edu Trace::InstRecord *traceData) const 1548920Snilay@cs.wisc.edu { 1555369Ssaidi@eecs.umich.edu Addr EA; 1565369Ssaidi@eecs.umich.edu Fault fault = NoFault; 1578718Snilay@cs.wisc.edu 1589197Snilay@cs.wisc.edu %(op_decl)s; 1599197Snilay@cs.wisc.edu %(op_rd)s; 1609197Snilay@cs.wisc.edu %(ea_code)s; 1619197Snilay@cs.wisc.edu 1629197Snilay@cs.wisc.edu if (fault == NoFault) { 1633005Sstever@eecs.umich.edu %(memacc_code)s; 1643395Shsul@eecs.umich.edu } 1653395Shsul@eecs.umich.edu 1669793Sakash.bagdia@arm.com if (fault == NoFault) { 1679836Sandreas.hansson@arm.com fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 1689815SAndreas Hansson <andreas.hansson> memAccessFlags, NULL); 1699793Sakash.bagdia@arm.com if (traceData) { traceData->setData(Mem); } 1709827Sakash.bagdia@arm.com } 1719827Sakash.bagdia@arm.com 1729827Sakash.bagdia@arm.com if (fault == NoFault) { 1739827Sakash.bagdia@arm.com %(op_wb)s; 1749827Sakash.bagdia@arm.com } 1759827Sakash.bagdia@arm.com 1769827Sakash.bagdia@arm.com return fault; 1779827Sakash.bagdia@arm.com } 1789827Sakash.bagdia@arm.com}}; 1799827Sakash.bagdia@arm.com 1809793Sakash.bagdia@arm.com 1819827Sakash.bagdia@arm.comdef template StoreInitiateAcc {{ 1829827Sakash.bagdia@arm.com Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 1839827Sakash.bagdia@arm.com Trace::InstRecord *traceData) const 1849793Sakash.bagdia@arm.com { 1859793Sakash.bagdia@arm.com Addr EA; 1869793Sakash.bagdia@arm.com Fault fault = NoFault; 1879793Sakash.bagdia@arm.com 1889793Sakash.bagdia@arm.com %(op_decl)s; 1893395Shsul@eecs.umich.edu %(op_rd)s; 1908926Sandreas.hansson@arm.com %(ea_code)s; 1919317Sandreas.hansson@arm.com 1929317Sandreas.hansson@arm.com if (fault == NoFault) { 1939317Sandreas.hansson@arm.com %(memacc_code)s; 1949317Sandreas.hansson@arm.com } 1959317Sandreas.hansson@arm.com 1968926Sandreas.hansson@arm.com if (fault == NoFault) { 1979647Sdam.sunwoo@arm.com fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 1989647Sdam.sunwoo@arm.com memAccessFlags, NULL); 1999647Sdam.sunwoo@arm.com if (traceData) { traceData->setData(Mem); } 2009647Sdam.sunwoo@arm.com } 2019647Sdam.sunwoo@arm.com 2029647Sdam.sunwoo@arm.com // Need to write back any potential address register update 2039647Sdam.sunwoo@arm.com if (fault == NoFault) { 2043395Shsul@eecs.umich.edu %(op_wb)s; 2059197Snilay@cs.wisc.edu } 2069197Snilay@cs.wisc.edu 2079197Snilay@cs.wisc.edu return fault; 2088957Sjayneel@cs.wisc.edu } 2098957Sjayneel@cs.wisc.edu}}; 2108957Sjayneel@cs.wisc.edu 2113005Sstever@eecs.umich.edu 2124968Sacolyte@umich.edudef template StoreCompleteAcc {{ 2139006Sandreas.hansson@arm.com Fault %(class_name)s::completeAcc(PacketPtr pkt, 2144968Sacolyte@umich.edu %(CPU_exec_context)s *xc, 2159647Sdam.sunwoo@arm.com Trace::InstRecord *traceData) const 21610381Sdam.sunwoo@arm.com { 2179647Sdam.sunwoo@arm.com Fault fault = NoFault; 2188887Sgeoffrey.blake@arm.com 2198887Sgeoffrey.blake@arm.com %(op_dest_decl)s; 2208887Sgeoffrey.blake@arm.com 2219384SAndreas.Sandberg@arm.com if (fault == NoFault) { 2229384SAndreas.Sandberg@arm.com %(op_wb)s; 2238887Sgeoffrey.blake@arm.com } 2248896Snilay@cs.wisc.edu 2258896Snilay@cs.wisc.edu return fault; 2268896Snilay@cs.wisc.edu } 2278896Snilay@cs.wisc.edu}}; 22810150Snilay@cs.wisc.edu 22910150Snilay@cs.wisc.edu 23010150Snilay@cs.wisc.edu// The generic memory operation generator. This is called when two versions 23110150Snilay@cs.wisc.edu// of an instruction are needed - when Ra == 0 and otherwise. This is so 2329836Sandreas.hansson@arm.com// that instructions can use the value 0 when Ra == 0 but avoid having a 23310092Snilay@cs.wisc.edu// dependence on Ra. 23410117Snilay@cs.wisc.edulet {{ 23510120Snilay@cs.wisc.edu 2368896Snilay@cs.wisc.edudef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 23710300Scastilloe@unican.es load_or_store, mem_flags = [], inst_flags = []): 23810300Scastilloe@unican.es 2398896Snilay@cs.wisc.edu # First the version where Ra is non-zero 24010120Snilay@cs.wisc.edu (header_output, decoder_output, decode_block, exec_output) = \ 2418896Snilay@cs.wisc.edu LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 2428896Snilay@cs.wisc.edu base_class = base, 2439268Smalek.musleh@gmail.com decode_template = CheckRaDecode, 2449268Smalek.musleh@gmail.com exec_template_base = load_or_store) 2458896Snilay@cs.wisc.edu 2468896Snilay@cs.wisc.edu # Now another version where Ra == 0 2478896Snilay@cs.wisc.edu (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 2488896Snilay@cs.wisc.edu LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 2498896Snilay@cs.wisc.edu mem_flags, inst_flags, 2509222Shestness@cs.wisc.edu base_class = base, 2519268Smalek.musleh@gmail.com exec_template_base = load_or_store) 2529268Smalek.musleh@gmail.com 2539268Smalek.musleh@gmail.com # Finally, add to the other outputs 2549222Shestness@cs.wisc.edu header_output += header_output_ra0 2559222Shestness@cs.wisc.edu decoder_output += decoder_output_ra0 2568887Sgeoffrey.blake@arm.com exec_output += exec_output_ra0 25710150Snilay@cs.wisc.edu return (header_output, decoder_output, decode_block, exec_output) 2589756Snilay@cs.wisc.edu 2598887Sgeoffrey.blake@arm.com}}; 2608887Sgeoffrey.blake@arm.com 2619836Sandreas.hansson@arm.com 2628887Sgeoffrey.blake@arm.comdef format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 2638801Sgblack@eecs.umich.edu ea_code_ra0 = {{ EA = Rb; }}, 2643481Shsul@eecs.umich.edu mem_flags = [], inst_flags = []) {{ 265 (header_output, decoder_output, decode_block, exec_output) = \ 266 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 267 'MemOp', 'Load', mem_flags, inst_flags) 268}}; 269 270 271def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 272 ea_code_ra0 = {{ EA = Rb; }}, 273 mem_flags = [], inst_flags = []) {{ 274 (header_output, decoder_output, decode_block, exec_output) = \ 275 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 276 'MemOp', 'Store', mem_flags, inst_flags) 277}}; 278 279 280def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 281 mem_flags = [], inst_flags = []) {{ 282 283 # Add in the update code 284 memacc_code += 'Ra = EA;' 285 286 # Generate the class 287 (header_output, decoder_output, decode_block, exec_output) = \ 288 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 289 base_class = 'MemOp', 290 exec_template_base = 'Load') 291}}; 292 293 294def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 295 mem_flags = [], inst_flags = []) {{ 296 297 # Add in the update code 298 memacc_code += 'Ra = EA;' 299 300 # Generate the class 301 (header_output, decoder_output, decode_block, exec_output) = \ 302 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 303 base_class = 'MemOp', 304 exec_template_base = 'Store') 305}}; 306 307 308def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 309 ea_code_ra0 = {{ EA = disp; }}, 310 mem_flags = [], inst_flags = []) {{ 311 (header_output, decoder_output, decode_block, exec_output) = \ 312 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 313 'MemDispOp', 'Load', mem_flags, inst_flags) 314}}; 315 316 317def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 318 ea_code_ra0 = {{ EA = disp; }}, 319 mem_flags = [], inst_flags = []) {{ 320 (header_output, decoder_output, decode_block, exec_output) = \ 321 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 322 'MemDispOp', 'Store', mem_flags, inst_flags) 323}}; 324 325 326def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 327 mem_flags = [], inst_flags = []) {{ 328 329 # Add in the update code 330 memacc_code += 'Ra = EA;' 331 332 # Generate the class 333 (header_output, decoder_output, decode_block, exec_output) = \ 334 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 335 base_class = 'MemDispOp', 336 exec_template_base = 'Load') 337}}; 338 339 340def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 341 mem_flags = [], inst_flags = []) {{ 342 343 # Add in the update code 344 memacc_code += 'Ra = EA;' 345 346 # Generate the class 347 (header_output, decoder_output, decode_block, exec_output) = \ 348 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 349 base_class = 'MemDispOp', 350 exec_template_base = 'Store') 351}}; 352