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
00156 double ReadMemoryDouble(simAddress addr, processor *proc) {
00157 qword_t qw = proc->ReadMemory64(addr,0);
00158 qw = endian_swap(qw);
00159 double out;
00160 memcpy(&out, &qw, sizeof(double));
00161 return out;
00162 }
00163
00164
00165 void WriteMemoryDouble(simAddress addr, processor *proc, double val) {
00166 qword_t valWord;
00167 memcpy(&valWord, &val, sizeof(qword_t));
00168 proc->WriteMemory64(addr, endian_swap(valWord), 0);
00169 }
00170
00171 ppcInstruction(ppcThread*);
00172 static bool isStack(const simAddress s) {
00173
00174 if (magicStack) return (memory::getAccType(s) == GlobalDynamic);
00175 else return 0;
00176 }
00177 void issueSystemTrap(processor*, uint32_t *At);
00178 bool commitSystemTrap(processor*, uint32_t *At, simRegister &nextPC);
00179 #include "ppcSystemTrapHandler.h"
00180 instType getOp(const simAddress);
00181 string op_args(uint32_t, simRegister*, ppc_regs_t&) const;
00182 instState _state;
00183
00184 uint8_t CommitReadByte (simAddress sa, bool specRd, processor *proc);
00185 uint16_t CommitReadHalf (simAddress sa, bool specRd, processor *proc);
00186 uint32_t CommitReadWord (simAddress sa, bool specRd, processor *proc);
00187 uint64_t CommitReadDouble (simAddress sa, bool specRd, processor *proc);
00188
00189 bool CommitWriteByte (simAddress sa, uint8_t dd, bool specRd, processor *proc);
00190 bool CommitWriteHalf (simAddress sa, uint16_t dd, bool specRd, processor *proc);
00191 bool CommitWriteWord (simAddress sa, uint32_t dd, bool specRd, processor *proc);
00192 bool CommitWriteDouble (simAddress sa, uint64_t dd, bool specRd, processor *proc);
00193
00194 public:
00195 ppcInstruction() : parent(0) {;}
00196 virtual bool fetch(processor*);
00197 virtual bool issue(processor* p) {return issue(p,0);}
00198 virtual bool commit(processor* p) {return commit(p,0);}
00199
00200 virtual instState state() const {return _state;}
00201 virtual simAddress PC() const;
00202 virtual instType op() const;
00203 virtual simAddress memEA() const;
00204
00205 virtual exceptType exception() const {return _exception;};
00206
00207 virtual simAddress moveToTarget() const {return _moveToTarget;}
00208
00209 virtual simAddress febTarget() const {return _febTarget;}
00210
00211 virtual simRegister NPC() const {return _NPC;}
00212 virtual simRegister TPC() const {return _TPC;}
00213 virtual bool issue(processor *p, const bool s);
00214 virtual bool commit(processor *p, const bool s);
00215 virtual int fu() const {return _fu;}
00216 virtual int specificOp() const {return _specificOp;}
00217 virtual const int* outDeps() const {return _outs;}
00218 virtual const int* inDeps() const {return _ins;}
00219 virtual bool isReturn() const;
00220 virtual bool isBranchLink() const;
00221 virtual simPID pid() const;
00222 };
00223
00224 struct ppc_regs_t;
00225
00226
00227
00228
00229
00230
00231
00232 class ppcThread : public thread {
00233 friend class boost::serialization::access;
00234 template<class Archive>
00235 void serialize(Archive & ar, const unsigned int version )
00236 {
00237 boost::serialization::
00238 void_cast_register(static_cast<ppcThread*>(NULL),
00239 static_cast<thread*>(NULL));
00240 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(thread);
00241 ar & BOOST_SERIALIZATION_NVP(loadInfo);
00242 ar & BOOST_SERIALIZATION_NVP(Name);
00243 ar & BOOST_SERIALIZATION_NVP(ShouldExit);
00244 ar & BOOST_SERIALIZATION_NVP(threadIDMap);
00245 ar & BOOST_SERIALIZATION_NVP(nextThreadID);
00246 ar & BOOST_SERIALIZATION_NVP(exitSysCallExitsAll);
00247 ar & BOOST_SERIALIZATION_NVP(realGettimeofday);
00248 ar & BOOST_SERIALIZATION_NVP(verbose);
00249 ar & BOOST_SERIALIZATION_NVP(ThreadID);
00250 ar & BOOST_SERIALIZATION_NVP(isFuture);
00251 ar & BOOST_SERIALIZATION_NVP(SequenceNumber);
00252 ar & BOOST_SERIALIZATION_NVP(_pid);
00253 ar & BOOST_SERIALIZATION_NVP(iPool);
00254 ar & BOOST_SERIALIZATION_NVP(ProgramCounter);
00255 ar & BOOST_SERIALIZATION_NVP(setStack);
00256 ar & BOOST_SERIALIZATION_NVP(ppcRegisters);
00257 ar & BOOST_SERIALIZATION_NVP(specPPCRegisters);
00258 ar & BOOST_SERIALIZATION_NVP(packagedRegisters);
00259 ar & BOOST_SERIALIZATION_NVP(outstandingInsts);
00260 ar & BOOST_SERIALIZATION_NVP(condemnedInsts);
00261 ar & BOOST_SERIALIZATION_NVP(registers);
00262 ar & BOOST_SERIALIZATION_NVP(home);
00263 ar & BOOST_SERIALIZATION_NVP(yieldCount);
00264 ar & BOOST_SERIALIZATION_NVP(myFrame);
00265 }
00266
00267 LoadInfo loadInfo;
00268
00269 string Name;
00270 bool ShouldExit;
00271 friend class ppcInstruction;
00272 friend class ppcLoader;
00273 static const bool usingMagicStack() {return ppcInstruction::magicStack;}
00274 static map<uint32_t, ppcThread*> threadIDMap;
00275 static unsigned int nextThreadID;
00276 static bool exitSysCallExitsAll;
00277
00278 static bool realGettimeofday;
00279
00280 static int verbose;
00281 simAddress ThreadID;
00282 bool isFuture;
00283 uint32_t SequenceNumber;
00284 simPID _pid;
00285
00286 static pool<ppcInstruction> iPool;
00287
00288
00289
00290 typedef pair<simAddress, simPID> addrPair;
00291 typedef map<addrPair, ppcThread*> reservedSetT;
00292 static reservedSetT reservedSet;
00293 addrPair reservedAddr;
00294
00295 simRegister ProgramCounter;
00296 bool setStack;
00297
00298 ppc_regs_t *ppcRegisters;
00299 ppc_regs_t *specPPCRegisters;
00300
00301
00302
00303
00304
00305
00306
00307 simRegister packagedRegisters[ppcRegSize];
00308
00309 #if 0
00310
00311
00312
00313
00314
00315
00316 static uint32_t PageSize;
00317
00318 static uint32_t PageShift;
00319
00320 static uint32_t PageMask;
00321 static uint8_t *GetTextPage (const simAddress sa);
00322 #endif
00323
00324 typedef deque<ppcInstruction*> instList;
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 instList outstandingInsts;
00336 set<ppcInstruction*> condemnedInsts;
00337 uint numOutstanding() const {return outstandingInsts.size();}
00338 instList &getOutstandingInsts() {return outstandingInsts;}
00339
00340 frameID registers;
00341
00342
00343
00344 processor *home;
00345
00346 int yieldCount;
00347
00348
00349 simRegister myFrame[ppcRegSize];
00350
00351 simRegister *getRegisters() {return myFrame;}
00352 simRegister *getSpecRegisters() {return packagedRegisters;}
00353
00354
00355
00356
00357
00358 bool CopyToSIM(simAddress dest, void* source, const unsigned int Bytes);
00359
00360
00361
00362
00363
00364 bool CopyFromSIM(void* dest, const simAddress source, const unsigned int Bytes);
00365
00366 uint8_t getSpecStackByte(const simAddress sa) {
00367 map<simAddress, uint8_t>::iterator i = specStackData.find(sa);
00368 if (i != specStackData.end()) {
00369 return i->second;
00370 } else {
00371 simAddress s2 = getStackIdx(sa);
00372 if (s2 <= ppcMaxStackSize) {
00373 return stackData[s2];
00374 } else {
00375 return 0;
00376 }
00377 }
00378 }
00379
00380 void writeSpecStackByte(const simAddress sa, const uint8_t Data) {
00381 specStackData[sa] = Data;
00382 }
00383
00384
00385 uint8_t readStack8(const simAddress sa, const bool isSpec) {
00386 if (isSpec) {
00387 return getSpecStackByte(sa);
00388 } else {
00389 simAddress s2 = getStackIdx(sa);
00390 return stackData[s2];
00391 }
00392 }
00393
00394 uint16_t readStack16(const simAddress sa, const bool isSpec) {
00395 if (isSpec) {
00396 uint16_t r = (getSpecStackByte(sa) << 8);
00397 r += getSpecStackByte(sa+1);
00398 return r;
00399 } else {
00400 simAddress s2 = getStackIdx(sa);
00401 uint16_t *t = (uint16_t*)&stackData[s2];
00402 return (uint16_t)(*t);
00403 }
00404 }
00405
00406 uint32_t readStack32(const simAddress sa, const bool isSpec) {
00407 if (isSpec) {
00408 uint32_t r = (getSpecStackByte(sa) << 24);
00409 r += getSpecStackByte(sa+1) << 16;
00410 r += getSpecStackByte(sa+2) << 8;
00411 r += getSpecStackByte(sa+3);
00412 return r;
00413 } else {
00414 simAddress s2 = getStackIdx(sa);
00415 if (s2 >= ppcMaxStackSize) {
00416 printf("overstack %p %d > %d\n",
00417 (void*)(size_t)sa,s2,ppcMaxStackSize);
00418 }
00419 uint32_t *t = (uint32_t*)&stackData[s2];
00420 return (uint32_t)(*t);
00421 }
00422 }
00423 bool writeStack8(const simAddress, const uint8_t, const bool isSpec);
00424 bool writeStack16(const simAddress, const uint16_t, const bool isSpec);
00425 bool writeStack32(const simAddress, const uint32_t, const bool isSpec);
00426
00427 typedef pair<simAddress,simAddress> adrRange;
00428 static vector<adrRange> constData;
00429
00430 public:
00431 static vector<thread*> init(processor *p, SST::Component::Params_t& paramsC);
00432 static void deleteThread(thread *t);
00433 #if 0
00434 static bool WriteTextByte(simAddress bDestination, uint8_t Byte);
00435 static uint32_t ReadTextWord(const simAddress bDestination);
00436 #endif
00437
00438 ppcThread( processor* hme, simPID, string name = "");
00439 ppcThread() {;}
00440 virtual ~ppcThread();
00441
00442 simRegister GetProgramCounter() {return(ProgramCounter);}
00443
00444 uint8_t stackData[ppcMaxStackSize];
00445
00446 map<simAddress, uint8_t> specStackData;
00447
00448 #if 0
00449
00450 static uint8_t *progText;
00451 static simAddress lastTextAddr;
00452 static vector<simAddress> textRanges;
00453 #endif
00454
00455 static bool isText (simAddress addr) {
00456 #if 1
00457 return true;
00458 #else
00459 if (addr > lastTextAddr)
00460 return false;
00461
00462 int ranges = textRanges.size() >> 1;
00463 for (int i = 0; i < ranges; i += 2) {
00464 if ((addr >= textRanges[i]) && (addr < textRanges[i+1]))
00465 return true;
00466 }
00467 return false;
00468 #endif
00469 }
00470
00471 #if 0
00472 static bool writeText (simAddress addr, uint8_t *data, unsigned int size) {
00473 if (lastTextAddr < (addr + size)) {
00474 lastTextAddr = addr + size;
00475 progText = (uint8_t*)realloc(progText, lastTextAddr);
00476 }
00477 textRanges.push_back(addr);
00478 textRanges.push_back(addr + size);
00479
00480 for (int i = 0; i < size; i++) {
00481 progText[i+addr] = data[i];
00482 }
00483 return true;
00484 }
00485 static bool readText (simAddress addr, uint8_t *buffer, unsigned int size) {
00486 if (addr > lastTextAddr)
00487 return false;
00488 for (int i = 0; i < size; i++) {
00489 buffer[i] = progText[addr+i];
00490 }
00491 return true;
00492 }
00493 #endif
00494
00495 virtual instruction* getNextInstruction();
00496 virtual bool squash(instruction * i);
00497 virtual bool retire(instruction *);
00498 virtual void assimilate(processor *);
00499 virtual void packageToSend(processor *);
00500
00501 virtual simAddress getStartPC();
00502 virtual bool isPCValid(const simAddress);
00503 virtual instruction* getNextInstruction(const simAddress);
00504 virtual void squashSpec();
00505 virtual void prepareSpec();
00506 virtual bool condemn(instruction*);
00507 simPID pid() const {return _pid;};
00508 virtual void changePid(const simPID p){ _pid = p;}
00509 int getInstructionSize() {return 4;}
00510
00511 simRegister getStack() const {
00512 if (home) {
00513 return myFrame[1];
00514 } else {
00515 return packagedRegisters[1];
00516 }
00517 }
00518
00519 bool isConstSection(const simAddress, const simPID) const;
00520 };
00521
00522 #endif