mem.isa revision 11303
1// -*- mode:c++ -*- 2 3// Copyright (c) 2009 The University of Edinburgh 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Timothy M. Jones 30 31//////////////////////////////////////////////////////////////////// 32// 33// Memory-format instructions 34// 35 36def template LoadStoreDeclare {{ 37 /** 38 * Static instruction class for "%(mnemonic)s". 39 */ 40 class %(class_name)s : public %(base_class)s 41 { 42 public: 43 44 /// Constructor. 45 %(class_name)s(ExtMachInst machInst); 46 47 %(BasicExecDeclare)s 48 49 %(InitiateAccDeclare)s 50 51 %(CompleteAccDeclare)s 52 }; 53}}; 54 55 56def template InitiateAccDeclare {{ 57 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 58}}; 59 60 61def template CompleteAccDeclare {{ 62 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; 63}}; 64 65 66def template LoadStoreConstructor {{ 67 %(class_name)s::%(class_name)s(ExtMachInst machInst) 68 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 69 { 70 %(constructor)s; 71 } 72}}; 73 74 75def template LoadExecute {{ 76 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 77 Trace::InstRecord *traceData) const 78 { 79 Addr EA; 80 Fault fault = NoFault; 81 82 %(op_decl)s; 83 %(op_rd)s; 84 %(ea_code)s; 85 86 if (fault == NoFault) { 87 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 88 %(memacc_code)s; 89 } 90 91 if (fault == NoFault) { 92 %(op_wb)s; 93 } 94 95 return fault; 96 } 97}}; 98 99 100def template LoadInitiateAcc {{ 101 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT *xc, 102 Trace::InstRecord *traceData) const 103 { 104 Addr EA; 105 Fault fault = NoFault; 106 107 %(op_src_decl)s; 108 %(op_rd)s; 109 %(ea_code)s; 110 111 if (fault == NoFault) { 112 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 113 xc->setEA(EA); 114 } 115 116 return fault; 117 } 118}}; 119 120 121def template LoadCompleteAcc {{ 122 Fault %(class_name)s::completeAcc(PacketPtr pkt, 123 CPU_EXEC_CONTEXT *xc, 124 Trace::InstRecord *traceData) const 125 { 126 Addr M5_VAR_USED EA; 127 Fault fault = NoFault; 128 129 %(op_decl)s; 130 %(op_rd)s; 131 132 EA = xc->getEA(); 133 134 getMem(pkt, Mem, traceData); 135 136 if (fault == NoFault) { 137 %(memacc_code)s; 138 } 139 140 if (fault == NoFault) { 141 %(op_wb)s; 142 } 143 144 return fault; 145 } 146}}; 147 148 149def template StoreExecute {{ 150 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 151 Trace::InstRecord *traceData) const 152 { 153 Addr EA; 154 Fault fault = NoFault; 155 156 %(op_decl)s; 157 %(op_rd)s; 158 %(ea_code)s; 159 160 if (fault == NoFault) { 161 %(memacc_code)s; 162 } 163 164 if (fault == NoFault) { 165 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 166 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(CPU_EXEC_CONTEXT *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, 210 CPU_EXEC_CONTEXT *xc, 211 Trace::InstRecord *traceData) const 212 { 213 return NoFault; 214 } 215}}; 216 217 218// The generic memory operation generator. This is called when two versions 219// of an instruction are needed - when Ra == 0 and otherwise. This is so 220// that instructions can use the value 0 when Ra == 0 but avoid having a 221// dependence on Ra. 222let {{ 223 224def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 225 load_or_store, mem_flags = [], inst_flags = []): 226 227 # First the version where Ra is non-zero 228 (header_output, decoder_output, decode_block, exec_output) = \ 229 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 230 base_class = base, 231 decode_template = CheckRaDecode, 232 exec_template_base = load_or_store) 233 234 # Now another version where Ra == 0 235 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 236 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 237 mem_flags, inst_flags, 238 base_class = base, 239 exec_template_base = load_or_store) 240 241 # Finally, add to the other outputs 242 header_output += header_output_ra0 243 decoder_output += decoder_output_ra0 244 exec_output += exec_output_ra0 245 return (header_output, decoder_output, decode_block, exec_output) 246 247}}; 248 249 250def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 251 ea_code_ra0 = {{ EA = Rb; }}, 252 mem_flags = [], inst_flags = []) {{ 253 (header_output, decoder_output, decode_block, exec_output) = \ 254 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 255 'MemOp', 'Load', mem_flags, inst_flags) 256}}; 257 258 259def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 260 ea_code_ra0 = {{ EA = Rb; }}, 261 mem_flags = [], inst_flags = []) {{ 262 (header_output, decoder_output, decode_block, exec_output) = \ 263 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 264 'MemOp', 'Store', mem_flags, inst_flags) 265}}; 266 267 268def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 269 mem_flags = [], inst_flags = []) {{ 270 271 # Add in the update code 272 memacc_code += 'Ra = EA;' 273 274 # Generate the class 275 (header_output, decoder_output, decode_block, exec_output) = \ 276 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 277 base_class = 'MemOp', 278 exec_template_base = 'Load') 279}}; 280 281 282def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 283 mem_flags = [], inst_flags = []) {{ 284 285 # Add in the update code 286 memacc_code += 'Ra = EA;' 287 288 # Generate the class 289 (header_output, decoder_output, decode_block, exec_output) = \ 290 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 291 base_class = 'MemOp', 292 exec_template_base = 'Store') 293}}; 294 295 296def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 297 ea_code_ra0 = {{ EA = disp; }}, 298 mem_flags = [], inst_flags = []) {{ 299 (header_output, decoder_output, decode_block, exec_output) = \ 300 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 301 'MemDispOp', 'Load', mem_flags, inst_flags) 302}}; 303 304 305def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 306 ea_code_ra0 = {{ EA = disp; }}, 307 mem_flags = [], inst_flags = []) {{ 308 (header_output, decoder_output, decode_block, exec_output) = \ 309 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 310 'MemDispOp', 'Store', mem_flags, inst_flags) 311}}; 312 313 314def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 315 mem_flags = [], inst_flags = []) {{ 316 317 # Add in the update code 318 memacc_code += 'Ra = EA;' 319 320 # Generate the class 321 (header_output, decoder_output, decode_block, exec_output) = \ 322 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 323 base_class = 'MemDispOp', 324 exec_template_base = 'Load') 325}}; 326 327 328def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 329 mem_flags = [], inst_flags = []) {{ 330 331 # Add in the update code 332 memacc_code += 'Ra = EA;' 333 334 # Generate the class 335 (header_output, decoder_output, decode_block, exec_output) = \ 336 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 337 base_class = 'MemDispOp', 338 exec_template_base = 'Store') 339}}; 340