1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 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: Gabe Black 30// Korey Sewell 31 32//////////////////////////////////////////////////////////////////// 33// 34// Memory-format instructions: LoadAddress, Load, Store 35// 36 37output header {{ 38 /** 39 * Base class for general Mips memory-format instructions. 40 */ 41 class Memory : public MipsStaticInst 42 { 43 protected: 44 45 /// Memory request flags. See mem_req_base.hh. 46 unsigned memAccessFlags; 47 /// Pointer to EAComp object. 48 const StaticInstPtr eaCompPtr; 49 /// Pointer to MemAcc object. 50 const StaticInstPtr memAccPtr; 51 52 /// Displacement for EA calculation (signed). 53 int32_t disp; 54 55 /// Constructor 56 Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 57 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 58 StaticInstPtr _memAccPtr = nullStaticInstPtr) 59 : MipsStaticInst(mnem, _machInst, __opClass), 60 memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 61 disp(OFFSET) 62 { 63 //If Bit 15 is 1 then Sign Extend 64 int32_t temp = disp & 0x00008000; 65 66 if (temp > 0) { 67 disp |= 0xFFFF0000; 68 } 69 } 70 71 std::string 72 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 73 74 public: 75 76 const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 77 const StaticInstPtr &memAccInst() const { return memAccPtr; } 78 }; 79 80}}; 81 82 83output decoder {{ 84 std::string 85 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 86 { 87 return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 88 flags[IsFloating] ? 'f' : 'r', RT, disp, RS); 89 } 90 91}}; 92
| 1// -*- mode:c++ -*- 2 3// Copyright (c) 2003-2005 The Regents of The University of Michigan 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: Gabe Black 30// Korey Sewell 31 32//////////////////////////////////////////////////////////////////// 33// 34// Memory-format instructions: LoadAddress, Load, Store 35// 36 37output header {{ 38 /** 39 * Base class for general Mips memory-format instructions. 40 */ 41 class Memory : public MipsStaticInst 42 { 43 protected: 44 45 /// Memory request flags. See mem_req_base.hh. 46 unsigned memAccessFlags; 47 /// Pointer to EAComp object. 48 const StaticInstPtr eaCompPtr; 49 /// Pointer to MemAcc object. 50 const StaticInstPtr memAccPtr; 51 52 /// Displacement for EA calculation (signed). 53 int32_t disp; 54 55 /// Constructor 56 Memory(const char *mnem, MachInst _machInst, OpClass __opClass, 57 StaticInstPtr _eaCompPtr = nullStaticInstPtr, 58 StaticInstPtr _memAccPtr = nullStaticInstPtr) 59 : MipsStaticInst(mnem, _machInst, __opClass), 60 memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), 61 disp(OFFSET) 62 { 63 //If Bit 15 is 1 then Sign Extend 64 int32_t temp = disp & 0x00008000; 65 66 if (temp > 0) { 67 disp |= 0xFFFF0000; 68 } 69 } 70 71 std::string 72 generateDisassembly(Addr pc, const SymbolTable *symtab) const; 73 74 public: 75 76 const StaticInstPtr &eaCompInst() const { return eaCompPtr; } 77 const StaticInstPtr &memAccInst() const { return memAccPtr; } 78 }; 79 80}}; 81 82 83output decoder {{ 84 std::string 85 Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const 86 { 87 return csprintf("%-10s %c%d,%d(r%d)", mnemonic, 88 flags[IsFloating] ? 'f' : 'r', RT, disp, RS); 89 } 90 91}}; 92
|
93def format LoadAddress(code) {{ 94 iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) 95 header_output = BasicDeclare.subst(iop) 96 decoder_output = BasicConstructor.subst(iop) 97 decode_block = BasicDecode.subst(iop) 98 exec_output = BasicExecute.subst(iop) 99}}; 100 101
| |
102def template LoadStoreDeclare {{ 103 /** 104 * Static instruction class for "%(mnemonic)s". 105 */ 106 class %(class_name)s : public %(base_class)s 107 { 108 protected: 109 110 /** 111 * "Fake" effective address computation class for "%(mnemonic)s". 112 */ 113 class EAComp : public %(base_class)s 114 { 115 public: 116 /// Constructor 117 EAComp(MachInst machInst); 118 119 %(BasicExecDeclare)s 120 }; 121 122 /** 123 * "Fake" memory access instruction class for "%(mnemonic)s". 124 */ 125 class MemAcc : public %(base_class)s 126 { 127 public: 128 /// Constructor 129 MemAcc(MachInst machInst); 130 131 %(BasicExecDeclare)s 132 }; 133 134 public: 135 136 /// Constructor. 137 %(class_name)s(MachInst machInst); 138 139 %(BasicExecDeclare)s 140 141 %(InitiateAccDeclare)s 142 143 %(CompleteAccDeclare)s 144 }; 145}}; 146 147 148def template InitiateAccDeclare {{ 149 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 150}}; 151 152 153def template CompleteAccDeclare {{ 154 Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 155}}; 156 157 158def template LoadStoreConstructor {{ 159 /** TODO: change op_class to AddrGenOp or something (requires 160 * creating new member of OpClass enum in op_class.hh, updating 161 * config files, etc.). */ 162 inline %(class_name)s::EAComp::EAComp(MachInst machInst) 163 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 164 { 165 %(ea_constructor)s; 166 } 167 168 inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) 169 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 170 { 171 %(memacc_constructor)s; 172 } 173 174 inline %(class_name)s::%(class_name)s(MachInst machInst) 175 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 176 new EAComp(machInst), new MemAcc(machInst)) 177 { 178 %(constructor)s; 179 } 180}}; 181 182 183def template EACompExecute {{ 184 Fault 185 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 186 Trace::InstRecord *traceData) const 187 { 188 Addr EA; 189 Fault fault = NoFault; 190 191 %(fp_enable_check)s; 192 %(op_decl)s; 193 %(op_rd)s; 194 %(code)s; 195 196 if (fault == NoFault) { 197 %(op_wb)s; 198 xc->setEA(EA); 199 } 200 201 return fault; 202 } 203}}; 204 205def template LoadMemAccExecute {{ 206 Fault 207 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 208 Trace::InstRecord *traceData) const 209 { 210 Addr EA; 211 Fault fault = NoFault; 212 213 %(fp_enable_check)s; 214 %(op_decl)s; 215 %(op_rd)s; 216 EA = xc->getEA(); 217 218 if (fault == NoFault) { 219 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 220 %(code)s; 221 } 222 223 if (fault == NoFault) { 224 %(op_wb)s; 225 } 226 227 return fault; 228 } 229}}; 230 231 232def template LoadExecute {{ 233 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 234 Trace::InstRecord *traceData) const 235 { 236 Addr EA; 237 Fault fault = NoFault; 238 239 %(fp_enable_check)s; 240 %(op_decl)s; 241 %(op_rd)s; 242 %(ea_code)s; 243 244 if (fault == NoFault) { 245 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 246 %(memacc_code)s; 247 } 248 249 if (fault == NoFault) { 250 %(op_wb)s; 251 } 252 253 return fault; 254 } 255}}; 256 257 258def template LoadInitiateAcc {{ 259 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 260 Trace::InstRecord *traceData) const 261 { 262 Addr EA; 263 Fault fault = NoFault; 264 265 %(fp_enable_check)s; 266 %(op_src_decl)s; 267 %(op_rd)s; 268 %(ea_code)s; 269 270 if (fault == NoFault) { 271 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 272 } 273 274 return fault; 275 } 276}}; 277 278 279def template LoadCompleteAcc {{ 280 Fault %(class_name)s::completeAcc(uint8_t *data, 281 %(CPU_exec_context)s *xc, 282 Trace::InstRecord *traceData) const 283 { 284 Fault fault = NoFault; 285 286 %(fp_enable_check)s; 287 %(op_decl)s; 288 289 memcpy(&Mem, data, sizeof(Mem)); 290 291 if (fault == NoFault) { 292 %(memacc_code)s; 293 } 294 295 if (fault == NoFault) { 296 %(op_wb)s; 297 } 298 299 return fault; 300 } 301}}; 302 303 304def template StoreMemAccExecute {{ 305 Fault 306 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 307 Trace::InstRecord *traceData) const 308 { 309 Addr EA; 310 Fault fault = NoFault; 311 uint64_t write_result = 0; 312 313 %(fp_enable_check)s; 314 %(op_decl)s; 315 %(op_rd)s; 316 EA = xc->getEA(); 317 318 if (fault == NoFault) { 319 %(code)s; 320 } 321 322 if (fault == NoFault) { 323 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 324 memAccessFlags, &write_result); 325 if (traceData) { traceData->setData(Mem); } 326 } 327 328 if (fault == NoFault) { 329 %(postacc_code)s; 330 } 331 332 if (fault == NoFault) { 333 %(op_wb)s; 334 } 335 336 return fault; 337 } 338}}; 339 340 341def template StoreExecute {{ 342 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 343 Trace::InstRecord *traceData) const 344 { 345 Addr EA; 346 Fault fault = NoFault; 347 uint64_t write_result = 0; 348 349 %(fp_enable_check)s; 350 %(op_decl)s; 351 %(op_rd)s; 352 %(ea_code)s; 353 354 if (fault == NoFault) { 355 %(memacc_code)s; 356 } 357 358 if (fault == NoFault) { 359 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 360 memAccessFlags, &write_result); 361 if (traceData) { traceData->setData(Mem); } 362 } 363 364 if (fault == NoFault) { 365 %(postacc_code)s; 366 } 367 368 if (fault == NoFault) { 369 %(op_wb)s; 370 } 371 372 return fault; 373 } 374}}; 375 376def template StoreInitiateAcc {{ 377 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 378 Trace::InstRecord *traceData) const 379 { 380 Addr EA; 381 Fault fault = NoFault; 382 uint64_t write_result = 0; 383 384 %(fp_enable_check)s; 385 %(op_decl)s; 386 %(op_rd)s; 387 %(ea_code)s; 388 389 if (fault == NoFault) { 390 %(memacc_code)s; 391 } 392 393 if (fault == NoFault) { 394 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 395 memAccessFlags, &write_result); 396 if (traceData) { traceData->setData(Mem); } 397 } 398 399 return fault; 400 } 401}}; 402 403 404def template StoreCompleteAcc {{ 405 Fault %(class_name)s::completeAcc(uint8_t *data, 406 %(CPU_exec_context)s *xc, 407 Trace::InstRecord *traceData) const 408 { 409 Fault fault = NoFault; 410 uint64_t write_result = 0; 411 412 %(fp_enable_check)s; 413 %(op_dest_decl)s; 414 415 memcpy(&write_result, data, sizeof(write_result)); 416 417 if (fault == NoFault) { 418 %(postacc_code)s; 419 } 420 421 if (fault == NoFault) { 422 %(op_wb)s; 423 } 424 425 return fault; 426 } 427}}; 428
| 93def template LoadStoreDeclare {{ 94 /** 95 * Static instruction class for "%(mnemonic)s". 96 */ 97 class %(class_name)s : public %(base_class)s 98 { 99 protected: 100 101 /** 102 * "Fake" effective address computation class for "%(mnemonic)s". 103 */ 104 class EAComp : public %(base_class)s 105 { 106 public: 107 /// Constructor 108 EAComp(MachInst machInst); 109 110 %(BasicExecDeclare)s 111 }; 112 113 /** 114 * "Fake" memory access instruction class for "%(mnemonic)s". 115 */ 116 class MemAcc : public %(base_class)s 117 { 118 public: 119 /// Constructor 120 MemAcc(MachInst machInst); 121 122 %(BasicExecDeclare)s 123 }; 124 125 public: 126 127 /// Constructor. 128 %(class_name)s(MachInst machInst); 129 130 %(BasicExecDeclare)s 131 132 %(InitiateAccDeclare)s 133 134 %(CompleteAccDeclare)s 135 }; 136}}; 137 138 139def template InitiateAccDeclare {{ 140 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; 141}}; 142 143 144def template CompleteAccDeclare {{ 145 Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; 146}}; 147 148 149def template LoadStoreConstructor {{ 150 /** TODO: change op_class to AddrGenOp or something (requires 151 * creating new member of OpClass enum in op_class.hh, updating 152 * config files, etc.). */ 153 inline %(class_name)s::EAComp::EAComp(MachInst machInst) 154 : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) 155 { 156 %(ea_constructor)s; 157 } 158 159 inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) 160 : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) 161 { 162 %(memacc_constructor)s; 163 } 164 165 inline %(class_name)s::%(class_name)s(MachInst machInst) 166 : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, 167 new EAComp(machInst), new MemAcc(machInst)) 168 { 169 %(constructor)s; 170 } 171}}; 172 173 174def template EACompExecute {{ 175 Fault 176 %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, 177 Trace::InstRecord *traceData) const 178 { 179 Addr EA; 180 Fault fault = NoFault; 181 182 %(fp_enable_check)s; 183 %(op_decl)s; 184 %(op_rd)s; 185 %(code)s; 186 187 if (fault == NoFault) { 188 %(op_wb)s; 189 xc->setEA(EA); 190 } 191 192 return fault; 193 } 194}}; 195 196def template LoadMemAccExecute {{ 197 Fault 198 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 199 Trace::InstRecord *traceData) const 200 { 201 Addr EA; 202 Fault fault = NoFault; 203 204 %(fp_enable_check)s; 205 %(op_decl)s; 206 %(op_rd)s; 207 EA = xc->getEA(); 208 209 if (fault == NoFault) { 210 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 211 %(code)s; 212 } 213 214 if (fault == NoFault) { 215 %(op_wb)s; 216 } 217 218 return fault; 219 } 220}}; 221 222 223def template LoadExecute {{ 224 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 225 Trace::InstRecord *traceData) const 226 { 227 Addr EA; 228 Fault fault = NoFault; 229 230 %(fp_enable_check)s; 231 %(op_decl)s; 232 %(op_rd)s; 233 %(ea_code)s; 234 235 if (fault == NoFault) { 236 fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); 237 %(memacc_code)s; 238 } 239 240 if (fault == NoFault) { 241 %(op_wb)s; 242 } 243 244 return fault; 245 } 246}}; 247 248 249def template LoadInitiateAcc {{ 250 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 251 Trace::InstRecord *traceData) const 252 { 253 Addr EA; 254 Fault fault = NoFault; 255 256 %(fp_enable_check)s; 257 %(op_src_decl)s; 258 %(op_rd)s; 259 %(ea_code)s; 260 261 if (fault == NoFault) { 262 fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); 263 } 264 265 return fault; 266 } 267}}; 268 269 270def template LoadCompleteAcc {{ 271 Fault %(class_name)s::completeAcc(uint8_t *data, 272 %(CPU_exec_context)s *xc, 273 Trace::InstRecord *traceData) const 274 { 275 Fault fault = NoFault; 276 277 %(fp_enable_check)s; 278 %(op_decl)s; 279 280 memcpy(&Mem, data, sizeof(Mem)); 281 282 if (fault == NoFault) { 283 %(memacc_code)s; 284 } 285 286 if (fault == NoFault) { 287 %(op_wb)s; 288 } 289 290 return fault; 291 } 292}}; 293 294 295def template StoreMemAccExecute {{ 296 Fault 297 %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 298 Trace::InstRecord *traceData) const 299 { 300 Addr EA; 301 Fault fault = NoFault; 302 uint64_t write_result = 0; 303 304 %(fp_enable_check)s; 305 %(op_decl)s; 306 %(op_rd)s; 307 EA = xc->getEA(); 308 309 if (fault == NoFault) { 310 %(code)s; 311 } 312 313 if (fault == NoFault) { 314 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 315 memAccessFlags, &write_result); 316 if (traceData) { traceData->setData(Mem); } 317 } 318 319 if (fault == NoFault) { 320 %(postacc_code)s; 321 } 322 323 if (fault == NoFault) { 324 %(op_wb)s; 325 } 326 327 return fault; 328 } 329}}; 330 331 332def template StoreExecute {{ 333 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 334 Trace::InstRecord *traceData) const 335 { 336 Addr EA; 337 Fault fault = NoFault; 338 uint64_t write_result = 0; 339 340 %(fp_enable_check)s; 341 %(op_decl)s; 342 %(op_rd)s; 343 %(ea_code)s; 344 345 if (fault == NoFault) { 346 %(memacc_code)s; 347 } 348 349 if (fault == NoFault) { 350 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 351 memAccessFlags, &write_result); 352 if (traceData) { traceData->setData(Mem); } 353 } 354 355 if (fault == NoFault) { 356 %(postacc_code)s; 357 } 358 359 if (fault == NoFault) { 360 %(op_wb)s; 361 } 362 363 return fault; 364 } 365}}; 366 367def template StoreInitiateAcc {{ 368 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 369 Trace::InstRecord *traceData) const 370 { 371 Addr EA; 372 Fault fault = NoFault; 373 uint64_t write_result = 0; 374 375 %(fp_enable_check)s; 376 %(op_decl)s; 377 %(op_rd)s; 378 %(ea_code)s; 379 380 if (fault == NoFault) { 381 %(memacc_code)s; 382 } 383 384 if (fault == NoFault) { 385 fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, 386 memAccessFlags, &write_result); 387 if (traceData) { traceData->setData(Mem); } 388 } 389 390 return fault; 391 } 392}}; 393 394 395def template StoreCompleteAcc {{ 396 Fault %(class_name)s::completeAcc(uint8_t *data, 397 %(CPU_exec_context)s *xc, 398 Trace::InstRecord *traceData) const 399 { 400 Fault fault = NoFault; 401 uint64_t write_result = 0; 402 403 %(fp_enable_check)s; 404 %(op_dest_decl)s; 405 406 memcpy(&write_result, data, sizeof(write_result)); 407 408 if (fault == NoFault) { 409 %(postacc_code)s; 410 } 411 412 if (fault == NoFault) { 413 %(op_wb)s; 414 } 415 416 return fault; 417 } 418}}; 419
|
| 420 421def template MiscMemAccExecute {{ 422 Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, 423 Trace::InstRecord *traceData) const 424 { 425 Addr EA; 426 Fault fault = NoFault; 427 428 %(fp_enable_check)s; 429 %(op_decl)s; 430 %(op_rd)s; 431 EA = xc->getEA(); 432 433 if (fault == NoFault) { 434 %(code)s; 435 } 436 437 return NoFault; 438 } 439}}; 440 441def template MiscExecute {{ 442 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 443 Trace::InstRecord *traceData) const 444 { 445 Addr EA; 446 Fault fault = NoFault; 447 448 %(fp_enable_check)s; 449 %(op_decl)s; 450 %(op_rd)s; 451 %(ea_code)s; 452 453 if (fault == NoFault) { 454 %(memacc_code)s; 455 } 456 457 return NoFault; 458 } 459}}; 460 461def template MiscInitiateAcc {{ 462 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, 463 Trace::InstRecord *traceData) const 464 { 465 panic("Misc instruction does not support split access method!"); 466 return NoFault; 467 } 468}}; 469 470 471def template MiscCompleteAcc {{ 472 Fault %(class_name)s::completeAcc(uint8_t *data, 473 %(CPU_exec_context)s *xc, 474 Trace::InstRecord *traceData) const 475 { 476 panic("Misc instruction does not support split access method!"); 477 478 return NoFault; 479 } 480}}; 481
|
429// load instructions use Rt as dest, so check for
| 482// load instructions use Rt as dest, so check for
|
430// Rt == 31 to detect nops
| 483// Rt == 0 to detect nops
|
431def template LoadNopCheckDecode {{ 432 { 433 MipsStaticInst *i = new %(class_name)s(machInst); 434 if (RT == 0) { 435 i = makeNop(i); 436 } 437 return i; 438 } 439}}; 440 441def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 442 mem_flags = [], inst_flags = []) {{ 443 (header_output, decoder_output, decode_block, exec_output) = \ 444 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 445 decode_template = LoadNopCheckDecode, 446 exec_template_base = 'Load') 447}}; 448
| 484def template LoadNopCheckDecode {{ 485 { 486 MipsStaticInst *i = new %(class_name)s(machInst); 487 if (RT == 0) { 488 i = makeNop(i); 489 } 490 return i; 491 } 492}}; 493 494def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 495 mem_flags = [], inst_flags = []) {{ 496 (header_output, decoder_output, decode_block, exec_output) = \ 497 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 498 decode_template = LoadNopCheckDecode, 499 exec_template_base = 'Load') 500}}; 501
|
449
| |
450def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 451 mem_flags = [], inst_flags = []) {{ 452 (header_output, decoder_output, decode_block, exec_output) = \ 453 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 454 exec_template_base = 'Store') 455}}; 456
| 502def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, 503 mem_flags = [], inst_flags = []) {{ 504 (header_output, decoder_output, decode_block, exec_output) = \ 505 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 506 exec_template_base = 'Store') 507}}; 508
|
457//FP loads are offloaded to these formats for now ... 458def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
| 509def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
|
459 mem_flags = [], inst_flags = []) {{ 460 (header_output, decoder_output, decode_block, exec_output) = \ 461 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
| 510 mem_flags = [], inst_flags = []) {{ 511 (header_output, decoder_output, decode_block, exec_output) = \ 512 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
462 decode_template = BasicDecode,
| 513 decode_template = LoadNopCheckDecode,
|
463 exec_template_base = 'Load') 464}}; 465
| 514 exec_template_base = 'Load') 515}}; 516
|
| 517def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }}, 518 mem_flags = [], inst_flags = []) {{ 519 (header_output, decoder_output, decode_block, exec_output) = \ 520 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 521 exec_template_base = 'Store') 522}};
|
466
| 523
|
467def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
| 524def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
|
468 mem_flags = [], inst_flags = []) {{
| 525 mem_flags = [], inst_flags = []) {{
|
| 526 decl_code = 'uint32_t mem_word = Mem.uw;\n' 527 decl_code += 'uint32_t unalign_addr = Rs + disp;\n' 528 decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n' 529 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 530 decl_code += '\tbyte_offset ^= 3;\n' 531 decl_code += '#endif\n' 532 533 memacc_code = decl_code + memacc_code 534
|
469 (header_output, decoder_output, decode_block, exec_output) = \ 470 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
| 535 (header_output, decoder_output, decode_block, exec_output) = \ 536 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
| 537 decode_template = LoadNopCheckDecode, 538 exec_template_base = 'Load') 539}}; 540 541def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }}, 542 mem_flags = [], inst_flags = []) {{ 543 decl_code = 'uint32_t mem_word = 0;\n' 544 decl_code += 'uint32_t unaligned_addr = Rs + disp;\n' 545 decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n' 546 decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n' 547 decl_code += '\tbyte_offset ^= 3;\n' 548 decl_code += '#endif\n' 549 decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n' 550 memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n' 551 552 (header_output, decoder_output, decode_block, exec_output) = \ 553 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 554 decode_template = LoadNopCheckDecode,
|
471 exec_template_base = 'Store') 472}}; 473
| 555 exec_template_base = 'Store') 556}}; 557
|
| 558def format Prefetch(ea_code = {{ EA = Rs + disp; }}, 559 mem_flags = [], pf_flags = [], inst_flags = []) {{ 560 pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] 561 pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 562 'IsDataPrefetch', 'MemReadOp']
|
474
| 563
|
475def format UnalignedStore(memacc_code, postacc_code, 476 ea_code = {{ EA = Rb + disp; }},
| 564 (header_output, decoder_output, decode_block, exec_output) = \ 565 LoadStoreBase(name, Name, ea_code, 566 'xc->prefetch(EA, memAccessFlags);', 567 pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') 568 569}}; 570 571def format StoreCond(memacc_code, postacc_code, 572 ea_code = {{ EA = Rs + disp; }},
|
477 mem_flags = [], inst_flags = []) {{ 478 (header_output, decoder_output, decode_block, exec_output) = \ 479 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 480 postacc_code, exec_template_base = 'Store') 481}};
| 573 mem_flags = [], inst_flags = []) {{ 574 (header_output, decoder_output, decode_block, exec_output) = \ 575 LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, 576 postacc_code, exec_template_base = 'Store') 577}};
|