mem.isa revision 12420
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 Fault execute(ExecContext *, Trace::InstRecord *) const; 48 Fault initiateAcc(ExecContext *, Trace::InstRecord *) const; 49 Fault completeAcc(PacketPtr, ExecContext *, Trace::InstRecord *) const; 50 }; 51}}; 52 53 54def template LoadStoreConstructor {{ 55 %(class_name)s::%(class_name)s(ExtMachInst machInst) 56 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) 57 { 58 %(constructor)s; 59 } 60}}; 61 62 63def template LoadExecute {{ 64 Fault %(class_name)s::execute(ExecContext *xc, 65 Trace::InstRecord *traceData) const 66 { 67 Addr EA; 68 Fault fault = NoFault; 69 70 %(op_decl)s; 71 %(op_rd)s; 72 %(ea_code)s; 73 74 if (fault == NoFault) { 75 fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags); 76 %(memacc_code)s; 77 } 78 79 if (fault == NoFault) { 80 %(op_wb)s; 81 } 82 83 return fault; 84 } 85}}; 86 87 88def template LoadInitiateAcc {{ 89 Fault %(class_name)s::initiateAcc(ExecContext *xc, 90 Trace::InstRecord *traceData) const 91 { 92 Addr EA; 93 Fault fault = NoFault; 94 95 %(op_src_decl)s; 96 %(op_rd)s; 97 %(ea_code)s; 98 99 if (fault == NoFault) { 100 fault = initiateMemRead(xc, traceData, EA, Mem, memAccessFlags); 101 } 102 103 return fault; 104 } 105}}; 106 107 108def template LoadCompleteAcc {{ 109 Fault %(class_name)s::completeAcc(PacketPtr pkt, 110 ExecContext *xc, 111 Trace::InstRecord *traceData) const 112 { 113 Addr M5_VAR_USED EA; 114 Fault fault = NoFault; 115 116 %(op_decl)s; 117 %(op_rd)s; 118 119 EA = pkt->req->getVaddr(); 120 121 getMem(pkt, Mem, traceData); 122 123 if (fault == NoFault) { 124 %(memacc_code)s; 125 } 126 127 if (fault == NoFault) { 128 %(op_wb)s; 129 } 130 131 return fault; 132 } 133}}; 134 135 136def template StoreExecute {{ 137 Fault %(class_name)s::execute(ExecContext *xc, 138 Trace::InstRecord *traceData) const 139 { 140 Addr EA; 141 Fault fault = NoFault; 142 143 %(op_decl)s; 144 %(op_rd)s; 145 %(ea_code)s; 146 147 if (fault == NoFault) { 148 %(memacc_code)s; 149 } 150 151 if (fault == NoFault) { 152 fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags, 153 NULL); 154 } 155 156 if (fault == NoFault) { 157 %(op_wb)s; 158 } 159 160 return fault; 161 } 162}}; 163 164 165def template StoreInitiateAcc {{ 166 Fault %(class_name)s::initiateAcc(ExecContext *xc, 167 Trace::InstRecord *traceData) const 168 { 169 Addr EA; 170 Fault fault = NoFault; 171 172 %(op_decl)s; 173 %(op_rd)s; 174 %(ea_code)s; 175 176 if (fault == NoFault) { 177 %(memacc_code)s; 178 } 179 180 if (fault == NoFault) { 181 fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags, 182 NULL); 183 } 184 185 // Need to write back any potential address register update 186 if (fault == NoFault) { 187 %(op_wb)s; 188 } 189 190 return fault; 191 } 192}}; 193 194 195def template StoreCompleteAcc {{ 196 Fault %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc, 197 Trace::InstRecord *traceData) const 198 { 199 return NoFault; 200 } 201}}; 202 203 204// The generic memory operation generator. This is called when two versions 205// of an instruction are needed - when Ra == 0 and otherwise. This is so 206// that instructions can use the value 0 when Ra == 0 but avoid having a 207// dependence on Ra. 208let {{ 209 210def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 211 load_or_store, mem_flags = [], inst_flags = []): 212 213 # First the version where Ra is non-zero 214 (header_output, decoder_output, decode_block, exec_output) = \ 215 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 216 base_class = base, 217 decode_template = CheckRaDecode, 218 exec_template_base = load_or_store) 219 220 # Now another version where Ra == 0 221 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 222 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 223 mem_flags, inst_flags, 224 base_class = base, 225 exec_template_base = load_or_store) 226 227 # Finally, add to the other outputs 228 header_output += header_output_ra0 229 decoder_output += decoder_output_ra0 230 exec_output += exec_output_ra0 231 return (header_output, decoder_output, decode_block, exec_output) 232 233}}; 234 235 236def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 237 ea_code_ra0 = {{ EA = Rb; }}, 238 mem_flags = [], inst_flags = []) {{ 239 (header_output, decoder_output, decode_block, exec_output) = \ 240 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 241 'MemOp', 'Load', mem_flags, inst_flags) 242}}; 243 244 245def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 246 ea_code_ra0 = {{ EA = Rb; }}, 247 mem_flags = [], inst_flags = []) {{ 248 (header_output, decoder_output, decode_block, exec_output) = \ 249 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 250 'MemOp', 'Store', mem_flags, inst_flags) 251}}; 252 253 254def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 255 mem_flags = [], inst_flags = []) {{ 256 257 # Add in the update code 258 memacc_code += 'Ra = EA;' 259 260 # Generate the class 261 (header_output, decoder_output, decode_block, exec_output) = \ 262 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 263 base_class = 'MemOp', 264 exec_template_base = 'Load') 265}}; 266 267 268def format StoreIndexUpdateOp(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 = 'Store') 279}}; 280 281 282def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 283 ea_code_ra0 = {{ EA = disp; }}, 284 mem_flags = [], inst_flags = []) {{ 285 (header_output, decoder_output, decode_block, exec_output) = \ 286 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 287 'MemDispOp', 'Load', mem_flags, inst_flags) 288}}; 289 290 291def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 292 ea_code_ra0 = {{ EA = disp; }}, 293 mem_flags = [], inst_flags = []) {{ 294 (header_output, decoder_output, decode_block, exec_output) = \ 295 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 296 'MemDispOp', 'Store', mem_flags, inst_flags) 297}}; 298 299 300def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 301 mem_flags = [], inst_flags = []) {{ 302 303 # Add in the update code 304 memacc_code += 'Ra = EA;' 305 306 # Generate the class 307 (header_output, decoder_output, decode_block, exec_output) = \ 308 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 309 base_class = 'MemDispOp', 310 exec_template_base = 'Load') 311}}; 312 313 314def format StoreDispUpdateOp(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 = 'Store') 325}}; 326