base_dyn_inst.hh (9044:904ddeecc653) | base_dyn_inst.hh (9046:a1104cc13db2) |
---|---|
1/* 2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 84 unchanged lines hidden (view full) --- 93 // The list of instructions iterator type. 94 typedef typename std::list<DynInstPtr>::iterator ListIt; 95 96 enum { 97 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 98 MaxInstDestRegs = TheISA::MaxInstDestRegs /// Max dest regs 99 }; 100 | 1/* 2 * Copyright (c) 2011 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 84 unchanged lines hidden (view full) --- 93 // The list of instructions iterator type. 94 typedef typename std::list<DynInstPtr>::iterator ListIt; 95 96 enum { 97 MaxInstSrcRegs = TheISA::MaxInstSrcRegs, /// Max source regs 98 MaxInstDestRegs = TheISA::MaxInstDestRegs /// Max dest regs 99 }; 100 |
101 /** The StaticInst used by this BaseDynInst. */ 102 StaticInstPtr staticInst; 103 StaticInstPtr macroop; | 101 union Result { 102 uint64_t integer; 103 double dbl; 104 void set(uint64_t i) { integer = i; } 105 void set(double d) { dbl = d; } 106 void get(uint64_t& i) { i = integer; } 107 void get(double& d) { d = dbl; } 108 }; |
104 | 109 |
105 //////////////////////////////////////////// 106 // 107 // INSTRUCTION EXECUTION 108 // 109 //////////////////////////////////////////// 110 /** InstRecord that tracks this instructions. */ 111 Trace::InstRecord *traceData; 112 113 void demapPage(Addr vaddr, uint64_t asn) 114 { 115 cpu->demapPage(vaddr, asn); 116 } 117 void demapInstPage(Addr vaddr, uint64_t asn) 118 { 119 cpu->demapPage(vaddr, asn); 120 } 121 void demapDataPage(Addr vaddr, uint64_t asn) 122 { 123 cpu->demapPage(vaddr, asn); 124 } 125 126 Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); 127 128 Fault writeMem(uint8_t *data, unsigned size, 129 Addr addr, unsigned flags, uint64_t *res); 130 131 /** Splits a request in two if it crosses a dcache block. */ 132 void splitRequest(RequestPtr req, RequestPtr &sreqLow, 133 RequestPtr &sreqHigh); 134 135 /** Initiate a DTB address translation. */ 136 void initiateTranslation(RequestPtr req, RequestPtr sreqLow, 137 RequestPtr sreqHigh, uint64_t *res, 138 BaseTLB::Mode mode); 139 140 /** Finish a DTB address translation. */ 141 void finishTranslation(WholeTranslationState *state); 142 143 /** True if the DTB address translation has started. */ 144 bool translationStarted; 145 146 /** True if the DTB address translation has completed. */ 147 bool translationCompleted; 148 149 /** True if this address was found to match a previous load and they issued 150 * out of order. If that happend, then it's only a problem if an incoming 151 * snoop invalidate modifies the line, in which case we need to squash. 152 * If nothing modified the line the order doesn't matter. 153 */ 154 bool possibleLoadViolation; 155 156 /** True if the address hit a external snoop while sitting in the LSQ. 157 * If this is true and a older instruction sees it, this instruction must 158 * reexecute 159 */ 160 bool hitExternalSnoop; 161 162 /** 163 * Returns true if the DTB address translation is being delayed due to a hw 164 * page table walk. 165 */ 166 bool isTranslationDelayed() const 167 { 168 return (translationStarted && !translationCompleted); 169 } 170 171 /** 172 * Saved memory requests (needed when the DTB address translation is 173 * delayed due to a hw page table walk). 174 */ 175 RequestPtr savedReq; 176 RequestPtr savedSreqLow; 177 RequestPtr savedSreqHigh; 178 179 // Need a copy of main request pointer to verify on writes. 180 RequestPtr reqToVerify; 181 182 /** @todo: Consider making this private. */ 183 public: 184 /** The sequence number of the instruction. */ 185 InstSeqNum seqNum; 186 | 110 protected: |
187 enum Status { 188 IqEntry, /// Instruction is in the IQ 189 RobEntry, /// Instruction is in the ROB 190 LsqEntry, /// Instruction is in the LSQ 191 Completed, /// Instruction has completed 192 ResultReady, /// Instruction has its result 193 CanIssue, /// Instruction can issue and execute 194 Issued, /// Instruction has issued --- 10 unchanged lines hidden (view full) --- 205 ThreadsyncWait, /// Is a thread synchronization instruction 206 SerializeBefore, /// Needs to serialize on 207 /// instructions ahead of it 208 SerializeAfter, /// Needs to serialize instructions behind it 209 SerializeHandled, /// Serialization has been handled 210 NumStatus 211 }; 212 | 111 enum Status { 112 IqEntry, /// Instruction is in the IQ 113 RobEntry, /// Instruction is in the ROB 114 LsqEntry, /// Instruction is in the LSQ 115 Completed, /// Instruction has completed 116 ResultReady, /// Instruction has its result 117 CanIssue, /// Instruction can issue and execute 118 Issued, /// Instruction has issued --- 10 unchanged lines hidden (view full) --- 129 ThreadsyncWait, /// Is a thread synchronization instruction 130 SerializeBefore, /// Needs to serialize on 131 /// instructions ahead of it 132 SerializeAfter, /// Needs to serialize instructions behind it 133 SerializeHandled, /// Serialization has been handled 134 NumStatus 135 }; 136 |
213 /** The status of this BaseDynInst. Several bits can be set. */ 214 std::bitset<NumStatus> status; | 137 enum Flags { 138 TranslationStarted, 139 TranslationCompleted, 140 PossibleLoadViolation, 141 HitExternalSnoop, 142 EffAddrValid, 143 RecordResult, 144 Predicate, 145 PredTaken, 146 /** Whether or not the effective address calculation is completed. 147 * @todo: Consider if this is necessary or not. 148 */ 149 EACalcDone, 150 IsUncacheable, 151 ReqMade, 152 MemOpDone, 153 MaxFlags 154 }; |
215 | 155 |
216 /** The thread this instruction is from. */ 217 ThreadID threadNumber; | 156 public: 157 /** The sequence number of the instruction. */ 158 InstSeqNum seqNum; |
218 | 159 |
219 /** data address space ID, for loads & stores. */ 220 short asid; | 160 /** The StaticInst used by this BaseDynInst. */ 161 StaticInstPtr staticInst; |
221 | 162 |
222 /** How many source registers are ready. */ 223 unsigned readyRegs; 224 | |
225 /** Pointer to the Impl's CPU object. */ 226 ImplCPU *cpu; 227 228 /** Pointer to the thread state. */ 229 ImplState *thread; 230 231 /** The kind of fault this instruction has generated. */ 232 Fault fault; 233 | 163 /** Pointer to the Impl's CPU object. */ 164 ImplCPU *cpu; 165 166 /** Pointer to the thread state. */ 167 ImplState *thread; 168 169 /** The kind of fault this instruction has generated. */ 170 Fault fault; 171 |
234 /** Pointer to the data for the memory access. */ 235 uint8_t *memData; | 172 /** InstRecord that tracks this instructions. */ 173 Trace::InstRecord *traceData; |
236 | 174 |
237 /** The effective virtual address (lds & stores only). */ 238 Addr effAddr; | 175 protected: 176 /** The result of the instruction; assumes an instruction can have many 177 * destination registers. 178 */ 179 std::queue<Result> instResult; |
239 | 180 |
240 /** The size of the request */ 241 Addr effSize; | 181 /** PC state for this instruction. */ 182 TheISA::PCState pc; |
242 | 183 |
243 /** Is the effective virtual address valid. */ 244 bool effAddrValid; | 184 /* An amalgamation of a lot of boolean values into one */ 185 std::bitset<MaxFlags> instFlags; |
245 | 186 |
187 /** The status of this BaseDynInst. Several bits can be set. */ 188 std::bitset<NumStatus> status; 189 190 /** Whether or not the source register is ready. 191 * @todo: Not sure this should be here vs the derived class. 192 */ 193 std::bitset<MaxInstSrcRegs> _readySrcRegIdx; 194 195 public: 196 /** The thread this instruction is from. */ 197 ThreadID threadNumber; 198 199 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 200 ListIt instListIt; 201 202 ////////////////////// Branch Data /////////////// 203 /** Predicted PC state after this instruction. */ 204 TheISA::PCState predPC; 205 206 /** The Macroop if one exists */ 207 StaticInstPtr macroop; 208 209 /** How many source registers are ready. */ 210 uint8_t readyRegs; 211 212 public: 213 /////////////////////// Load Store Data ////////////////////// 214 /** The effective virtual address (lds & stores only). */ 215 Addr effAddr; 216 |
|
246 /** The effective physical address. */ 247 Addr physEffAddr; 248 249 /** The memory request flags (from translation). */ 250 unsigned memReqFlags; 251 | 217 /** The effective physical address. */ 218 Addr physEffAddr; 219 220 /** The memory request flags (from translation). */ 221 unsigned memReqFlags; 222 |
252 union Result { 253 uint64_t integer; 254 double dbl; 255 void set(uint64_t i) { integer = i; } 256 void set(double d) { dbl = d; } 257 void get(uint64_t& i) { i = integer; } 258 void get(double& d) { d = dbl; } 259 }; | 223 /** data address space ID, for loads & stores. */ 224 short asid; |
260 | 225 |
261 /** The result of the instruction; assumes an instruction can have many 262 * destination registers. 263 */ 264 std::queue<Result> instResult; | 226 /** The size of the request */ 227 uint8_t effSize; |
265 | 228 |
266 /** Records changes to result? */ 267 bool recordResult; | 229 /** Pointer to the data for the memory access. */ 230 uint8_t *memData; |
268 | 231 |
269 /** Did this instruction execute, or is it predicated false */ 270 bool predicate; | 232 /** Load queue index. */ 233 int16_t lqIdx; |
271 | 234 |
272 protected: 273 /** PC state for this instruction. */ 274 TheISA::PCState pc; | 235 /** Store queue index. */ 236 int16_t sqIdx; |
275 | 237 |
276 /** Predicted PC state after this instruction. */ 277 TheISA::PCState predPC; | |
278 | 238 |
279 /** If this is a branch that was predicted taken */ 280 bool predTaken; | 239 /////////////////////// TLB Miss ////////////////////// 240 /** 241 * Saved memory requests (needed when the DTB address translation is 242 * delayed due to a hw page table walk). 243 */ 244 RequestPtr savedReq; 245 RequestPtr savedSreqLow; 246 RequestPtr savedSreqHigh; |
281 | 247 |
282 public: | 248 /////////////////////// Checker ////////////////////// 249 // Need a copy of main request pointer to verify on writes. 250 RequestPtr reqToVerify; |
283 | 251 |
284#ifdef DEBUG 285 void dumpSNList(); 286#endif 287 288 /** Whether or not the source register is ready. 289 * @todo: Not sure this should be here vs the derived class. | 252 private: 253 /** Instruction effective address. 254 * @todo: Consider if this is necessary or not. |
290 */ | 255 */ |
291 bool _readySrcRegIdx[MaxInstSrcRegs]; | 256 Addr instEffAddr; |
292 293 protected: 294 /** Flattened register index of the destination registers of this 295 * instruction. 296 */ 297 TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; 298 | 257 258 protected: 259 /** Flattened register index of the destination registers of this 260 * instruction. 261 */ 262 TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; 263 |
299 /** Flattened register index of the source registers of this 300 * instruction. 301 */ 302 TheISA::RegIndex _flatSrcRegIdx[TheISA::MaxInstSrcRegs]; 303 | |
304 /** Physical register index of the destination registers of this 305 * instruction. 306 */ 307 PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; 308 309 /** Physical register index of the source registers of this 310 * instruction. 311 */ 312 PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; 313 314 /** Physical register index of the previous producers of the 315 * architected destinations. 316 */ 317 PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; 318 | 264 /** Physical register index of the destination registers of this 265 * instruction. 266 */ 267 PhysRegIndex _destRegIdx[TheISA::MaxInstDestRegs]; 268 269 /** Physical register index of the source registers of this 270 * instruction. 271 */ 272 PhysRegIndex _srcRegIdx[TheISA::MaxInstSrcRegs]; 273 274 /** Physical register index of the previous producers of the 275 * architected destinations. 276 */ 277 PhysRegIndex _prevDestRegIdx[TheISA::MaxInstDestRegs]; 278 |
279 |
|
319 public: | 280 public: |
281 /** Records changes to result? */ 282 void recordResult(bool f) { instFlags[RecordResult] = f; } |
|
320 | 283 |
284 /** Is the effective virtual address valid. */ 285 bool effAddrValid() const { return instFlags[EffAddrValid]; } 286 287 /** Whether or not the memory operation is done. */ 288 bool memOpDone() const { return instFlags[MemOpDone]; } 289 void memOpDone(bool f) { instFlags[MemOpDone] = f; } 290 291 292 //////////////////////////////////////////// 293 // 294 // INSTRUCTION EXECUTION 295 // 296 //////////////////////////////////////////// 297 298 void demapPage(Addr vaddr, uint64_t asn) 299 { 300 cpu->demapPage(vaddr, asn); 301 } 302 void demapInstPage(Addr vaddr, uint64_t asn) 303 { 304 cpu->demapPage(vaddr, asn); 305 } 306 void demapDataPage(Addr vaddr, uint64_t asn) 307 { 308 cpu->demapPage(vaddr, asn); 309 } 310 311 Fault readMem(Addr addr, uint8_t *data, unsigned size, unsigned flags); 312 313 Fault writeMem(uint8_t *data, unsigned size, 314 Addr addr, unsigned flags, uint64_t *res); 315 316 /** Splits a request in two if it crosses a dcache block. */ 317 void splitRequest(RequestPtr req, RequestPtr &sreqLow, 318 RequestPtr &sreqHigh); 319 320 /** Initiate a DTB address translation. */ 321 void initiateTranslation(RequestPtr req, RequestPtr sreqLow, 322 RequestPtr sreqHigh, uint64_t *res, 323 BaseTLB::Mode mode); 324 325 /** Finish a DTB address translation. */ 326 void finishTranslation(WholeTranslationState *state); 327 328 /** True if the DTB address translation has started. */ 329 bool translationStarted() const { return instFlags[TranslationStarted]; } 330 void translationStarted(bool f) { instFlags[TranslationStarted] = f; } 331 332 /** True if the DTB address translation has completed. */ 333 bool translationCompleted() const { return instFlags[TranslationCompleted]; } 334 void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; } 335 336 /** True if this address was found to match a previous load and they issued 337 * out of order. If that happend, then it's only a problem if an incoming 338 * snoop invalidate modifies the line, in which case we need to squash. 339 * If nothing modified the line the order doesn't matter. 340 */ 341 bool possibleLoadViolation() const { return instFlags[PossibleLoadViolation]; } 342 void possibleLoadViolation(bool f) { instFlags[PossibleLoadViolation] = f; } 343 344 /** True if the address hit a external snoop while sitting in the LSQ. 345 * If this is true and a older instruction sees it, this instruction must 346 * reexecute 347 */ 348 bool hitExternalSnoop() const { return instFlags[HitExternalSnoop]; } 349 void hitExternalSnoop(bool f) { instFlags[HitExternalSnoop] = f; } 350 351 /** 352 * Returns true if the DTB address translation is being delayed due to a hw 353 * page table walk. 354 */ 355 bool isTranslationDelayed() const 356 { 357 return (translationStarted() && !translationCompleted()); 358 } 359 360 public: 361#ifdef DEBUG 362 void dumpSNList(); 363#endif 364 |
|
321 /** Returns the physical register index of the i'th destination 322 * register. 323 */ 324 PhysRegIndex renamedDestRegIdx(int idx) const 325 { 326 return _destRegIdx[idx]; 327 } 328 329 /** Returns the physical register index of the i'th source register. */ 330 PhysRegIndex renamedSrcRegIdx(int idx) const 331 { | 365 /** Returns the physical register index of the i'th destination 366 * register. 367 */ 368 PhysRegIndex renamedDestRegIdx(int idx) const 369 { 370 return _destRegIdx[idx]; 371 } 372 373 /** Returns the physical register index of the i'th source register. */ 374 PhysRegIndex renamedSrcRegIdx(int idx) const 375 { |
376 assert(TheISA::MaxInstSrcRegs > idx); |
|
332 return _srcRegIdx[idx]; 333 } 334 335 /** Returns the flattened register index of the i'th destination 336 * register. 337 */ 338 TheISA::RegIndex flattenedDestRegIdx(int idx) const 339 { 340 return _flatDestRegIdx[idx]; 341 } 342 | 377 return _srcRegIdx[idx]; 378 } 379 380 /** Returns the flattened register index of the i'th destination 381 * register. 382 */ 383 TheISA::RegIndex flattenedDestRegIdx(int idx) const 384 { 385 return _flatDestRegIdx[idx]; 386 } 387 |
343 /** Returns the flattened register index of the i'th source register */ 344 TheISA::RegIndex flattenedSrcRegIdx(int idx) const 345 { 346 return _flatSrcRegIdx[idx]; 347 } 348 | |
349 /** Returns the physical register index of the previous physical register 350 * that remapped to the same logical register index. 351 */ 352 PhysRegIndex prevDestRegIdx(int idx) const 353 { 354 return _prevDestRegIdx[idx]; 355 } 356 --- 12 unchanged lines hidden (view full) --- 369 * has/will produce that logical register's result. 370 * @todo: add in whether or not the source register is ready. 371 */ 372 void renameSrcReg(int idx, PhysRegIndex renamed_src) 373 { 374 _srcRegIdx[idx] = renamed_src; 375 } 376 | 388 /** Returns the physical register index of the previous physical register 389 * that remapped to the same logical register index. 390 */ 391 PhysRegIndex prevDestRegIdx(int idx) const 392 { 393 return _prevDestRegIdx[idx]; 394 } 395 --- 12 unchanged lines hidden (view full) --- 408 * has/will produce that logical register's result. 409 * @todo: add in whether or not the source register is ready. 410 */ 411 void renameSrcReg(int idx, PhysRegIndex renamed_src) 412 { 413 _srcRegIdx[idx] = renamed_src; 414 } 415 |
377 /** Flattens a source architectural register index into a logical index. 378 */ 379 void flattenSrcReg(int idx, TheISA::RegIndex flattened_src) 380 { 381 _flatSrcRegIdx[idx] = flattened_src; 382 } 383 | |
384 /** Flattens a destination architectural register index into a logical 385 * index. 386 */ 387 void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) 388 { 389 _flatDestRegIdx[idx] = flattened_dest; 390 } 391 /** BaseDynInst constructor given a binary instruction. --- 60 unchanged lines hidden (view full) --- 452 Addr predNextInstAddr() { return predPC.nextInstAddr(); } 453 454 /** Returns the predicted micro PC after the branch */ 455 Addr predMicroPC() { return predPC.microPC(); } 456 457 /** Returns whether the instruction was predicted taken or not. */ 458 bool readPredTaken() 459 { | 416 /** Flattens a destination architectural register index into a logical 417 * index. 418 */ 419 void flattenDestReg(int idx, TheISA::RegIndex flattened_dest) 420 { 421 _flatDestRegIdx[idx] = flattened_dest; 422 } 423 /** BaseDynInst constructor given a binary instruction. --- 60 unchanged lines hidden (view full) --- 484 Addr predNextInstAddr() { return predPC.nextInstAddr(); } 485 486 /** Returns the predicted micro PC after the branch */ 487 Addr predMicroPC() { return predPC.microPC(); } 488 489 /** Returns whether the instruction was predicted taken or not. */ 490 bool readPredTaken() 491 { |
460 return predTaken; | 492 return instFlags[PredTaken]; |
461 } 462 463 void setPredTaken(bool predicted_taken) 464 { | 493 } 494 495 void setPredTaken(bool predicted_taken) 496 { |
465 predTaken = predicted_taken; | 497 instFlags[PredTaken] = predicted_taken; |
466 } 467 468 /** Returns whether the instruction mispredicted. */ 469 bool mispredicted() 470 { 471 TheISA::PCState tempPC = pc; 472 TheISA::advancePC(tempPC, staticInst); 473 return !(tempPC == predPC); --- 109 unchanged lines hidden (view full) --- 583 { 584 instResult.back().get(t); 585 } 586 587 /** Pushes a result onto the instResult queue */ 588 template <class T> 589 void setResult(T t) 590 { | 498 } 499 500 /** Returns whether the instruction mispredicted. */ 501 bool mispredicted() 502 { 503 TheISA::PCState tempPC = pc; 504 TheISA::advancePC(tempPC, staticInst); 505 return !(tempPC == predPC); --- 109 unchanged lines hidden (view full) --- 615 { 616 instResult.back().get(t); 617 } 618 619 /** Pushes a result onto the instResult queue */ 620 template <class T> 621 void setResult(T t) 622 { |
591 if (recordResult) { | 623 if (instFlags[RecordResult]) { |
592 Result instRes; 593 instRes.set(t); 594 instResult.push(instRes); 595 } 596 } 597 598 /** Records an integer register being set to a value. */ 599 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) --- 169 unchanged lines hidden (view full) --- 769 /** Read the PC of the next instruction. */ 770 const Addr nextInstAddr() const { return pc.nextInstAddr(); } 771 772 /**Read the micro PC of this instruction. */ 773 const Addr microPC() const { return pc.microPC(); } 774 775 bool readPredicate() 776 { | 624 Result instRes; 625 instRes.set(t); 626 instResult.push(instRes); 627 } 628 } 629 630 /** Records an integer register being set to a value. */ 631 void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) --- 169 unchanged lines hidden (view full) --- 801 /** Read the PC of the next instruction. */ 802 const Addr nextInstAddr() const { return pc.nextInstAddr(); } 803 804 /**Read the micro PC of this instruction. */ 805 const Addr microPC() const { return pc.microPC(); } 806 807 bool readPredicate() 808 { |
777 return predicate; | 809 return instFlags[Predicate]; |
778 } 779 780 void setPredicate(bool val) 781 { | 810 } 811 812 void setPredicate(bool val) 813 { |
782 predicate = val; | 814 instFlags[Predicate] = val; |
783 784 if (traceData) { 785 traceData->setPredicate(val); 786 } 787 } 788 789 /** Sets the ASID. */ 790 void setASID(short addr_space_id) { asid = addr_space_id; } 791 792 /** Sets the thread id. */ 793 void setTid(ThreadID tid) { threadNumber = tid; } 794 795 /** Sets the pointer to the thread state. */ 796 void setThreadState(ImplState *state) { thread = state; } 797 798 /** Returns the thread context. */ 799 ThreadContext *tcBase() { return thread->getTC(); } 800 | 815 816 if (traceData) { 817 traceData->setPredicate(val); 818 } 819 } 820 821 /** Sets the ASID. */ 822 void setASID(short addr_space_id) { asid = addr_space_id; } 823 824 /** Sets the thread id. */ 825 void setTid(ThreadID tid) { threadNumber = tid; } 826 827 /** Sets the pointer to the thread state. */ 828 void setThreadState(ImplState *state) { thread = state; } 829 830 /** Returns the thread context. */ 831 ThreadContext *tcBase() { return thread->getTC(); } 832 |
801 private: 802 /** Instruction effective address. 803 * @todo: Consider if this is necessary or not. 804 */ 805 Addr instEffAddr; 806 807 /** Whether or not the effective address calculation is completed. 808 * @todo: Consider if this is necessary or not. 809 */ 810 bool eaCalcDone; 811 812 /** Is this instruction's memory access uncacheable. */ 813 bool isUncacheable; 814 815 /** Has this instruction generated a memory request. */ 816 bool reqMade; 817 | |
818 public: 819 /** Sets the effective address. */ | 833 public: 834 /** Sets the effective address. */ |
820 void setEA(Addr &ea) { instEffAddr = ea; eaCalcDone = true; } | 835 void setEA(Addr &ea) { instEffAddr = ea; instFlags[EACalcDone] = true; } |
821 822 /** Returns the effective address. */ 823 const Addr &getEA() const { return instEffAddr; } 824 825 /** Returns whether or not the eff. addr. calculation has been completed. */ | 836 837 /** Returns the effective address. */ 838 const Addr &getEA() const { return instEffAddr; } 839 840 /** Returns whether or not the eff. addr. calculation has been completed. */ |
826 bool doneEACalc() { return eaCalcDone; } | 841 bool doneEACalc() { return instFlags[EACalcDone]; } |
827 828 /** Returns whether or not the eff. addr. source registers are ready. */ 829 bool eaSrcsReady(); 830 | 842 843 /** Returns whether or not the eff. addr. source registers are ready. */ 844 bool eaSrcsReady(); 845 |
831 /** Whether or not the memory operation is done. */ 832 bool memOpDone; 833 | |
834 /** Is this instruction's memory access uncacheable. */ | 846 /** Is this instruction's memory access uncacheable. */ |
835 bool uncacheable() { return isUncacheable; } | 847 bool uncacheable() { return instFlags[IsUncacheable]; } |
836 837 /** Has this instruction generated a memory request. */ | 848 849 /** Has this instruction generated a memory request. */ |
838 bool hasRequest() { return reqMade; } | 850 bool hasRequest() { return instFlags[ReqMade]; } |
839 | 851 |
840 public: 841 /** Load queue index. */ 842 int16_t lqIdx; 843 844 /** Store queue index. */ 845 int16_t sqIdx; 846 847 /** Iterator pointing to this BaseDynInst in the list of all insts. */ 848 ListIt instListIt; 849 | |
850 /** Returns iterator to this instruction in the list of all insts. */ 851 ListIt &getInstListIt() { return instListIt; } 852 853 /** Sets iterator for this instruction in the list of all insts. */ 854 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 855 856 public: 857 /** Returns the number of consecutive store conditional failures. */ --- 5 unchanged lines hidden (view full) --- 863 { thread->storeCondFailures = sc_failures; } 864}; 865 866template<class Impl> 867Fault 868BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data, 869 unsigned size, unsigned flags) 870{ | 852 /** Returns iterator to this instruction in the list of all insts. */ 853 ListIt &getInstListIt() { return instListIt; } 854 855 /** Sets iterator for this instruction in the list of all insts. */ 856 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 857 858 public: 859 /** Returns the number of consecutive store conditional failures. */ --- 5 unchanged lines hidden (view full) --- 865 { thread->storeCondFailures = sc_failures; } 866}; 867 868template<class Impl> 869Fault 870BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data, 871 unsigned size, unsigned flags) 872{ |
871 reqMade = true; | 873 instFlags[ReqMade] = true; |
872 Request *req = NULL; 873 Request *sreqLow = NULL; 874 Request *sreqHigh = NULL; 875 | 874 Request *req = NULL; 875 Request *sreqLow = NULL; 876 Request *sreqHigh = NULL; 877 |
876 if (reqMade && translationStarted) { | 878 if (instFlags[ReqMade] && translationStarted()) { |
877 req = savedReq; 878 sreqLow = savedSreqLow; 879 sreqHigh = savedSreqHigh; 880 } else { 881 req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), 882 thread->contextId(), threadNumber); 883 884 // Only split the request if the ISA supports unaligned accesses. 885 if (TheISA::HasUnalignedMemAcc) { 886 splitRequest(req, sreqLow, sreqHigh); 887 } 888 initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read); 889 } 890 | 879 req = savedReq; 880 sreqLow = savedSreqLow; 881 sreqHigh = savedSreqHigh; 882 } else { 883 req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), 884 thread->contextId(), threadNumber); 885 886 // Only split the request if the ISA supports unaligned accesses. 887 if (TheISA::HasUnalignedMemAcc) { 888 splitRequest(req, sreqLow, sreqHigh); 889 } 890 initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read); 891 } 892 |
891 if (translationCompleted) { | 893 if (translationCompleted()) { |
892 if (fault == NoFault) { 893 effAddr = req->getVaddr(); 894 effSize = size; | 894 if (fault == NoFault) { 895 effAddr = req->getVaddr(); 896 effSize = size; |
895 effAddrValid = true; | 897 instFlags[EffAddrValid] = true; |
896 897 if (cpu->checker) { 898 if (reqToVerify != NULL) { 899 delete reqToVerify; 900 } 901 reqToVerify = new Request(*req); 902 } 903 fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx); --- 22 unchanged lines hidden (view full) --- 926Fault 927BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, 928 Addr addr, unsigned flags, uint64_t *res) 929{ 930 if (traceData) { 931 traceData->setAddr(addr); 932 } 933 | 898 899 if (cpu->checker) { 900 if (reqToVerify != NULL) { 901 delete reqToVerify; 902 } 903 reqToVerify = new Request(*req); 904 } 905 fault = cpu->read(req, sreqLow, sreqHigh, data, lqIdx); --- 22 unchanged lines hidden (view full) --- 928Fault 929BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, 930 Addr addr, unsigned flags, uint64_t *res) 931{ 932 if (traceData) { 933 traceData->setAddr(addr); 934 } 935 |
934 reqMade = true; | 936 instFlags[ReqMade] = true; |
935 Request *req = NULL; 936 Request *sreqLow = NULL; 937 Request *sreqHigh = NULL; 938 | 937 Request *req = NULL; 938 Request *sreqLow = NULL; 939 Request *sreqHigh = NULL; 940 |
939 if (reqMade && translationStarted) { | 941 if (instFlags[ReqMade] && translationStarted()) { |
940 req = savedReq; 941 sreqLow = savedSreqLow; 942 sreqHigh = savedSreqHigh; 943 } else { 944 req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), 945 thread->contextId(), threadNumber); 946 947 // Only split the request if the ISA supports unaligned accesses. 948 if (TheISA::HasUnalignedMemAcc) { 949 splitRequest(req, sreqLow, sreqHigh); 950 } 951 initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write); 952 } 953 | 942 req = savedReq; 943 sreqLow = savedSreqLow; 944 sreqHigh = savedSreqHigh; 945 } else { 946 req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(), 947 thread->contextId(), threadNumber); 948 949 // Only split the request if the ISA supports unaligned accesses. 950 if (TheISA::HasUnalignedMemAcc) { 951 splitRequest(req, sreqLow, sreqHigh); 952 } 953 initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write); 954 } 955 |
954 if (fault == NoFault && translationCompleted) { | 956 if (fault == NoFault && translationCompleted()) { |
955 effAddr = req->getVaddr(); 956 effSize = size; | 957 effAddr = req->getVaddr(); 958 effSize = size; |
957 effAddrValid = true; | 959 instFlags[EffAddrValid] = true; |
958 959 if (cpu->checker) { 960 if (reqToVerify != NULL) { 961 delete reqToVerify; 962 } 963 reqToVerify = new Request(*req); 964 } 965 fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx); --- 20 unchanged lines hidden (view full) --- 986} 987 988template<class Impl> 989inline void 990BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow, 991 RequestPtr sreqHigh, uint64_t *res, 992 BaseTLB::Mode mode) 993{ | 960 961 if (cpu->checker) { 962 if (reqToVerify != NULL) { 963 delete reqToVerify; 964 } 965 reqToVerify = new Request(*req); 966 } 967 fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx); --- 20 unchanged lines hidden (view full) --- 988} 989 990template<class Impl> 991inline void 992BaseDynInst<Impl>::initiateTranslation(RequestPtr req, RequestPtr sreqLow, 993 RequestPtr sreqHigh, uint64_t *res, 994 BaseTLB::Mode mode) 995{ |
994 translationStarted = true; | 996 translationStarted(true); |
995 996 if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) { 997 WholeTranslationState *state = 998 new WholeTranslationState(req, NULL, res, mode); 999 1000 // One translation if the request isn't split. 1001 DataTranslation<BaseDynInstPtr> *trans = 1002 new DataTranslation<BaseDynInstPtr>(this, state); 1003 cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); | 997 998 if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) { 999 WholeTranslationState *state = 1000 new WholeTranslationState(req, NULL, res, mode); 1001 1002 // One translation if the request isn't split. 1003 DataTranslation<BaseDynInstPtr> *trans = 1004 new DataTranslation<BaseDynInstPtr>(this, state); 1005 cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); |
1004 if (!translationCompleted) { | 1006 if (!translationCompleted()) { |
1005 // Save memory requests. 1006 savedReq = state->mainReq; 1007 savedSreqLow = state->sreqLow; 1008 savedSreqHigh = state->sreqHigh; 1009 } 1010 } else { 1011 WholeTranslationState *state = 1012 new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, mode); 1013 1014 // Two translations when the request is split. 1015 DataTranslation<BaseDynInstPtr> *stransLow = 1016 new DataTranslation<BaseDynInstPtr>(this, state, 0); 1017 DataTranslation<BaseDynInstPtr> *stransHigh = 1018 new DataTranslation<BaseDynInstPtr>(this, state, 1); 1019 1020 cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode); 1021 cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode); | 1007 // Save memory requests. 1008 savedReq = state->mainReq; 1009 savedSreqLow = state->sreqLow; 1010 savedSreqHigh = state->sreqHigh; 1011 } 1012 } else { 1013 WholeTranslationState *state = 1014 new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, mode); 1015 1016 // Two translations when the request is split. 1017 DataTranslation<BaseDynInstPtr> *stransLow = 1018 new DataTranslation<BaseDynInstPtr>(this, state, 0); 1019 DataTranslation<BaseDynInstPtr> *stransHigh = 1020 new DataTranslation<BaseDynInstPtr>(this, state, 1); 1021 1022 cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode); 1023 cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode); |
1022 if (!translationCompleted) { | 1024 if (!translationCompleted()) { |
1023 // Save memory requests. 1024 savedReq = state->mainReq; 1025 savedSreqLow = state->sreqLow; 1026 savedSreqHigh = state->sreqHigh; 1027 } 1028 } 1029} 1030 1031template<class Impl> 1032inline void 1033BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state) 1034{ 1035 fault = state->getFault(); 1036 | 1025 // Save memory requests. 1026 savedReq = state->mainReq; 1027 savedSreqLow = state->sreqLow; 1028 savedSreqHigh = state->sreqHigh; 1029 } 1030 } 1031} 1032 1033template<class Impl> 1034inline void 1035BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state) 1036{ 1037 fault = state->getFault(); 1038 |
1037 if (state->isUncacheable()) 1038 isUncacheable = true; | 1039 instFlags[IsUncacheable] = state->isUncacheable(); |
1039 1040 if (fault == NoFault) { 1041 physEffAddr = state->getPaddr(); 1042 memReqFlags = state->getFlags(); 1043 1044 if (state->mainReq->isCondSwap()) { 1045 assert(state->res); 1046 state->mainReq->setExtraData(*state->res); 1047 } 1048 1049 } else { 1050 state->deleteReqs(); 1051 } 1052 delete state; 1053 | 1040 1041 if (fault == NoFault) { 1042 physEffAddr = state->getPaddr(); 1043 memReqFlags = state->getFlags(); 1044 1045 if (state->mainReq->isCondSwap()) { 1046 assert(state->res); 1047 state->mainReq->setExtraData(*state->res); 1048 } 1049 1050 } else { 1051 state->deleteReqs(); 1052 } 1053 delete state; 1054 |
1054 translationCompleted = true; | 1055 translationCompleted(true); |
1055} 1056 1057#endif // __CPU_BASE_DYN_INST_HH__ | 1056} 1057 1058#endif // __CPU_BASE_DYN_INST_HH__ |