mem.isa revision 7712:7733c562e5e3
12SN/A// -*- mode:c++ -*- 21762SN/A 32SN/A// Copyright (c) 2009 The University of Edinburgh 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 272665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 282665Ssaidi@eecs.umich.edu// 292SN/A// Authors: Timothy M. Jones 302SN/A 316216Snate@binkert.org//////////////////////////////////////////////////////////////////// 326216Snate@binkert.org// 332SN/A// Memory-format instructions 346216Snate@binkert.org// 35100SN/A 366214Snate@binkert.orgdef template LoadStoreDeclare {{ 37100SN/A /** 382SN/A * Static instruction class for "%(mnemonic)s". 392020SN/A */ 402SN/A class %(class_name)s : public %(base_class)s 412SN/A { 4250SN/A public: 432SN/A 442020SN/A /// Constructor. 452SN/A %(class_name)s(ExtMachInst machInst); 4650SN/A 472SN/A %(BasicExecDeclare)s 4850SN/A 4950SN/A %(InitiateAccDeclare)s 5050SN/A 5150SN/A %(CompleteAccDeclare)s 5250SN/A }; 5350SN/A}}; 5450SN/A 5550SN/A 5650SN/Adef template InitiateAccDeclare {{ 5750SN/A Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 5850SN/A}}; 5950SN/A 602SN/A 612SN/Adef template CompleteAccDeclare {{ 622SN/A Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 6350SN/A}}; 6450SN/A 652020SN/A 662SN/Adef template LoadStoreConstructor {{ 6750SN/A inline %(class_name)s::%(class_name)s(ExtMachInst machInst) 682SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 692SN/A { 7050SN/A %(constructor)s; 7150SN/A } 722020SN/A}}; 7350SN/A 742020SN/A 7550SN/Adef template LoadExecute {{ 7650SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 772SN/A Trace::InstRecord *traceData) const 782020SN/A { 7950SN/A Addr EA; 80100SN/A Fault fault = NoFault; 812SN/A 8250SN/A %(op_decl)s; 832SN/A %(op_rd)s; 8450SN/A %(ea_code)s; 8550SN/A 8650SN/A if (fault == NoFault) { 8750SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 8850SN/A %(memacc_code)s; 8950SN/A } 9050SN/A 9150SN/A if (fault == NoFault) { 9250SN/A %(op_wb)s; 93100SN/A } 942020SN/A 951642SN/A return fault; 961642SN/A } 971642SN/A}}; 981642SN/A 991642SN/A 1001642SN/Adef template LoadInitiateAcc {{ 1011642SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 1021642SN/A Trace::InstRecord *traceData) const 1031642SN/A { 1041642SN/A Addr EA; 1051642SN/A Fault fault = NoFault; 1061642SN/A 1071642SN/A %(op_src_decl)s; 1081642SN/A %(op_rd)s; 1091642SN/A %(ea_code)s; 1101642SN/A 1111642SN/A if (fault == NoFault) { 1121642SN/A fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 1132020SN/A xc->setEA(EA); 114100SN/A } 115100SN/A 116100SN/A return fault; 117100SN/A } 118100SN/A}}; 119100SN/A 120100SN/A 121100SN/Adef template LoadCompleteAcc {{ 122100SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 123100SN/A %(CPU_exec_context)s *xc, 124100SN/A Trace::InstRecord *traceData) const 125100SN/A { 126100SN/A Addr EA; 127100SN/A Fault fault = NoFault; 128100SN/A uint%(mem_acc_size)d_t val; 129100SN/A 1302020SN/A %(op_decl)s; 131100SN/A %(op_rd)s; 132100SN/A 1332020SN/A EA = xc->getEA(); 134100SN/A 135100SN/A val = pkt->get<uint%(mem_acc_size)d_t>(); 136100SN/A *((uint%(mem_acc_size)d_t*)&Mem) = val; 1372020SN/A 138100SN/A if (fault == NoFault) { 139100SN/A %(memacc_code)s; 1402020SN/A } 1411642SN/A 1421642SN/A if (fault == NoFault) { 1431642SN/A %(op_wb)s; 1442020SN/A } 1451642SN/A 1461642SN/A return fault; 1472020SN/A } 148100SN/A}}; 149100SN/A 15050SN/A 15150SN/Adef template StoreExecute {{ 1522020SN/A Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 15350SN/A Trace::InstRecord *traceData) const 154100SN/A { 155100SN/A Addr EA; 156100SN/A Fault fault = NoFault; 1572020SN/A 15850SN/A %(op_decl)s; 15950SN/A %(op_rd)s; 16050SN/A %(ea_code)s; 16150SN/A 1622020SN/A if (fault == NoFault) { 16350SN/A %(memacc_code)s; 1642020SN/A } 16550SN/A 16650SN/A if (fault == NoFault) { 16750SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 16850SN/A memAccessFlags, NULL); 1692020SN/A } 17050SN/A 1712020SN/A if (fault == NoFault) { 17250SN/A %(op_wb)s; 1732SN/A } 17452SN/A 17552SN/A return fault; 1762020SN/A } 17752SN/A}}; 17852SN/A 17952SN/A 18052SN/Adef template StoreInitiateAcc {{ 18152SN/A Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 18252SN/A Trace::InstRecord *traceData) const 1832021SN/A { 18452SN/A Addr EA; 1852021SN/A Fault fault = NoFault; 18652SN/A 18752SN/A %(op_decl)s; 18852SN/A %(op_rd)s; 18952SN/A %(ea_code)s; 19052SN/A 1912418SN/A if (fault == NoFault) { 19252SN/A %(memacc_code)s; 1932418SN/A } 19452SN/A 19552SN/A if (fault == NoFault) { 19652SN/A fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 1972SN/A memAccessFlags, NULL); 1982020SN/A } 19950SN/A 2005570Snate@binkert.org // Need to write back any potential address register update 2015570Snate@binkert.org if (fault == NoFault) { 2025570Snate@binkert.org %(op_wb)s; 2032SN/A } 2042SN/A 2052SN/A return fault; 2062020SN/A } 20750SN/A}}; 20850SN/A 20950SN/A 2102SN/Adef template StoreCompleteAcc {{ 2112SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 2122020SN/A %(CPU_exec_context)s *xc, 21350SN/A Trace::InstRecord *traceData) const 21450SN/A { 21550SN/A return NoFault; 2162SN/A } 2172SN/A}}; 2182020SN/A 2192SN/A 2202SN/A// The generic memory operation generator. This is called when two versions 2212SN/A// of an instruction are needed - when Ra == 0 and otherwise. This is so 2222SN/A// that instructions can use the value 0 when Ra == 0 but avoid having a 223105SN/A// dependence on Ra. 2242SN/Alet {{ 2252SN/A 2262SN/Adef GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 2272SN/A load_or_store, mem_flags = [], inst_flags = []): 2282SN/A 2292SN/A # First the version where Ra is non-zero 2302SN/A (header_output, decoder_output, decode_block, exec_output) = \ 2312SN/A LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 2326216Snate@binkert.org base_class = base, 233 decode_template = CheckRaDecode, 234 exec_template_base = load_or_store) 235 236 # Now another version where Ra == 0 237 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 238 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 239 mem_flags, inst_flags, 240 base_class = base, 241 exec_template_base = load_or_store) 242 243 # Finally, add to the other outputs 244 header_output += header_output_ra0 245 decoder_output += decoder_output_ra0 246 exec_output += exec_output_ra0 247 return (header_output, decoder_output, decode_block, exec_output) 248 249}}; 250 251 252def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 253 ea_code_ra0 = {{ EA = Rb; }}, 254 mem_flags = [], inst_flags = []) {{ 255 (header_output, decoder_output, decode_block, exec_output) = \ 256 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 257 'MemOp', 'Load', mem_flags, inst_flags) 258}}; 259 260 261def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 262 ea_code_ra0 = {{ EA = Rb; }}, 263 mem_flags = [], inst_flags = []) {{ 264 (header_output, decoder_output, decode_block, exec_output) = \ 265 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 266 'MemOp', 'Store', mem_flags, inst_flags) 267}}; 268 269 270def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 271 mem_flags = [], inst_flags = []) {{ 272 273 # Add in the update code 274 memacc_code += 'Ra = EA;' 275 276 # Generate the class 277 (header_output, decoder_output, decode_block, exec_output) = \ 278 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 279 base_class = 'MemOp', 280 exec_template_base = 'Load') 281}}; 282 283 284def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 285 mem_flags = [], inst_flags = []) {{ 286 287 # Add in the update code 288 memacc_code += 'Ra = EA;' 289 290 # Generate the class 291 (header_output, decoder_output, decode_block, exec_output) = \ 292 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 293 base_class = 'MemOp', 294 exec_template_base = 'Store') 295}}; 296 297 298def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 299 ea_code_ra0 = {{ EA = disp; }}, 300 mem_flags = [], inst_flags = []) {{ 301 (header_output, decoder_output, decode_block, exec_output) = \ 302 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 303 'MemDispOp', 'Load', mem_flags, inst_flags) 304}}; 305 306 307def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 308 ea_code_ra0 = {{ EA = disp; }}, 309 mem_flags = [], inst_flags = []) {{ 310 (header_output, decoder_output, decode_block, exec_output) = \ 311 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 312 'MemDispOp', 'Store', mem_flags, inst_flags) 313}}; 314 315 316def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 317 mem_flags = [], inst_flags = []) {{ 318 319 # Add in the update code 320 memacc_code += 'Ra = EA;' 321 322 # Generate the class 323 (header_output, decoder_output, decode_block, exec_output) = \ 324 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 325 base_class = 'MemDispOp', 326 exec_template_base = 'Load') 327}}; 328 329 330def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 331 mem_flags = [], inst_flags = []) {{ 332 333 # Add in the update code 334 memacc_code += 'Ra = EA;' 335 336 # Generate the class 337 (header_output, decoder_output, decode_block, exec_output) = \ 338 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 339 base_class = 'MemDispOp', 340 exec_template_base = 'Store') 341}}; 342