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 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 }; |
109 |
110 protected: |
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 |
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 }; |
155 |
156 public: 157 /** The sequence number of the instruction. */ 158 InstSeqNum seqNum; |
159 |
160 /** The StaticInst used by this BaseDynInst. */ 161 StaticInstPtr staticInst; |
162 |
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 |
172 /** InstRecord that tracks this instructions. */ 173 Trace::InstRecord *traceData; |
174 |
175 protected: 176 /** The result of the instruction; assumes an instruction can have many 177 * destination registers. 178 */ 179 std::queue<Result> instResult; |
180 |
181 /** PC state for this instruction. */ 182 TheISA::PCState pc; |
183 |
184 /* An amalgamation of a lot of boolean values into one */ 185 std::bitset<MaxFlags> instFlags; |
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 |
217 /** The effective physical address. */ 218 Addr physEffAddr; 219 220 /** The memory request flags (from translation). */ 221 unsigned memReqFlags; 222 |
223 /** data address space ID, for loads & stores. */ 224 short asid; |
225 |
226 /** The size of the request */ 227 uint8_t effSize; |
228 |
229 /** Pointer to the data for the memory access. */ 230 uint8_t *memData; |
231 |
232 /** Load queue index. */ 233 int16_t lqIdx; |
234 |
235 /** Store queue index. */ 236 int16_t sqIdx; |
237 |
238 |
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; |
247 |
248 /////////////////////// Checker ////////////////////// 249 // Need a copy of main request pointer to verify on writes. 250 RequestPtr reqToVerify; |
251 |
252 private: 253 /** Instruction effective address. 254 * @todo: Consider if this is necessary or not. |
255 */ |
256 Addr instEffAddr; |
257 258 protected: 259 /** Flattened register index of the destination registers of this 260 * instruction. 261 */ 262 TheISA::RegIndex _flatDestRegIdx[TheISA::MaxInstDestRegs]; 263 |
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 |
280 public: |
281 /** Records changes to result? */ 282 void recordResult(bool f) { instFlags[RecordResult] = f; } |
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 |
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); |
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 |
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 |
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 { |
492 return instFlags[PredTaken]; |
493 } 494 495 void setPredTaken(bool predicted_taken) 496 { |
497 instFlags[PredTaken] = predicted_taken; |
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 { |
623 if (instFlags[RecordResult]) { |
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 { |
809 return instFlags[Predicate]; |
810 } 811 812 void setPredicate(bool val) 813 { |
814 instFlags[Predicate] = val; |
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 |
833 public: 834 /** Sets the effective address. */ |
835 void setEA(Addr &ea) { instEffAddr = ea; instFlags[EACalcDone] = true; } |
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. */ |
841 bool doneEACalc() { return instFlags[EACalcDone]; } |
842 843 /** Returns whether or not the eff. addr. source registers are ready. */ 844 bool eaSrcsReady(); 845 |
846 /** Is this instruction's memory access uncacheable. */ |
847 bool uncacheable() { return instFlags[IsUncacheable]; } |
848 849 /** Has this instruction generated a memory request. */ |
850 bool hasRequest() { return instFlags[ReqMade]; } |
851 |
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{ |
873 instFlags[ReqMade] = true; |
874 Request *req = NULL; 875 Request *sreqLow = NULL; 876 Request *sreqHigh = NULL; 877 |
878 if (instFlags[ReqMade] && translationStarted()) { |
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 |
893 if (translationCompleted()) { |
894 if (fault == NoFault) { 895 effAddr = req->getVaddr(); 896 effSize = size; |
897 instFlags[EffAddrValid] = true; |
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 |
936 instFlags[ReqMade] = true; |
937 Request *req = NULL; 938 Request *sreqLow = NULL; 939 Request *sreqHigh = NULL; 940 |
941 if (instFlags[ReqMade] && translationStarted()) { |
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 |
956 if (fault == NoFault && translationCompleted()) { |
957 effAddr = req->getVaddr(); 958 effSize = size; |
959 instFlags[EffAddrValid] = true; |
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{ |
996 translationStarted(true); |
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); |
1006 if (!translationCompleted()) { |
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); |
1024 if (!translationCompleted()) { |
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 |
1039 instFlags[IsUncacheable] = state->isUncacheable(); |
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 |
1055 translationCompleted(true); |
1056} 1057 1058#endif // __CPU_BASE_DYN_INST_HH__ |