Advertisement
Guest User

Untitled

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