base_dyn_inst.hh (13557:fc33e6048b25) | base_dyn_inst.hh (13590:d7e018859709) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2011,2013,2016 ARM Limited | 2 * Copyright (c) 2011, 2013, 2016-2018 ARM Limited |
3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license --- 68 unchanged lines hidden (view full) --- 79class BaseDynInst : public ExecContext, public RefCounted 80{ 81 public: 82 // Typedef for the CPU. 83 typedef typename Impl::CPUType ImplCPU; 84 typedef typename ImplCPU::ImplState ImplState; 85 using VecRegContainer = TheISA::VecRegContainer; 86 | 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license --- 68 unchanged lines hidden (view full) --- 79class BaseDynInst : public ExecContext, public RefCounted 80{ 81 public: 82 // Typedef for the CPU. 83 typedef typename Impl::CPUType ImplCPU; 84 typedef typename ImplCPU::ImplState ImplState; 85 using VecRegContainer = TheISA::VecRegContainer; 86 |
87 using LSQRequestPtr = typename Impl::CPUPol::LSQ::LSQRequest*; 88 using LQIterator = typename Impl::CPUPol::LSQUnit::LQIterator; 89 using SQIterator = typename Impl::CPUPol::LSQUnit::SQIterator; 90 |
|
87 // The DynInstPtr type. 88 typedef typename Impl::DynInstPtr DynInstPtr; 89 typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr; 90 91 // The list of instructions iterator type. 92 typedef typename std::list<DynInstPtr>::iterator ListIt; 93 94 enum { --- 103 unchanged lines hidden (view full) --- 198 uint8_t readyRegs; 199 200 public: 201 /////////////////////// Load Store Data ////////////////////// 202 /** The effective virtual address (lds & stores only). */ 203 Addr effAddr; 204 205 /** The effective physical address. */ | 91 // The DynInstPtr type. 92 typedef typename Impl::DynInstPtr DynInstPtr; 93 typedef RefCountingPtr<BaseDynInst<Impl> > BaseDynInstPtr; 94 95 // The list of instructions iterator type. 96 typedef typename std::list<DynInstPtr>::iterator ListIt; 97 98 enum { --- 103 unchanged lines hidden (view full) --- 202 uint8_t readyRegs; 203 204 public: 205 /////////////////////// Load Store Data ////////////////////// 206 /** The effective virtual address (lds & stores only). */ 207 Addr effAddr; 208 209 /** The effective physical address. */ |
206 Addr physEffAddrLow; | 210 Addr physEffAddr; |
207 | 211 |
208 /** The effective physical address 209 * of the second request for a split request 210 */ 211 Addr physEffAddrHigh; 212 | |
213 /** The memory request flags (from translation). */ 214 unsigned memReqFlags; 215 216 /** data address space ID, for loads & stores. */ 217 short asid; 218 219 /** The size of the request */ 220 uint8_t effSize; 221 222 /** Pointer to the data for the memory access. */ 223 uint8_t *memData; 224 225 /** Load queue index. */ 226 int16_t lqIdx; | 212 /** The memory request flags (from translation). */ 213 unsigned memReqFlags; 214 215 /** data address space ID, for loads & stores. */ 216 short asid; 217 218 /** The size of the request */ 219 uint8_t effSize; 220 221 /** Pointer to the data for the memory access. */ 222 uint8_t *memData; 223 224 /** Load queue index. */ 225 int16_t lqIdx; |
226 LQIterator lqIt; |
|
227 228 /** Store queue index. */ 229 int16_t sqIdx; | 227 228 /** Store queue index. */ 229 int16_t sqIdx; |
230 SQIterator sqIt; |
|
230 231 232 /////////////////////// TLB Miss ////////////////////// 233 /** | 231 232 233 /////////////////////// TLB Miss ////////////////////// 234 /** |
234 * Saved memory requests (needed when the DTB address translation is | 235 * Saved memory request (needed when the DTB address translation is |
235 * delayed due to a hw page table walk). 236 */ | 236 * delayed due to a hw page table walk). 237 */ |
237 RequestPtr savedReq; 238 RequestPtr savedSreqLow; 239 RequestPtr savedSreqHigh; | 238 LSQRequestPtr savedReq; |
240 241 /////////////////////// Checker ////////////////////// 242 // Need a copy of main request pointer to verify on writes. 243 RequestPtr reqToVerify; 244 245 protected: 246 /** Flattened register index of the destination registers of this 247 * instruction. --- 17 unchanged lines hidden (view full) --- 265 266 267 public: 268 /** Records changes to result? */ 269 void recordResult(bool f) { instFlags[RecordResult] = f; } 270 271 /** Is the effective virtual address valid. */ 272 bool effAddrValid() const { return instFlags[EffAddrValid]; } | 239 240 /////////////////////// Checker ////////////////////// 241 // Need a copy of main request pointer to verify on writes. 242 RequestPtr reqToVerify; 243 244 protected: 245 /** Flattened register index of the destination registers of this 246 * instruction. --- 17 unchanged lines hidden (view full) --- 264 265 266 public: 267 /** Records changes to result? */ 268 void recordResult(bool f) { instFlags[RecordResult] = f; } 269 270 /** Is the effective virtual address valid. */ 271 bool effAddrValid() const { return instFlags[EffAddrValid]; } |
272 void effAddrValid(bool b) { instFlags[EffAddrValid] = b; } |
|
273 274 /** Whether or not the memory operation is done. */ 275 bool memOpDone() const { return instFlags[MemOpDone]; } 276 void memOpDone(bool f) { instFlags[MemOpDone] = f; } 277 278 bool notAnInst() const { return instFlags[NotAnInst]; } 279 void setNotAnInst() { instFlags[NotAnInst] = true; } 280 --- 17 unchanged lines hidden (view full) --- 298 cpu->demapPage(vaddr, asn); 299 } 300 301 Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags); 302 303 Fault writeMem(uint8_t *data, unsigned size, Addr addr, 304 Request::Flags flags, uint64_t *res); 305 | 273 274 /** Whether or not the memory operation is done. */ 275 bool memOpDone() const { return instFlags[MemOpDone]; } 276 void memOpDone(bool f) { instFlags[MemOpDone] = f; } 277 278 bool notAnInst() const { return instFlags[NotAnInst]; } 279 void setNotAnInst() { instFlags[NotAnInst] = true; } 280 --- 17 unchanged lines hidden (view full) --- 298 cpu->demapPage(vaddr, asn); 299 } 300 301 Fault initiateMemRead(Addr addr, unsigned size, Request::Flags flags); 302 303 Fault writeMem(uint8_t *data, unsigned size, Addr addr, 304 Request::Flags flags, uint64_t *res); 305 |
306 /** Splits a request in two if it crosses a dcache block. */ 307 void splitRequest(const RequestPtr &req, RequestPtr &sreqLow, 308 RequestPtr &sreqHigh); 309 310 /** Initiate a DTB address translation. */ 311 void initiateTranslation(const RequestPtr &req, const RequestPtr &sreqLow, 312 const RequestPtr &sreqHigh, uint64_t *res, 313 BaseTLB::Mode mode); 314 315 /** Finish a DTB address translation. */ 316 void finishTranslation(WholeTranslationState *state); 317 | |
318 /** True if the DTB address translation has started. */ 319 bool translationStarted() const { return instFlags[TranslationStarted]; } 320 void translationStarted(bool f) { instFlags[TranslationStarted] = f; } 321 322 /** True if the DTB address translation has completed. */ 323 bool translationCompleted() const { return instFlags[TranslationCompleted]; } 324 void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; } 325 --- 123 unchanged lines hidden (view full) --- 449 /** Read this CPU's data requestor ID */ 450 MasterID masterId() const { return cpu->dataMasterId(); } 451 452 /** Read this context's system-wide ID **/ 453 ContextID contextId() const { return thread->contextId(); } 454 455 /** Returns the fault type. */ 456 Fault getFault() const { return fault; } | 306 /** True if the DTB address translation has started. */ 307 bool translationStarted() const { return instFlags[TranslationStarted]; } 308 void translationStarted(bool f) { instFlags[TranslationStarted] = f; } 309 310 /** True if the DTB address translation has completed. */ 311 bool translationCompleted() const { return instFlags[TranslationCompleted]; } 312 void translationCompleted(bool f) { instFlags[TranslationCompleted] = f; } 313 --- 123 unchanged lines hidden (view full) --- 437 /** Read this CPU's data requestor ID */ 438 MasterID masterId() const { return cpu->dataMasterId(); } 439 440 /** Read this context's system-wide ID **/ 441 ContextID contextId() const { return thread->contextId(); } 442 443 /** Returns the fault type. */ 444 Fault getFault() const { return fault; } |
445 /** TODO: This I added for the LSQRequest side to be able to modify the 446 * fault. There should be a better mechanism in place. */ 447 Fault& getFault() { return fault; } |
|
457 458 /** Checks whether or not this instruction has had its branch target 459 * calculated yet. For now it is not utilized and is hacked to be 460 * always false. 461 * @todo: Actually use this instruction. 462 */ 463 bool doneTargCalc() { return false; } 464 --- 119 unchanged lines hidden (view full) --- 584 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 585 586 // the following are used to track physical register usage 587 // for machines with separate int & FP reg files 588 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 589 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 590 int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } 591 int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); } | 448 449 /** Checks whether or not this instruction has had its branch target 450 * calculated yet. For now it is not utilized and is hacked to be 451 * always false. 452 * @todo: Actually use this instruction. 453 */ 454 bool doneTargCalc() { return false; } 455 --- 119 unchanged lines hidden (view full) --- 575 int8_t numDestRegs() const { return staticInst->numDestRegs(); } 576 577 // the following are used to track physical register usage 578 // for machines with separate int & FP reg files 579 int8_t numFPDestRegs() const { return staticInst->numFPDestRegs(); } 580 int8_t numIntDestRegs() const { return staticInst->numIntDestRegs(); } 581 int8_t numCCDestRegs() const { return staticInst->numCCDestRegs(); } 582 int8_t numVecDestRegs() const { return staticInst->numVecDestRegs(); } |
592 int8_t numVecElemDestRegs() const { | 583 int8_t numVecElemDestRegs() const 584 { |
593 return staticInst->numVecElemDestRegs(); 594 } 595 596 /** Returns the logical register index of the i'th destination register. */ 597 const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); } 598 599 /** Returns the logical register index of the i'th source register. */ 600 const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } --- 231 unchanged lines hidden (view full) --- 832 833 if (traceData) { 834 traceData->setPredicate(val); 835 } 836 } 837 838 /** Sets the ASID. */ 839 void setASID(short addr_space_id) { asid = addr_space_id; } | 585 return staticInst->numVecElemDestRegs(); 586 } 587 588 /** Returns the logical register index of the i'th destination register. */ 589 const RegId& destRegIdx(int i) const { return staticInst->destRegIdx(i); } 590 591 /** Returns the logical register index of the i'th source register. */ 592 const RegId& srcRegIdx(int i) const { return staticInst->srcRegIdx(i); } --- 231 unchanged lines hidden (view full) --- 824 825 if (traceData) { 826 traceData->setPredicate(val); 827 } 828 } 829 830 /** Sets the ASID. */ 831 void setASID(short addr_space_id) { asid = addr_space_id; } |
832 short getASID() { return asid; } |
|
840 841 /** Sets the thread id. */ 842 void setTid(ThreadID tid) { threadNumber = tid; } 843 844 /** Sets the pointer to the thread state. */ 845 void setThreadState(ImplState *state) { thread = state; } 846 847 /** Returns the thread context. */ 848 ThreadContext *tcBase() { return thread->getTC(); } 849 850 public: 851 /** Returns whether or not the eff. addr. source registers are ready. */ 852 bool eaSrcsReady() const; 853 854 /** Is this instruction's memory access strictly ordered? */ 855 bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; } | 833 834 /** Sets the thread id. */ 835 void setTid(ThreadID tid) { threadNumber = tid; } 836 837 /** Sets the pointer to the thread state. */ 838 void setThreadState(ImplState *state) { thread = state; } 839 840 /** Returns the thread context. */ 841 ThreadContext *tcBase() { return thread->getTC(); } 842 843 public: 844 /** Returns whether or not the eff. addr. source registers are ready. */ 845 bool eaSrcsReady() const; 846 847 /** Is this instruction's memory access strictly ordered? */ 848 bool strictlyOrdered() const { return instFlags[IsStrictlyOrdered]; } |
849 void strictlyOrdered(bool so) { instFlags[IsStrictlyOrdered] = so; } |
|
856 857 /** Has this instruction generated a memory request. */ 858 bool hasRequest() const { return instFlags[ReqMade]; } | 850 851 /** Has this instruction generated a memory request. */ 852 bool hasRequest() const { return instFlags[ReqMade]; } |
853 /** Assert this instruction has generated a memory request. */ 854 void setRequest() { instFlags[ReqMade] = true; } |
|
859 860 /** Returns iterator to this instruction in the list of all insts. */ 861 ListIt &getInstListIt() { return instListIt; } 862 863 /** Sets iterator for this instruction in the list of all insts. */ 864 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 865 866 public: --- 15 unchanged lines hidden (view full) --- 882 { return cpu->getCpuAddrMonitor(threadNumber); } 883}; 884 885template<class Impl> 886Fault 887BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size, 888 Request::Flags flags) 889{ | 855 856 /** Returns iterator to this instruction in the list of all insts. */ 857 ListIt &getInstListIt() { return instListIt; } 858 859 /** Sets iterator for this instruction in the list of all insts. */ 860 void setInstListIt(ListIt _instListIt) { instListIt = _instListIt; } 861 862 public: --- 15 unchanged lines hidden (view full) --- 878 { return cpu->getCpuAddrMonitor(threadNumber); } 879}; 880 881template<class Impl> 882Fault 883BaseDynInst<Impl>::initiateMemRead(Addr addr, unsigned size, 884 Request::Flags flags) 885{ |
890 instFlags[ReqMade] = true; 891 RequestPtr req = NULL; 892 RequestPtr sreqLow = NULL; 893 RequestPtr sreqHigh = NULL; 894 895 if (instFlags[ReqMade] && translationStarted()) { 896 req = savedReq; 897 sreqLow = savedSreqLow; 898 sreqHigh = savedSreqHigh; 899 } else { 900 req = std::make_shared<Request>( 901 asid, addr, size, flags, masterId(), 902 this->pc.instAddr(), thread->contextId()); 903 904 req->taskId(cpu->taskId()); 905 906 // Only split the request if the ISA supports unaligned accesses. 907 if (TheISA::HasUnalignedMemAcc) { 908 splitRequest(req, sreqLow, sreqHigh); 909 } 910 initiateTranslation(req, sreqLow, sreqHigh, NULL, BaseTLB::Read); 911 } 912 913 if (translationCompleted()) { 914 if (fault == NoFault) { 915 effAddr = req->getVaddr(); 916 effSize = size; 917 instFlags[EffAddrValid] = true; 918 919 if (cpu->checker) { 920 reqToVerify = std::make_shared<Request>(*req); 921 } 922 fault = cpu->read(req, sreqLow, sreqHigh, lqIdx); 923 } else { 924 // Commit will have to clean up whatever happened. Set this 925 // instruction as executed. 926 this->setExecuted(); 927 } 928 } 929 930 if (traceData) 931 traceData->setMem(addr, size, flags); 932 933 return fault; | 886 return cpu->pushRequest( 887 dynamic_cast<typename DynInstPtr::PtrType>(this), 888 /* ld */ true, nullptr, size, addr, flags, nullptr); |
934} 935 936template<class Impl> 937Fault 938BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, Addr addr, 939 Request::Flags flags, uint64_t *res) 940{ | 889} 890 891template<class Impl> 892Fault 893BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size, Addr addr, 894 Request::Flags flags, uint64_t *res) 895{ |
941 if (traceData) 942 traceData->setMem(addr, size, flags); 943 944 instFlags[ReqMade] = true; 945 RequestPtr req = NULL; 946 RequestPtr sreqLow = NULL; 947 RequestPtr sreqHigh = NULL; 948 949 if (instFlags[ReqMade] && translationStarted()) { 950 req = savedReq; 951 sreqLow = savedSreqLow; 952 sreqHigh = savedSreqHigh; 953 } else { 954 req = std::make_shared<Request>( 955 asid, addr, size, flags, masterId(), 956 this->pc.instAddr(), thread->contextId()); 957 958 req->taskId(cpu->taskId()); 959 960 // Only split the request if the ISA supports unaligned accesses. 961 if (TheISA::HasUnalignedMemAcc) { 962 splitRequest(req, sreqLow, sreqHigh); 963 } 964 initiateTranslation(req, sreqLow, sreqHigh, res, BaseTLB::Write); 965 } 966 967 if (fault == NoFault && translationCompleted()) { 968 effAddr = req->getVaddr(); 969 effSize = size; 970 instFlags[EffAddrValid] = true; 971 972 if (cpu->checker) { 973 reqToVerify = std::make_shared<Request>(*req); 974 } 975 fault = cpu->write(req, sreqLow, sreqHigh, data, sqIdx); 976 } 977 978 return fault; | 896 return cpu->pushRequest( 897 dynamic_cast<typename DynInstPtr::PtrType>(this), 898 /* st */ false, data, size, addr, flags, res); |
979} 980 | 899} 900 |
981template<class Impl> 982inline void 983BaseDynInst<Impl>::splitRequest(const RequestPtr &req, RequestPtr &sreqLow, 984 RequestPtr &sreqHigh) 985{ 986 // Check to see if the request crosses the next level block boundary. 987 unsigned block_size = cpu->cacheLineSize(); 988 Addr addr = req->getVaddr(); 989 Addr split_addr = roundDown(addr + req->getSize() - 1, block_size); 990 assert(split_addr <= addr || split_addr - addr < block_size); 991 992 // Spans two blocks. 993 if (split_addr > addr) { 994 req->splitOnVaddr(split_addr, sreqLow, sreqHigh); 995 } 996} 997 998template<class Impl> 999inline void 1000BaseDynInst<Impl>::initiateTranslation(const RequestPtr &req, 1001 const RequestPtr &sreqLow, 1002 const RequestPtr &sreqHigh, 1003 uint64_t *res, 1004 BaseTLB::Mode mode) 1005{ 1006 translationStarted(true); 1007 1008 if (!TheISA::HasUnalignedMemAcc || sreqLow == NULL) { 1009 WholeTranslationState *state = 1010 new WholeTranslationState(req, NULL, res, mode); 1011 1012 // One translation if the request isn't split. 1013 DataTranslation<BaseDynInstPtr> *trans = 1014 new DataTranslation<BaseDynInstPtr>(this, state); 1015 1016 cpu->dtb->translateTiming(req, thread->getTC(), trans, mode); 1017 1018 if (!translationCompleted()) { 1019 // The translation isn't yet complete, so we can't possibly have a 1020 // fault. Overwrite any existing fault we might have from a previous 1021 // execution of this instruction (e.g. an uncachable load that 1022 // couldn't execute because it wasn't at the head of the ROB). 1023 fault = NoFault; 1024 1025 // Save memory requests. 1026 savedReq = state->mainReq; 1027 savedSreqLow = state->sreqLow; 1028 savedSreqHigh = state->sreqHigh; 1029 } 1030 } else { 1031 WholeTranslationState *state = 1032 new WholeTranslationState(req, sreqLow, sreqHigh, NULL, res, mode); 1033 1034 // Two translations when the request is split. 1035 DataTranslation<BaseDynInstPtr> *stransLow = 1036 new DataTranslation<BaseDynInstPtr>(this, state, 0); 1037 DataTranslation<BaseDynInstPtr> *stransHigh = 1038 new DataTranslation<BaseDynInstPtr>(this, state, 1); 1039 1040 cpu->dtb->translateTiming(sreqLow, thread->getTC(), stransLow, mode); 1041 cpu->dtb->translateTiming(sreqHigh, thread->getTC(), stransHigh, mode); 1042 1043 if (!translationCompleted()) { 1044 // The translation isn't yet complete, so we can't possibly have a 1045 // fault. Overwrite any existing fault we might have from a previous 1046 // execution of this instruction (e.g. an uncachable load that 1047 // couldn't execute because it wasn't at the head of the ROB). 1048 fault = NoFault; 1049 1050 // Save memory requests. 1051 savedReq = state->mainReq; 1052 savedSreqLow = state->sreqLow; 1053 savedSreqHigh = state->sreqHigh; 1054 } 1055 } 1056} 1057 1058template<class Impl> 1059inline void 1060BaseDynInst<Impl>::finishTranslation(WholeTranslationState *state) 1061{ 1062 fault = state->getFault(); 1063 1064 instFlags[IsStrictlyOrdered] = state->isStrictlyOrdered(); 1065 1066 if (fault == NoFault) { 1067 // save Paddr for a single req 1068 physEffAddrLow = state->getPaddr(); 1069 1070 // case for the request that has been split 1071 if (state->isSplit) { 1072 physEffAddrLow = state->sreqLow->getPaddr(); 1073 physEffAddrHigh = state->sreqHigh->getPaddr(); 1074 } 1075 1076 memReqFlags = state->getFlags(); 1077 1078 if (state->mainReq->isCondSwap()) { 1079 assert(state->res); 1080 state->mainReq->setExtraData(*state->res); 1081 } 1082 1083 } else { 1084 state->deleteReqs(); 1085 } 1086 delete state; 1087 1088 translationCompleted(true); 1089} 1090 | |
1091#endif // __CPU_BASE_DYN_INST_HH__ | 901#endif // __CPU_BASE_DYN_INST_HH__ |