mem.isa revision 12234
12SN/A// -*- mode:c++ -*- 211071SN/A 311071SN/A// Copyright (c) 2009 The University of Edinburgh 411071SN/A// All rights reserved. 511071SN/A// 611071SN/A// Redistribution and use in source and binary forms, with or without 711071SN/A// modification, are permitted provided that the following conditions are 811071SN/A// met: redistributions of source code must retain the above copyright 911071SN/A// notice, this list of conditions and the following disclaimer; 1011071SN/A// redistributions in binary form must reproduce the above copyright 1111071SN/A// notice, this list of conditions and the following disclaimer in the 1211071SN/A// documentation and/or other materials provided with the distribution; 1311071SN/A// neither the name of the copyright holders nor the names of its 141762SN/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. 282SN/A// 292SN/A// Authors: Timothy M. Jones 302SN/A 312SN/A//////////////////////////////////////////////////////////////////// 322SN/A// 332SN/A// Memory-format instructions 342SN/A// 352SN/A 362SN/Adef template LoadStoreDeclare {{ 372SN/A /** 382SN/A * Static instruction class for "%(mnemonic)s". 392665SN/A */ 402665SN/A class %(class_name)s : public %(base_class)s 412SN/A { 422SN/A public: 432SN/A 442SN/A /// Constructor. 452SN/A %(class_name)s(ExtMachInst machInst); 462SN/A 4711263Sandreas.sandberg@arm.com %(BasicExecDeclare)s 4811263Sandreas.sandberg@arm.com 492SN/A %(InitiateAccDeclare)s 5011071SN/A 5111071SN/A %(CompleteAccDeclare)s 526216SN/A }; 5311263Sandreas.sandberg@arm.com}}; 5411263Sandreas.sandberg@arm.com 5511263Sandreas.sandberg@arm.com 564981SN/Adef template InitiateAccDeclare {{ 571354SN/A Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 5856SN/A}}; 592SN/A 602SN/A 611435SN/Adef template CompleteAccDeclare {{ 622SN/A Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 632SN/A}}; 642SN/A 654981SN/A 662SN/Adef template LoadStoreConstructor {{ 672SN/A %(class_name)s::%(class_name)s(ExtMachInst machInst) 682SN/A : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 692SN/A { 7011071SN/A %(constructor)s; 7111071SN/A } 7211071SN/A}}; 731435SN/A 741435SN/A 752SN/Adef template LoadExecute {{ 7611071SN/A Fault %(class_name)s::execute(ExecContext *xc, 77265SN/A Trace::InstRecord *traceData) const 7811071SN/A { 7911071SN/A Addr EA; 801435SN/A Fault fault = NoFault; 812SN/A 822SN/A %(op_decl)s; 832SN/A %(op_rd)s; 8411071SN/A %(ea_code)s; 8511071SN/A 8611071SN/A if (fault == NoFault) { 8711071SN/A fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 882SN/A %(memacc_code)s; 892SN/A } 902SN/A 912SN/A if (fault == NoFault) { 922SN/A %(op_wb)s; 932566SN/A } 94633SN/A 95633SN/A return fault; 961354SN/A } 97633SN/A}}; 982SN/A 9911071SN/A 10011071SN/Adef template LoadInitiateAcc {{ 10111071SN/A Fault %(class_name)s::initiateAcc(ExecContext *xc, 10211071SN/A Trace::InstRecord *traceData) const 10311071SN/A { 10411071SN/A Addr EA; 10511071SN/A Fault fault = NoFault; 10611071SN/A 10711071SN/A %(op_src_decl)s; 10811071SN/A %(op_rd)s; 10911071SN/A %(ea_code)s; 11011071SN/A 1112566SN/A if (fault == NoFault) { 1122SN/A fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 1132SN/A xc->setEA(EA); 1141435SN/A } 1151954SN/A 1162SN/A return fault; 1172SN/A } 1181435SN/A}}; 119265SN/A 1202SN/A 1212566SN/Adef template LoadCompleteAcc {{ 1222SN/A Fault %(class_name)s::completeAcc(PacketPtr pkt, 1232SN/A ExecContext *xc, 1242SN/A Trace::InstRecord *traceData) const 125558SN/A { 12610905SN/A Addr M5_VAR_USED EA; 12710905SN/A Fault fault = NoFault; 1282SN/A 1292SN/A %(op_decl)s; 1302SN/A %(op_rd)s; 1312SN/A 1322SN/A EA = xc->getEA(); 1332SN/A 1342SN/A getMem(pkt, Mem, traceData); 1352SN/A 1362SN/A if (fault == NoFault) { 1372SN/A %(memacc_code)s; 1382SN/A } 1392SN/A 1402566SN/A if (fault == NoFault) { 1411017SN/A %(op_wb)s; 1424419SN/A } 1432SN/A 1442SN/A return fault; 1451435SN/A } 1464981SN/A}}; 1472SN/A 1482SN/A 1494981SN/Adef template StoreExecute {{ 1504981SN/A Fault %(class_name)s::execute(ExecContext *xc, 1512SN/A Trace::InstRecord *traceData) const 152558SN/A { 1534981SN/A Addr EA; 1544981SN/A Fault fault = NoFault; 1554981SN/A 1564981SN/A %(op_decl)s; 1574981SN/A %(op_rd)s; 1584981SN/A %(ea_code)s; 15911169SN/A 1604981SN/A if (fault == NoFault) { 16111168SN/A %(memacc_code)s; 16211168SN/A } 163558SN/A 1642SN/A if (fault == NoFault) { 1652SN/A fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 16611263Sandreas.sandberg@arm.com NULL); 167 } 168 169 if (fault == NoFault) { 170 %(op_wb)s; 171 } 172 173 return fault; 174 } 175}}; 176 177 178def template StoreInitiateAcc {{ 179 Fault %(class_name)s::initiateAcc(ExecContext *xc, 180 Trace::InstRecord *traceData) const 181 { 182 Addr EA; 183 Fault fault = NoFault; 184 185 %(op_decl)s; 186 %(op_rd)s; 187 %(ea_code)s; 188 189 if (fault == NoFault) { 190 %(memacc_code)s; 191 } 192 193 if (fault == NoFault) { 194 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 195 NULL); 196 } 197 198 // Need to write back any potential address register update 199 if (fault == NoFault) { 200 %(op_wb)s; 201 } 202 203 return fault; 204 } 205}}; 206 207 208def template StoreCompleteAcc {{ 209 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 210 Trace::InstRecord *traceData) const 211 { 212 return NoFault; 213 } 214}}; 215 216 217// The generic memory operation generator. This is called when two versions 218// of an instruction are needed - when Ra == 0 and otherwise. This is so 219// that instructions can use the value 0 when Ra == 0 but avoid having a 220// dependence on Ra. 221let {{ 222 223def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 224 load_or_store, mem_flags = [], inst_flags = []): 225 226 # First the version where Ra is non-zero 227 (header_output, decoder_output, decode_block, exec_output) = \ 228 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 229 base_class = base, 230 decode_template = CheckRaDecode, 231 exec_template_base = load_or_store) 232 233 # Now another version where Ra == 0 234 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 235 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 236 mem_flags, inst_flags, 237 base_class = base, 238 exec_template_base = load_or_store) 239 240 # Finally, add to the other outputs 241 header_output += header_output_ra0 242 decoder_output += decoder_output_ra0 243 exec_output += exec_output_ra0 244 return (header_output, decoder_output, decode_block, exec_output) 245 246}}; 247 248 249def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 250 ea_code_ra0 = {{ EA = Rb; }}, 251 mem_flags = [], inst_flags = []) {{ 252 (header_output, decoder_output, decode_block, exec_output) = \ 253 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 254 'MemOp', 'Load', mem_flags, inst_flags) 255}}; 256 257 258def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 259 ea_code_ra0 = {{ EA = Rb; }}, 260 mem_flags = [], inst_flags = []) {{ 261 (header_output, decoder_output, decode_block, exec_output) = \ 262 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 263 'MemOp', 'Store', mem_flags, inst_flags) 264}}; 265 266 267def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 268 mem_flags = [], inst_flags = []) {{ 269 270 # Add in the update code 271 memacc_code += 'Ra = EA;' 272 273 # Generate the class 274 (header_output, decoder_output, decode_block, exec_output) = \ 275 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 276 base_class = 'MemOp', 277 exec_template_base = 'Load') 278}}; 279 280 281def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 282 mem_flags = [], inst_flags = []) {{ 283 284 # Add in the update code 285 memacc_code += 'Ra = EA;' 286 287 # Generate the class 288 (header_output, decoder_output, decode_block, exec_output) = \ 289 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 290 base_class = 'MemOp', 291 exec_template_base = 'Store') 292}}; 293 294 295def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 296 ea_code_ra0 = {{ EA = disp; }}, 297 mem_flags = [], inst_flags = []) {{ 298 (header_output, decoder_output, decode_block, exec_output) = \ 299 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 300 'MemDispOp', 'Load', mem_flags, inst_flags) 301}}; 302 303 304def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 305 ea_code_ra0 = {{ EA = disp; }}, 306 mem_flags = [], inst_flags = []) {{ 307 (header_output, decoder_output, decode_block, exec_output) = \ 308 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 309 'MemDispOp', 'Store', mem_flags, inst_flags) 310}}; 311 312 313def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 314 mem_flags = [], inst_flags = []) {{ 315 316 # Add in the update code 317 memacc_code += 'Ra = EA;' 318 319 # Generate the class 320 (header_output, decoder_output, decode_block, exec_output) = \ 321 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 322 base_class = 'MemDispOp', 323 exec_template_base = 'Load') 324}}; 325 326 327def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 328 mem_flags = [], inst_flags = []) {{ 329 330 # Add in the update code 331 memacc_code += 'Ra = EA;' 332 333 # Generate the class 334 (header_output, decoder_output, decode_block, exec_output) = \ 335 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 336 base_class = 'MemDispOp', 337 exec_template_base = 'Store') 338}}; 339