Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.56 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdbool.h>
  4. #include <stdlib.h>
  5. #include <pthread.h>
  6.  
  7. typedef struct {
  8.   uint32_t base;
  9.   uint32_t element;
  10.   void** labels;
  11. } pv_block_t;
  12.  
  13. typedef struct {
  14.   //Platform specific
  15.   uint32_t a0,a1,a2,ra;
  16.   //Emulation specific:
  17.   bool delay;
  18.   uint32_t delayPc;
  19. } pv_allegrexContext_t;
  20.  
  21. typedef struct {
  22.   int blockCount;
  23.   pv_block_t* blocks;
  24.   uint32_t compileAddress;
  25.   void* platformContext;
  26. } pv_context_t;
  27.  
  28. typedef struct {
  29.   pthread_t posixThread;
  30.   pv_context_t* context;
  31.   void* userData;
  32. } pv_thread_t;
  33.  
  34.  
  35. void addIns(void* x,uint32_t y) {
  36.   printf("Adding ins 0x%08X for 0x%08X\n",x,y);
  37. }
  38.  
  39. #define PV_INSTRUCTION(address, code) label ## address: \
  40.                                       if (precomp) { \
  41.                                         ctx->compileAddress = address; \
  42.                                         code \
  43.                                       } else { \
  44.                                         addIns(&&label ## address,address); \
  45.                                       }
  46.  
  47. #define PV_CODE(context,code) { \
  48.                                 pv_context_t* ctx = context; \
  49.                                 for(bool precomp = false; true; precomp = true) { \
  50.                                   code \
  51.                                 } \
  52.                               }
  53.  
  54. #define PV_JUMP(address) { \
  55.                            printf("Jumping to 0x%08X\n",address); \
  56.                            pv_block_t* block = pv_findBlock(ctx,address); \
  57.                            goto *(block->labels[(address-block->base)/block->element]); \
  58.                          }
  59.  
  60. #define ALLEGREX(code,del) { \
  61.                              pv_allegrexContext_t* ctx_p = (pv_allegrexContext_t*)ctx->platformContext; \
  62.                              code \
  63.                              if (ctx_p->delay) { \
  64.                                ctx_p->delay = del; /*most likely false - maybe even requirement?*/ \
  65.                                PV_JUMP(ctx_p->delayPc) \
  66.                              } \
  67.                              ctx_p->delay = del; \
  68.                            }
  69.  
  70.  
  71. #define allegrexAdd_RRI(a,b,c) ALLEGREX(printf("Increasing something!\n"); ctx_p->a = ctx_p->b + c;,false)
  72. #define allegrexJ_I(a) ALLEGREX(ctx_p->delayPc = a;,true)
  73. #define allegrexJl_I(a) ALLEGREX(ctx_p->ra = ctx->compileAddress+8; allegrexJ_I(a),true)
  74. #define allegrexJr_R(a) ALLEGREX(allegrexJ_I(ctx_p->a),true)
  75. #define allegrexNop_(a) ALLEGREX(/*nothing*/,false)
  76.  
  77.  
  78. typedef void(pv_threadFunction_t)(pv_thread_t*);
  79.  
  80. void pv_joinThread(pv_thread_t* thread) {
  81.   pthread_join(thread->posixThread, NULL);
  82. }
  83.  
  84. typedef struct {
  85.   pv_threadFunction_t* function;
  86.   pv_thread_t* thread;
  87. } _pv_posixData_t;
  88.  
  89. void* _pv_posixThread(void* data) {
  90.   _pv_posixData_t* threadData = (_pv_posixData_t*)data;
  91.   threadData->function(threadData->thread);
  92.   free(data);
  93.   return NULL;
  94. }
  95.  
  96. pv_thread_t* pv_createThread(pv_threadFunction_t* function, pv_context_t* context, void* userData) {
  97.   pv_thread_t* thread = (pv_thread_t*)malloc(sizeof(pv_thread_t));
  98.   _pv_posixData_t* threadData = (_pv_posixData_t*)malloc(sizeof(_pv_posixData_t));
  99.   threadData->function = function;
  100.   threadData->thread = thread;
  101.   int result = pthread_create(&thread->posixThread, NULL, _pv_posixThread, (void*)threadData);
  102.   thread->context = context;
  103.   thread->userData = userData;
  104.   return thread;
  105. }
  106.  
  107. pv_block_t* pv_findBlock(pv_context_t* context, uint32_t address) {
  108.   //TODO: Binary search or something like that would be neat. But useless for the current amount of blocks
  109.   int i = context->blockCount;
  110.   while(true) {
  111.     pv_block_t* block = (pv_block_t*)&context->blocks[--i];
  112.     if (address >= block->base) {
  113.       return block;
  114.     }
  115.   }
  116. }
  117.  
  118. pv_context_t* pv_CreateContextForAllegrex(void) {
  119.   pv_context_t* context = (pv_context_t*)malloc(sizeof(pv_context_t));
  120.   pv_allegrexContext_t* allegrexContext = (pv_allegrexContext_t*)malloc(sizeof(pv_allegrexContext_t));
  121.   context->platformContext = allegrexContext;
  122.   return context;
  123. }
  124.  
  125. void entryCode(pv_thread_t* thread) {
  126.  
  127.   pv_context_t* context = thread->context;
  128.  
  129.   static const void* block0x00000000[] = {
  130.     &&label0x00000000, &&label0x00000004, &&label0x00000008, &&label0x0000000C, &&label0x00000010,
  131.   };
  132.  
  133.   static const void* block0x00000028[] = {
  134.     &&label0x00000028, &&label0x0000002C,
  135.   };
  136.  
  137.   static const pv_block_t blocks[] = {
  138.     { 0x00000000, 4, (void**)block0x00000000 },
  139.     { 0x00000028, 4, (void**)block0x00000028 },
  140.   };
  141.  
  142.   context->blockCount = sizeof(blocks)/sizeof(pv_block_t);
  143.   context->blocks = (pv_block_t*)blocks;
  144.   ((pv_allegrexContext_t*)context->platformContext)->a2 = 0;
  145.  
  146.   PV_CODE(thread->context,
  147.     PV_INSTRUCTION(0x00000000, allegrexAdd_RRI(a2,a2,1);)
  148.     PV_INSTRUCTION(0x00000004, allegrexJl_I(0x00000028);)
  149.     PV_INSTRUCTION(0x00000008, printf("delay slot!\n");
  150.                                allegrexAdd_RRI(a1,a1,1);)
  151.     PV_INSTRUCTION(0x0000000C, ALLEGREX(if (ctx_p->a2 > 10000000) { printf("%i\n",ctx_p->a2);  exit(0); },false) printf("wb!\n");
  152.                                allegrexJr_R(a0);)
  153.     PV_INSTRUCTION(0x00000010, allegrexNop_();)
  154.  
  155.     // 8 byte gap
  156.  
  157.     PV_INSTRUCTION(0x00000028, printf("Woo!\n");
  158.                                allegrexJr_R(ra);)
  159.     PV_INSTRUCTION(0x0000002C, allegrexNop_();)
  160.   )
  161.  
  162. }
  163.  
  164. int main(int argc, char* argv[]) {
  165.   pv_context_t* entryContext = pv_CreateContextForAllegrex();
  166.   pv_thread_t* entryThread = pv_createThread(entryCode,entryContext,NULL);
  167.   pv_joinThread(entryThread);
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement