mem.isa (6691:cd68b6ecd68d) | mem.isa (7045:e21fe6a62b1c) |
---|---|
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 inline %(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)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t&)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)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t &)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)s *xc, 124 Trace::InstRecord *traceData) const 125 { 126 Addr EA; 127 Fault fault = NoFault; 128 uint%(mem_acc_size)d_t val; 129 130 %(op_decl)s; 131 %(op_rd)s; 132 133 EA = xc->getEA(); 134 135 val = pkt->get<uint%(mem_acc_size)d_t>(); 136 *((uint%(mem_acc_size)d_t*)&Mem) = val; 137 138 if (fault == NoFault) { 139 %(memacc_code)s; 140 } 141 142 if (fault == NoFault) { 143 %(op_wb)s; 144 } 145 146 return fault; 147 } 148}}; 149 150 151def template StoreExecute {{ 152 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 153 Trace::InstRecord *traceData) const 154 { 155 Addr EA; 156 Fault fault = NoFault; 157 158 %(op_decl)s; 159 %(op_rd)s; 160 %(ea_code)s; 161 162 if (fault == NoFault) { 163 %(memacc_code)s; 164 } 165 166 if (fault == NoFault) { 167 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 168 memAccessFlags, NULL); | 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 inline %(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)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t&)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)s *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 = xc->read(EA, (uint%(mem_acc_size)d_t &)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)s *xc, 124 Trace::InstRecord *traceData) const 125 { 126 Addr EA; 127 Fault fault = NoFault; 128 uint%(mem_acc_size)d_t val; 129 130 %(op_decl)s; 131 %(op_rd)s; 132 133 EA = xc->getEA(); 134 135 val = pkt->get<uint%(mem_acc_size)d_t>(); 136 *((uint%(mem_acc_size)d_t*)&Mem) = val; 137 138 if (fault == NoFault) { 139 %(memacc_code)s; 140 } 141 142 if (fault == NoFault) { 143 %(op_wb)s; 144 } 145 146 return fault; 147 } 148}}; 149 150 151def template StoreExecute {{ 152 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 153 Trace::InstRecord *traceData) const 154 { 155 Addr EA; 156 Fault fault = NoFault; 157 158 %(op_decl)s; 159 %(op_rd)s; 160 %(ea_code)s; 161 162 if (fault == NoFault) { 163 %(memacc_code)s; 164 } 165 166 if (fault == NoFault) { 167 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 168 memAccessFlags, NULL); |
169 if (traceData) { traceData->setData(Mem); } | |
170 } 171 172 if (fault == NoFault) { 173 %(op_wb)s; 174 } 175 176 return fault; 177 } 178}}; 179 180 181def template StoreInitiateAcc {{ 182 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 183 Trace::InstRecord *traceData) const 184 { 185 Addr EA; 186 Fault fault = NoFault; 187 188 %(op_decl)s; 189 %(op_rd)s; 190 %(ea_code)s; 191 192 if (fault == NoFault) { 193 %(memacc_code)s; 194 } 195 196 if (fault == NoFault) { 197 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 198 memAccessFlags, NULL); | 169 } 170 171 if (fault == NoFault) { 172 %(op_wb)s; 173 } 174 175 return fault; 176 } 177}}; 178 179 180def template StoreInitiateAcc {{ 181 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 182 Trace::InstRecord *traceData) const 183 { 184 Addr EA; 185 Fault fault = NoFault; 186 187 %(op_decl)s; 188 %(op_rd)s; 189 %(ea_code)s; 190 191 if (fault == NoFault) { 192 %(memacc_code)s; 193 } 194 195 if (fault == NoFault) { 196 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 197 memAccessFlags, NULL); |
199 if (traceData) { traceData->setData(Mem); } | |
200 } 201 202 // Need to write back any potential address register update 203 if (fault == NoFault) { 204 %(op_wb)s; 205 } 206 207 return fault; 208 } 209}}; 210 211 212def template StoreCompleteAcc {{ 213 Fault %(class_name)s::completeAcc(PacketPtr pkt, 214 %(CPU_exec_context)s *xc, 215 Trace::InstRecord *traceData) const 216 { 217 Fault fault = NoFault; 218 219 %(op_dest_decl)s; 220 221 if (fault == NoFault) { 222 %(op_wb)s; 223 } 224 225 return fault; 226 } 227}}; 228 229 230// The generic memory operation generator. This is called when two versions 231// of an instruction are needed - when Ra == 0 and otherwise. This is so 232// that instructions can use the value 0 when Ra == 0 but avoid having a 233// dependence on Ra. 234let {{ 235 236def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 237 load_or_store, mem_flags = [], inst_flags = []): 238 239 # First the version where Ra is non-zero 240 (header_output, decoder_output, decode_block, exec_output) = \ 241 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 242 base_class = base, 243 decode_template = CheckRaDecode, 244 exec_template_base = load_or_store) 245 246 # Now another version where Ra == 0 247 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 248 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 249 mem_flags, inst_flags, 250 base_class = base, 251 exec_template_base = load_or_store) 252 253 # Finally, add to the other outputs 254 header_output += header_output_ra0 255 decoder_output += decoder_output_ra0 256 exec_output += exec_output_ra0 257 return (header_output, decoder_output, decode_block, exec_output) 258 259}}; 260 261 262def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 263 ea_code_ra0 = {{ EA = Rb; }}, 264 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}}; | 198 } 199 200 // Need to write back any potential address register update 201 if (fault == NoFault) { 202 %(op_wb)s; 203 } 204 205 return fault; 206 } 207}}; 208 209 210def template StoreCompleteAcc {{ 211 Fault %(class_name)s::completeAcc(PacketPtr pkt, 212 %(CPU_exec_context)s *xc, 213 Trace::InstRecord *traceData) const 214 { 215 Fault fault = NoFault; 216 217 %(op_dest_decl)s; 218 219 if (fault == NoFault) { 220 %(op_wb)s; 221 } 222 223 return fault; 224 } 225}}; 226 227 228// The generic memory operation generator. This is called when two versions 229// of an instruction are needed - when Ra == 0 and otherwise. This is so 230// that instructions can use the value 0 when Ra == 0 but avoid having a 231// dependence on Ra. 232let {{ 233 234def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, 235 load_or_store, mem_flags = [], inst_flags = []): 236 237 # First the version where Ra is non-zero 238 (header_output, decoder_output, decode_block, exec_output) = \ 239 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 240 base_class = base, 241 decode_template = CheckRaDecode, 242 exec_template_base = load_or_store) 243 244 # Now another version where Ra == 0 245 (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ 246 LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, 247 mem_flags, inst_flags, 248 base_class = base, 249 exec_template_base = load_or_store) 250 251 # Finally, add to the other outputs 252 header_output += header_output_ra0 253 decoder_output += decoder_output_ra0 254 exec_output += exec_output_ra0 255 return (header_output, decoder_output, decode_block, exec_output) 256 257}}; 258 259 260def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 261 ea_code_ra0 = {{ EA = Rb; }}, 262 mem_flags = [], inst_flags = []) {{ 263 (header_output, decoder_output, decode_block, exec_output) = \ 264 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 265 'MemOp', 'Load', mem_flags, inst_flags) 266}}; 267 268 269def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 270 ea_code_ra0 = {{ EA = Rb; }}, 271 mem_flags = [], inst_flags = []) {{ 272 (header_output, decoder_output, decode_block, exec_output) = \ 273 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 274 'MemOp', 'Store', mem_flags, inst_flags) 275}}; 276 277 278def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 279 mem_flags = [], inst_flags = []) {{ 280 281 # Add in the update code 282 memacc_code += 'Ra = EA;' 283 284 # Generate the class 285 (header_output, decoder_output, decode_block, exec_output) = \ 286 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 287 base_class = 'MemOp', 288 exec_template_base = 'Load') 289}}; 290 291 292def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, 293 mem_flags = [], inst_flags = []) {{ 294 295 # Add in the update code 296 memacc_code += 'Ra = EA;' 297 298 # Generate the class 299 (header_output, decoder_output, decode_block, exec_output) = \ 300 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 301 base_class = 'MemOp', 302 exec_template_base = 'Store') 303}}; 304 305 306def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 307 ea_code_ra0 = {{ EA = disp; }}, 308 mem_flags = [], inst_flags = []) {{ 309 (header_output, decoder_output, decode_block, exec_output) = \ 310 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 311 'MemDispOp', 'Load', mem_flags, inst_flags) 312}}; 313 314 315def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 316 ea_code_ra0 = {{ EA = disp; }}, 317 mem_flags = [], inst_flags = []) {{ 318 (header_output, decoder_output, decode_block, exec_output) = \ 319 GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, 320 'MemDispOp', 'Store', mem_flags, inst_flags) 321}}; 322 323 324def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 325 mem_flags = [], inst_flags = []) {{ 326 327 # Add in the update code 328 memacc_code += 'Ra = EA;' 329 330 # Generate the class 331 (header_output, decoder_output, decode_block, exec_output) = \ 332 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 333 base_class = 'MemDispOp', 334 exec_template_base = 'Load') 335}}; 336 337 338def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, 339 mem_flags = [], inst_flags = []) {{ 340 341 # Add in the update code 342 memacc_code += 'Ra = EA;' 343 344 # Generate the class 345 (header_output, decoder_output, decode_block, exec_output) = \ 346 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 347 base_class = 'MemDispOp', 348 exec_template_base = 'Store') 349}}; |