/*
 * This File contains all hardware dependent C code.
 */


#include "VMS.h"

/*Create stack, then create __cdecl structure on it and put initialData and
 * pointer to the new structure instance into the parameter positions on
 * the stack
 *Then put function pointer into nextInstrPt -- the stack is setup in std
 * call structure, so jumping to function ptr is same as a GCC generated
 * function call
 *No need to save registers on old stack frame, because there's no old
 * animator state to return to --
 *
 */
inline VirtProcr *
create_procr_helper( VirtProcr *newPr,       VirtProcrFnPtr  fnPtr,
                     void      *initialData, void           *stackLocs )
 {
   void  *stackPtr;

   newPr->startOfStack = stackLocs;
   newPr->procrID      = _VMSMasterEnv->numProcrsCreated++;
   newPr->initialData  = initialData;
   newPr->requests     = NULL;
   newPr->schedSlot    = NULL;

   /*
    * Hardware dependent part           
    */
   //instead of calling the function directly, call a wrapper function to fetch
   //arguments from stack
   newPr->nextInstrPt  = (VirtProcrFnPtr)&startVirtProcrFn;
   
    //fnPtr takes two params -- void *initData & void *animProcr
    //alloc stack locations, make stackPtr be the highest addr minus room
    // for 2 params + return addr.  Return addr (NULL) is in loc pointed to
    // by stackPtr, initData at stackPtr + 8 bytes, animatingPr just above
   stackPtr = ( (void *)stackLocs + VIRT_PROCR_STACK_SIZE - 4*sizeof(void*));
   
      //setup __cdecl on stack -- coreloop will switch to stackPtr before jmp
   *((VirtProcr**)stackPtr + 2 ) = newPr; //rightmost param
   *((void**)stackPtr + 1 ) = initialData;  //next  param to left
   *((void**)stackPtr) = (void*)fnPtr;
   
   /*
    * end of Hardware dependent part           
    */
   
   newPr->stackPtr = stackPtr; //core loop will switch to this, then
   newPr->framePtr = stackPtr; //suspend loop will save new stack & frame ptr

   //============================= MEASUREMENT STUFF ========================
   #ifdef STATS__TURN_ON_PROBES
   //struct timeval timeStamp;
   //gettimeofday( &(timeStamp), NULL);
   //newPr->createPtInSecs = timeStamp.tv_sec +(timeStamp.tv_usec/1000000.0) -
   //                                            _VMSMasterEnv->createPtInSecs;
   #endif
   //========================================================================

   return newPr;
 }