⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mlite.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 2 页
字号:
   unsigned long c0, c1, c2;   unsigned long c1_a, c1_b;   ahi = a >> 16;   alo = a & 0xffff;   bhi = b >> 16;   blo = b & 0xffff;   c0 = alo * blo;   c1_a = ahi * blo;   c1_b = alo * bhi;   c2 = ahi * bhi;   c2 += (c1_a >> 16) + (c1_b >> 16);   c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16);   c2 += (c1 >> 16);   c0 = (c1 << 16) + (c0 & 0xffff);   *hi = c2;   *lo = c0;}void mult_big_signed(long a,                      long b,                     unsigned long *hi,                      unsigned long *lo){   unsigned long ahi, alo, bhi, blo;   unsigned long c0, c1, c2;   unsigned long c1_a, c1_b;   ahi = a >> 16;   alo = a & 0xffff;   bhi = b >> 16;   blo = b & 0xffff;   c0 = alo * blo;   c1_a = ahi * blo;   c1_b = alo * bhi;   c2 = ahi * bhi;   c2 += (c1_a >> 16) + (c1_b >> 16);   c1 = (c1_a & 0xffff) + (c1_b & 0xffff) + (c0 >> 16);   c2 += (c1 >> 16);   c0 = (c1 << 16) + (c0 & 0xffff);   *hi = c2;   *lo = c0;}//execute one cycle of a Plasma CPUvoid cycle(State *s, int show_mode){   unsigned long opcode;   unsigned long op, rs, rt, rd, re, func, imm, target;   long imm_shift, branch=0, lbranch=2, skip2=0;   long *r=s->r;   unsigned long *u=(unsigned long*)s->r;   unsigned long ptr, epc, rSave;   opcode = mem_read(s, 4, s->pc);   op = (opcode >> 26) & 0x3f;   rs = (opcode >> 21) & 0x1f;   rt = (opcode >> 16) & 0x1f;   rd = (opcode >> 11) & 0x1f;   re = (opcode >> 6) & 0x1f;   func = opcode & 0x3f;   imm = opcode & 0xffff;   imm_shift = (((long)(short)imm) << 2) - 4;   target = (opcode << 6) >> 4;   ptr = (short)imm + r[rs];   r[0] = 0;   if(show_mode)    {      printf("%8.8lx %8.8lx ", s->pc, opcode);      if(op == 0)          printf("%8s ", special_string[func]);      else if(op == 1)          printf("%8s ", regimm_string[rt]);      else          printf("%8s ", opcode_string[op]);      printf("$%2.2ld $%2.2ld $%2.2ld $%2.2ld ", rs, rt, rd, re);      printf("%4.4lx", imm);      if(show_mode == 1)         printf(" r[%2.2d]=%8.8x r[%2.2d]=%8.8x", rs, r[rs], rt, r[rt]);      printf("\n");   }   if(show_mode > 5)       return;   epc = s->pc + 4;   if(s->pc_next != s->pc + 4)      epc |= 2;  //branch delay slot   s->pc = s->pc_next;   s->pc_next = s->pc_next + 4;   if(s->skip)    {      s->skip = 0;      return;   }   rSave = r[rt];   switch(op)    {      case 0x00:/*SPECIAL*/         switch(func)          {            case 0x00:/*SLL*/  r[rd]=r[rt]<<re;          break;            case 0x02:/*SRL*/  r[rd]=u[rt]>>re;          break;            case 0x03:/*SRA*/  r[rd]=r[rt]>>re;          break;            case 0x04:/*SLLV*/ r[rd]=r[rt]<<r[rs];       break;            case 0x06:/*SRLV*/ r[rd]=u[rt]>>r[rs];       break;            case 0x07:/*SRAV*/ r[rd]=r[rt]>>r[rs];       break;            case 0x08:/*JR*/   s->pc_next=r[rs];         break;            case 0x09:/*JALR*/ r[rd]=s->pc_next; s->pc_next=r[rs]; break;            case 0x0a:/*MOVZ*/ if(!r[rt]) r[rd]=r[rs];   break;  /*IV*/            case 0x0b:/*MOVN*/ if(r[rt]) r[rd]=r[rs];    break;  /*IV*/            case 0x0c:/*SYSCALL*/ epc|=1; s->exceptionId=1; break;            case 0x0d:/*BREAK*/   epc|=1; s->exceptionId=1; break;            case 0x0f:/*SYNC*/ s->wakeup=1;              break;            case 0x10:/*MFHI*/ r[rd]=s->hi;              break;            case 0x11:/*FTHI*/ s->hi=r[rs];              break;            case 0x12:/*MFLO*/ r[rd]=s->lo;              break;            case 0x13:/*MTLO*/ s->lo=r[rs];              break;            case 0x18:/*MULT*/ mult_big_signed(r[rs],r[rt],&s->hi,&s->lo); break;            case 0x19:/*MULTU*/ mult_big(r[rs],r[rt],&s->hi,&s->lo); break;            case 0x1a:/*DIV*/  s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt]; break;            case 0x1b:/*DIVU*/ s->lo=u[rs]/u[rt]; s->hi=u[rs]%u[rt]; break;            case 0x20:/*ADD*/  r[rd]=r[rs]+r[rt];        break;            case 0x21:/*ADDU*/ r[rd]=r[rs]+r[rt];        break;            case 0x22:/*SUB*/  r[rd]=r[rs]-r[rt];        break;            case 0x23:/*SUBU*/ r[rd]=r[rs]-r[rt];        break;            case 0x24:/*AND*/  r[rd]=r[rs]&r[rt];        break;            case 0x25:/*OR*/   r[rd]=r[rs]|r[rt];        break;            case 0x26:/*XOR*/  r[rd]=r[rs]^r[rt];        break;            case 0x27:/*NOR*/  r[rd]=~(r[rs]|r[rt]);     break;            case 0x2a:/*SLT*/  r[rd]=r[rs]<r[rt];        break;            case 0x2b:/*SLTU*/ r[rd]=u[rs]<u[rt];        break;            case 0x2d:/*DADDU*/r[rd]=r[rs]+u[rt];        break;            case 0x31:/*TGEU*/ break;            case 0x32:/*TLT*/  break;            case 0x33:/*TLTU*/ break;            case 0x34:/*TEQ*/  break;            case 0x36:/*TNE*/  break;            default: printf("ERROR0(*0x%x~0x%x)\n", s->pc, opcode);               s->wakeup=1;         }         break;      case 0x01:/*REGIMM*/         switch(rt) {            case 0x10:/*BLTZAL*/ r[31]=s->pc_next;            case 0x00:/*BLTZ*/   branch=r[rs]<0;    break;            case 0x11:/*BGEZAL*/ r[31]=s->pc_next;            case 0x01:/*BGEZ*/   branch=r[rs]>=0;   break;            case 0x12:/*BLTZALL*/r[31]=s->pc_next;            case 0x02:/*BLTZL*/  lbranch=r[rs]<0;   break;            case 0x13:/*BGEZALL*/r[31]=s->pc_next;            case 0x03:/*BGEZL*/  lbranch=r[rs]>=0;  break;            default: printf("ERROR1\n"); s->wakeup=1;          }         break;      case 0x03:/*JAL*/    r[31]=s->pc_next;      case 0x02:/*J*/      s->pc_next=(s->pc&0xf0000000)|target; break;      case 0x04:/*BEQ*/    branch=r[rs]==r[rt];     break;      case 0x05:/*BNE*/    branch=r[rs]!=r[rt];     break;      case 0x06:/*BLEZ*/   branch=r[rs]<=0;         break;      case 0x07:/*BGTZ*/   branch=r[rs]>0;          break;      case 0x08:/*ADDI*/   r[rt]=r[rs]+(short)imm;  break;      case 0x09:/*ADDIU*/  u[rt]=u[rs]+(short)imm;  break;      case 0x0a:/*SLTI*/   r[rt]=r[rs]<(short)imm;  break;      case 0x0b:/*SLTIU*/  u[rt]=u[rs]<(unsigned long)(short)imm; break;      case 0x0c:/*ANDI*/   r[rt]=r[rs]&imm;         break;      case 0x0d:/*ORI*/    r[rt]=r[rs]|imm;         break;      case 0x0e:/*XORI*/   r[rt]=r[rs]^imm;         break;      case 0x0f:/*LUI*/    r[rt]=(imm<<16);         break;      case 0x10:/*COP0*/         if((opcode & (1<<23)) == 0)  //move from CP0         {            if(rd == 12)               r[rt]=s->status;            else               r[rt]=s->epc;         }         else                         //move to CP0         {            s->status=r[rt]&1;            if(s->processId && (r[rt]&2))            {               s->userMode|=r[rt]&2;               //printf("CpuStatus=%d %d %d\n", r[rt], s->status, s->userMode);               //s->wakeup = 1;               //printf("pc=0x%x\n", epc);            }         }         break;//      case 0x11:/*COP1*/ break;//      case 0x12:/*COP2*/ break;//      case 0x13:/*COP3*/ break;      case 0x14:/*BEQL*/   lbranch=r[rs]==r[rt];    break;      case 0x15:/*BNEL*/   lbranch=r[rs]!=r[rt];    break;      case 0x16:/*BLEZL*/  lbranch=r[rs]<=0;        break;      case 0x17:/*BGTZL*/  lbranch=r[rs]>0;         break;//      case 0x1c:/*MAD*/  break;   /*IV*/      case 0x20:/*LB*/   r[rt]=(signed char)mem_read(s,1,ptr);  break;      case 0x21:/*LH*/   r[rt]=(signed short)mem_read(s,2,ptr); break;      case 0x22:/*LWL*/  rt=rt; //fixme fall through      case 0x23:/*LW*/   r[rt]=mem_read(s,4,ptr);   break;      case 0x24:/*LBU*/  r[rt]=(unsigned char)mem_read(s,1,ptr); break;      case 0x25:/*LHU*/  r[rt]=(unsigned short)mem_read(s,2,ptr); break;      case 0x26:/*LWR*/  break; //fixme      case 0x28:/*SB*/   mem_write(s,1,ptr,r[rt]);  break;      case 0x29:/*SH*/   mem_write(s,2,ptr,r[rt]);  break;      case 0x2a:/*SWL*/  rt=rt; //fixme fall through      case 0x2b:/*SW*/   mem_write(s,4,ptr,r[rt]);  break;      case 0x2e:/*SWR*/  break; //fixme      case 0x2f:/*CACHE*/break;      case 0x30:/*LL*/   r[rt]=mem_read(s,4,ptr);   break;//      case 0x31:/*LWC1*/ break;//      case 0x32:/*LWC2*/ break;//      case 0x33:/*LWC3*/ break;//      case 0x35:/*LDC1*/ break;//      case 0x36:/*LDC2*/ break;//      case 0x37:/*LDC3*/ break;//      case 0x38:/*SC*/     *(long*)ptr=r[rt]; r[rt]=1; break;      case 0x38:/*SC*/     mem_write(s,4,ptr,r[rt]); r[rt]=1; break;//      case 0x39:/*SWC1*/ break;//      case 0x3a:/*SWC2*/ break;//      case 0x3b:/*SWC3*/ break;//      case 0x3d:/*SDC1*/ break;//      case 0x3e:/*SDC2*/ break;//      case 0x3f:/*SDC3*/ break;      default: printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);          s->wakeup=1;   }   s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;   s->pc_next &= ~3;   s->skip = (lbranch == 0) | skip2;   if(s->exceptionId)   {      r[rt] = rSave;      s->epc = epc;       s->pc_next = 0x3c;      s->skip = 1;       s->exceptionId = 0;      s->userMode = 0;      //s->wakeup = 1;      return;   }}void show_state(State *s){   long i,j;   printf("pid=%d userMode=%d, epc=0x%x\n", s->processId, s->userMode, s->epc);   for(i = 0; i < 4; ++i)    {      printf("%2.2ld ", i * 8);      for(j = 0; j < 8; ++j)       {         printf("%8.8lx ", s->r[i*8+j]);      }      printf("\n");   }   //printf("%8.8lx %8.8lx %8.8lx %8.8lx\n", s->pc, s->pc_next, s->hi, s->lo);   j = s->pc;   for(i = -4; i <= 8; ++i)    {      printf("%c", i==0 ? '*' : ' ');      s->pc = j + i * 4;      cycle(s, 10);   }   s->pc = j;}void do_debug(State *s){   int ch;   long i, j=0, watch=0, addr;   s->pc_next = s->pc + 4;   s->skip = 0;   s->wakeup = 0;   show_state(s);   ch = ' ';   for(;;)    {      if(ch != 'n')      {         if(watch)             printf("0x%8.8lx=0x%8.8lx\n", watch, mem_read(s, 4, watch));         printf("1=Debug 2=Trace 3=Step 4=BreakPt 5=Go 6=Memory ");         printf("7=Watch 8=Jump 9=Quit> ");      }      ch = getch();      if(ch != 'n')         printf("\n");      switch(ch)       {      case '1': case 'd': case ' ':          cycle(s, 0); show_state(s); break;      case 'n':          cycle(s, 1); break;      case '2': case 't':          cycle(s, 0); printf("*"); cycle(s, 10); break;      case '3': case 's':         printf("Count> ");         scanf("%ld", &j);         for(i = 0; i < j; ++i)             cycle(s, 1);         show_state(s);         break;      case '4': case 'b':         printf("Line> ");         scanf("%lx", &j);         printf("break point=0x%x\n", j);         break;      case '5': case 'g':         s->wakeup = 0;         cycle(s, 0);         while(s->wakeup == 0)          {            if(s->pc == j)                break;            cycle(s, 0);         }         show_state(s);         break;      case 'G':         s->wakeup = 0;         cycle(s, 1);         while(s->wakeup == 0)          {            if(s->pc == j)                break;            cycle(s, 1);         }         show_state(s);         break;      case '6': case 'm':         printf("Memory> ");         scanf("%lx", &j);         for(i = 0; i < 8; ++i)          {            printf("%8.8lx ", mem_read(s, 4, j+i*4));         }         printf("\n");         break;      case '7': case 'w':         printf("Watch> ");         scanf("%lx", &watch);         break;      case '8': case 'j':         printf("Jump> ");         scanf("%lx", &addr);         s->pc = addr;         s->pc_next = addr + 4;         show_state(s);         break;      case '9': case 'q':          return;      }   }}/************************************************************/int main(int argc,char *argv[]){   State state, *s=&state;   FILE *in;   long bytes, index;   printf("Plasma emulator\n");   memset(s, 0, sizeof(State));   s->big_endian = 1;   s->mem = (unsigned char*)malloc(MEM_SIZE);   memset(s->mem, 0, MEM_SIZE);   if(argc <= 1)    {      printf("   Usage:  mlite file.exe\n");      printf("           mlite file.exe B   {for big_endian}\n");      printf("           mlite file.exe L   {for little_endian}\n");      printf("           mlite file.exe BD  {disassemble big_endian}\n");      printf("           mlite file.exe LD  {disassemble little_endian}\n");      return 0;   }   in = fopen(argv[1], "rb");   if(in == NULL)    {       printf("Can't open file %s!\n",argv[1]);       getch();       return(0);    }   bytes = fread(s->mem, 1, MEM_SIZE, in);   fclose(in);   printf("Read %ld bytes.\n", bytes);   cache_init();   if(argc == 3 && argv[2][0] == 'B')    {      printf("Big Endian\n");      s->big_endian = 1;   }   if(argc == 3 && argv[2][0] == 'L')    {      printf("Big Endian\n");      s->big_endian = 0;   }   s->processId = 0;   if(argc == 3 && argv[2][0] == 'S')    {  /*make big endian*/      printf("Big Endian\n");      for(index = 0; index < bytes+3; index += 4)       {         *(unsigned long*)&s->mem[index] = htonl(*(unsigned long*)&s->mem[index]);      }      in = fopen("big.exe", "wb");      fwrite(s->mem, bytes, 1, in);      fclose(in);      return(0);   }   if(argc == 3 && argv[2][1] == 'D')    {  /*dump image*/      for(index = 0; index < bytes; index += 4) {         s->pc = index;         cycle(s, 10);      }      free(s->mem);      return(0);   }   memcpy(s->mem + 1024*1024, s->mem, 1024*8);  //internal 8KB SRAM   s->pc = 0x0;   index = mem_read(s, 4, 0);   if(index == 0x3c1c1000)      s->pc = 0x10000000;   do_debug(s);   free(s->mem);   return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -