00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef PPCTHREAD_H
00016 #define PPCTHREAD_H
00017
00018 #include "sst_stdint.h"
00019 #include "thread.h"
00020 #include "pool.h"
00021 #include "processor.h"
00022 #include <utility>
00023 #include <boost/serialization/set.hpp>
00024
00025 #include "loadInfo.h"
00026
00027
00028 #include "sst/core/component.h"
00029
00030 #include "regs.h"
00031
00032 #ifdef __APPLE__
00033 #include <architecture/ppc/cframe.h>
00034 #endif
00035
00036 static const unsigned int ppcMaxStackSize=32*1024;
00037
00038 #define ppcSimStackBase memory::segRange[GlobalDynamic][0]
00039 #define ppcInitStackBase memory::segRange[GlobalDynamic][0]+0x1000
00040 #define getStackIdx(SA) (SA - memory::segRange[GlobalDynamic][0])
00041
00042 instType classifyMask(const unsigned int mask);
00043
00044 const int altivecWordSize = 16;
00045 const int ppcRegSize = 32+64+(32*altivecWordSize);
00046
00047 class processor;
00048 class ppcThread;
00049
00050 typedef enum { SOFTWARE, CPLUSPLUS, ASM_PPC } fpu_mode_t;
00051
00052
00053
00054 class ppcInstruction : public instruction {
00055 friend class boost::serialization::access;
00056 template<class Archive>
00057 void serialize(Archive & ar, const unsigned int version )
00058 {
00059 boost::serialization::
00060 void_cast_register(static_cast<ppcInstruction*>(NULL),
00061 static_cast<instruction*>(NULL));
00062 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( instruction );
00063 ar & BOOST_SERIALIZATION_NVP(loadsAlwaysCheckFEB);
00064 ar & BOOST_SERIALIZATION_NVP(storesAlwaysSetFEB);
00065 ar & BOOST_SERIALIZATION_NVP(allowSelfModify);
00066 ar & BOOST_SERIALIZATION_NVP(totalCommitted);
00067 ar & BOOST_SERIALIZATION_NVP(parent);
00068 ar & BOOST_SERIALIZATION_NVP(magicStack);
00069 ar & BOOST_SERIALIZATION_NVP(fpu_mode);
00070 ar & BOOST_SERIALIZATION_NVP(fpu_mode_software);
00071 ar & BOOST_SERIALIZATION_NVP(fpu_mode_cplusplus);
00072 ar & BOOST_SERIALIZATION_NVP(fpu_mode_asm_ppc);
00073 ar & BOOST_SERIALIZATION_NVP(fpu_mode_asm_x86);
00074 ar & BOOST_SERIALIZATION_NVP(debugPrintFPSCR);
00075 ar & BOOST_SERIALIZATION_NVP(_NPC);
00076 ar & BOOST_SERIALIZATION_NVP(_TPC);
00077 ar & BOOST_SERIALIZATION_NVP(_fu);
00078 ar & BOOST_SERIALIZATION_NVP(_specificOp);
00079 ar & BOOST_SERIALIZATION_NVP(_ins);
00080 ar & BOOST_SERIALIZATION_NVP(_outs);
00081 ar & BOOST_SERIALIZATION_NVP(ProgramCounter);
00082 ar & BOOST_SERIALIZATION_NVP(_memEA);
00083 ar & BOOST_SERIALIZATION_NVP(_op);
00084 ar & BOOST_SERIALIZATION_NVP(_exception);
00085 ar & BOOST_SERIALIZATION_NVP(_moveToTarget);
00086 ar & BOOST_SERIALIZATION_NVP(_febTarget);
00087 ar & BOOST_SERIALIZATION_NVP(simOp);
00088 ar & BOOST_SERIALIZATION_NVP(invalid);
00089 ar & BOOST_SERIALIZATION_NVP(aCurrentInstruction);
00090 ar & BOOST_SERIALIZATION_NVP(_state);
00091 }
00092
00093 friend class ppcThread;
00094 static bool loadsAlwaysCheckFEB;
00095 static bool storesAlwaysSetFEB;
00096 static bool allowSelfModify;
00097 static unsigned totalCommitted;
00098
00099
00100
00101 ppcThread *parent;
00102
00103 static bool magicStack;
00104
00105
00106 static bool little_endian;
00107 static fpu_mode_t fpu_mode;
00108 static bool fpu_mode_software;
00109 static bool fpu_mode_cplusplus;
00110 static bool fpu_mode_asm_ppc;
00111 static bool fpu_mode_asm_x86;
00112
00113
00114
00115 static bool debugPrintFPSCR;
00116
00117
00118 void printRegs();
00119
00120 simRegister _NPC;
00121 simRegister _TPC;
00122
00123 int _fu;
00124 int _specificOp;
00125 static const int max_deps = 5;
00126 int _ins[max_deps+1];
00127 int _outs[max_deps+1];
00128
00129
00130 simRegister ProgramCounter;
00131
00132 simAddress _memEA;
00133
00134 instType _op;
00135
00136 exceptType _exception;
00137
00138 simAddress _moveToTarget;
00139
00140 simAddress _febTarget;
00141
00142
00143
00144
00145
00146 int simOp;
00147
00148
00149
00150 bool invalid;
00151
00152
00153 uint32_t aCurrentInstruction;
00154
00155 ppcInstruction(ppcThread*);
00156 static bool isStack(const simAddress s) {
00157
00158 if (magicStack) return (memory::getAccType(s) == GlobalDynamic);
00159 else return 0;
00160 }
00161 void issueSystemTrap(processor*, uint32_t *At);
00162 bool commitSystemTrap(processor*, uint32_t *At, simRegister &nextPC);
00163 #include "ppcSystemTrapHandler.h"
00164 instType getOp(const simAddress);
00165 string op_args(uint32_t, simRegister*, ppc_regs_t&) const;
00166 instState _state;
00167
00168 uint8_t CommitReadByte (simAddress sa, bool specRd, processor *proc);
00169 uint16_t CommitReadHalf (simAddress sa, bool specRd, processor *proc);
00170 uint32_t CommitReadWord (simAddress sa, bool specRd, processor *proc);
00171 uint64_t CommitReadDouble (simAddress sa, bool specRd, processor *proc);
00172
00173 bool CommitWriteByte (simAddress sa, uint8_t dd, bool specRd, processor *proc);
00174 bool CommitWriteHalf (simAddress sa, uint16_t dd, bool specRd, processor *proc);
00175 bool CommitWriteWord (simAddress sa, uint32_t dd, bool specRd, processor *proc);
00176 bool CommitWriteDouble (simAddress sa, uint64_t dd, bool specRd, processor *proc);
00177
00178 public:
00179 ppcInstruction() : parent(0) {;}
00180 virtual bool fetch(processor*);
00181 virtual bool issue(processor* p) {return issue(p,0);}
00182 virtual bool commit(processor* p) {return commit(p,0);}
00183
00184 virtual instState state() const {return _state;}
00185 virtual simAddress PC() const;
00186 virtual instType op() const;
00187 virtual simAddress memEA() const;
00188
00189 virtual exceptType exception() const {return _exception;};
00190
00191 virtual simAddress moveToTarget() const {return _moveToTarget;}
00192
00193 virtual simAddress febTarget() const {return _febTarget;}
00194
00195 virtual simRegister NPC() const {return _NPC;}
00196 virtual simRegister TPC() const {return _TPC;}
00197 virtual bool issue(processor *p, const bool s);
00198 virtual bool commit(processor *p, const bool s);
00199 virtual int fu() const {return _fu;}
00200 virtual int specificOp() const {return _specificOp;}
00201 virtual const int* outDeps() const {return _outs;}
00202 virtual const int* inDeps() const {return _ins;}
00203 virtual bool isReturn() const;
00204 virtual bool isBranchLink() const;
00205 virtual simPID pid() const;
00206 };
00207
00208 struct ppc_regs_t;
00209
00210
00211
00212
00213
00214
00215
00216 class ppcThread : public thread {
00217 friend class boost::serialization::access;
00218 template<class Archive>
00219 void serialize(Archive & ar, const unsigned int version )
00220 {
00221 boost::serialization::
00222 void_cast_register(static_cast<ppcThread*>(NULL),
00223 static_cast<thread*>(NULL));
00224 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(thread);
00225 ar & BOOST_SERIALIZATION_NVP(loadInfo);
00226 ar & BOOST_SERIALIZATION_NVP(Name);
00227 ar & BOOST_SERIALIZATION_NVP(ShouldExit);
00228 ar & BOOST_SERIALIZATION_NVP(threadIDMap);
00229 ar & BOOST_SERIALIZATION_NVP(nextThreadID);
00230 ar & BOOST_SERIALIZATION_NVP(exitSysCallExitsAll);
00231 ar & BOOST_SERIALIZATION_NVP(realGettimeofday);
00232 ar & BOOST_SERIALIZATION_NVP(verbose);
00233 ar & BOOST_SERIALIZATION_NVP(ThreadID);
00234 ar & BOOST_SERIALIZATION_NVP(isFuture);
00235 ar & BOOST_SERIALIZATION_NVP(SequenceNumber);
00236 ar & BOOST_SERIALIZATION_NVP(_pid);
00237 ar & BOOST_SERIALIZATION_NVP(iPool);
00238 ar & BOOST_SERIALIZATION_NVP(ProgramCounter);
00239 ar & BOOST_SERIALIZATION_NVP(setStack);
00240 ar & BOOST_SERIALIZATION_NVP(ppcRegisters);
00241 ar & BOOST_SERIALIZATION_NVP(specPPCRegisters);
00242 ar & BOOST_SERIALIZATION_NVP(packagedRegisters);
00243 ar & BOOST_SERIALIZATION_NVP(outstandingInsts);
00244 ar & BOOST_SERIALIZATION_NVP(condemnedInsts);
00245 ar & BOOST_SERIALIZATION_NVP(registers);
00246 ar & BOOST_SERIALIZATION_NVP(home);
00247 ar & BOOST_SERIALIZATION_NVP(yieldCount);
00248 ar & BOOST_SERIALIZATION_NVP(myFrame);
00249 }
00250
00251 LoadInfo loadInfo;
00252
00253 string Name;
00254 bool ShouldExit;
00255 friend class ppcInstruction;
00256 friend class ppcLoader;
00257 static const bool usingMagicStack() {return ppcInstruction::magicStack;}
00258 static map<uint32_t, ppcThread*> threadIDMap;
00259 static unsigned int nextThreadID;
00260 static bool exitSysCallExitsAll;
00261
00262 static bool realGettimeofday;
00263
00264 static int verbose;
00265 simAddress ThreadID;
00266 bool isFuture;
00267 uint32_t SequenceNumber;
00268 simPID _pid;
00269
00270 static pool<ppcInstruction> iPool;
00271
00272
00273
00274 typedef pair<simAddress, simPID> addrPair;
00275 typedef map<addrPair, ppcThread*> reservedSetT;
00276 static reservedSetT reservedSet;
00277
00278 simRegister ProgramCounter;
00279 bool setStack;
00280
00281 ppc_regs_t *ppcRegisters;
00282 ppc_regs_t *specPPCRegisters;
00283
00284
00285
00286
00287
00288
00289
00290 simRegister packagedRegisters[ppcRegSize];
00291
00292 #if 0
00293
00294
00295
00296
00297
00298
00299 static uint32_t PageSize;
00300
00301 static uint32_t PageShift;
00302
00303 static uint32_t PageMask;
00304 static uint8_t *GetTextPage (const simAddress sa);
00305 #endif
00306
00307 typedef deque<ppcInstruction*> instList;
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 instList outstandingInsts;
00319 set<ppcInstruction*> condemnedInsts;
00320 uint numOutstanding() const {return outstandingInsts.size();}
00321 instList &getOutstandingInsts() {return outstandingInsts;}
00322
00323 frameID registers;
00324
00325
00326
00327 processor *home;
00328
00329 int yieldCount;
00330
00331
00332 simRegister myFrame[ppcRegSize];
00333
00334 simRegister *getRegisters() {return myFrame;}
00335 simRegister *getSpecRegisters() {return packagedRegisters;}
00336
00337
00338
00339
00340
00341 bool CopyToSIM(simAddress dest, void* source, const unsigned int Bytes);
00342
00343
00344
00345
00346
00347 bool CopyFromSIM(void* dest, const simAddress source, const unsigned int Bytes);
00348
00349 uint8_t getSpecStackByte(const simAddress sa) {
00350 map<simAddress, uint8_t>::iterator i = specStackData.find(sa);
00351 if (i != specStackData.end()) {
00352 return i->second;
00353 } else {
00354 simAddress s2 = getStackIdx(sa);
00355 if (s2 <= ppcMaxStackSize) {
00356 return stackData[s2];
00357 } else {
00358 return 0;
00359 }
00360 }
00361 }
00362
00363 void writeSpecStackByte(const simAddress sa, const uint8_t Data) {
00364 specStackData[sa] = Data;
00365 }
00366
00367
00368 uint8_t readStack8(const simAddress sa, const bool isSpec) {
00369 if (isSpec) {
00370 return getSpecStackByte(sa);
00371 } else {
00372 simAddress s2 = getStackIdx(sa);
00373 return stackData[s2];
00374 }
00375 }
00376
00377 uint16_t readStack16(const simAddress sa, const bool isSpec) {
00378 if (isSpec) {
00379 uint16_t r = (getSpecStackByte(sa) << 8);
00380 r += getSpecStackByte(sa+1);
00381 return r;
00382 } else {
00383 simAddress s2 = getStackIdx(sa);
00384 uint16_t *t = (uint16_t*)&stackData[s2];
00385 return (uint16_t)(*t);
00386 }
00387 }
00388
00389 uint32_t readStack32(const simAddress sa, const bool isSpec) {
00390 if (isSpec) {
00391 uint32_t r = (getSpecStackByte(sa) << 24);
00392 r += getSpecStackByte(sa+1) << 16;
00393 r += getSpecStackByte(sa+2) << 8;
00394 r += getSpecStackByte(sa+3);
00395 return r;
00396 } else {
00397 simAddress s2 = getStackIdx(sa);
00398 if (s2 >= ppcMaxStackSize) {
00399 printf("overstack %p %d > %d\n",
00400 (void*)(size_t)sa,s2,ppcMaxStackSize);
00401 }
00402 uint32_t *t = (uint32_t*)&stackData[s2];
00403 return (uint32_t)(*t);
00404 }
00405 }
00406 bool writeStack8(const simAddress, const uint8_t, const bool isSpec);
00407 bool writeStack16(const simAddress, const uint16_t, const bool isSpec);
00408 bool writeStack32(const simAddress, const uint32_t, const bool isSpec);
00409
00410 typedef pair<simAddress,simAddress> adrRange;
00411 static vector<adrRange> constData;
00412
00413 public:
00414 static vector<thread*> init(processor *p, SST::Component::Params_t& paramsC);
00415 static void deleteThread(thread *t);
00416 #if 0
00417 static bool WriteTextByte(simAddress bDestination, uint8_t Byte);
00418 static uint32_t ReadTextWord(const simAddress bDestination);
00419 #endif
00420
00421 ppcThread( processor* hme, simPID, string name = "");
00422 ppcThread() {;}
00423 virtual ~ppcThread();
00424
00425 simRegister GetProgramCounter() {return(ProgramCounter);}
00426
00427 uint8_t stackData[ppcMaxStackSize];
00428
00429 map<simAddress, uint8_t> specStackData;
00430
00431 #if 0
00432
00433 static uint8_t *progText;
00434 static simAddress lastTextAddr;
00435 static vector<simAddress> textRanges;
00436 #endif
00437
00438 static bool isText (simAddress addr) {
00439 #if 1
00440 return true;
00441 #else
00442 if (addr > lastTextAddr)
00443 return false;
00444
00445 int ranges = textRanges.size() >> 1;
00446 for (int i = 0; i < ranges; i += 2) {
00447 if ((addr >= textRanges[i]) && (addr < textRanges[i+1]))
00448 return true;
00449 }
00450 return false;
00451 #endif
00452 }
00453
00454 #if 0
00455 static bool writeText (simAddress addr, uint8_t *data, unsigned int size) {
00456 if (lastTextAddr < (addr + size)) {
00457 lastTextAddr = addr + size;
00458 progText = (uint8_t*)realloc(progText, lastTextAddr);
00459 }
00460 textRanges.push_back(addr);
00461 textRanges.push_back(addr + size);
00462
00463 for (int i = 0; i < size; i++) {
00464 progText[i+addr] = data[i];
00465 }
00466 return true;
00467 }
00468 static bool readText (simAddress addr, uint8_t *buffer, unsigned int size) {
00469 if (addr > lastTextAddr)
00470 return false;
00471 for (int i = 0; i < size; i++) {
00472 buffer[i] = progText[addr+i];
00473 }
00474 return true;
00475 }
00476 #endif
00477
00478 virtual instruction* getNextInstruction();
00479 virtual bool squash(instruction * i);
00480 virtual bool retire(instruction *);
00481 virtual void assimilate(processor *);
00482 virtual void packageToSend(processor *);
00483
00484 virtual simAddress getStartPC();
00485 virtual bool isPCValid(const simAddress);
00486 virtual instruction* getNextInstruction(const simAddress);
00487 virtual void squashSpec();
00488 virtual void prepareSpec();
00489 virtual bool condemn(instruction*);
00490 simPID pid() const {return _pid;};
00491 virtual void changePid(const simPID p){ _pid = p;}
00492 int getInstructionSize() {return 4;}
00493
00494 simRegister getStack() const {
00495 if (home) {
00496 return myFrame[1];
00497 } else {
00498 return packagedRegisters[1];
00499 }
00500 }
00501
00502 bool isConstSection(const simAddress, const simPID) const;
00503 };
00504
00505 #endif