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

📄 opcodes.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
   Reg base = P->R[RS(instr)];   Result ret;   uint data = P->R[RT(instr)];      vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000003) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   }      if (UNCACHED_LL_SC) {        if (P->LLbit) {         /* This is a successful SC */         scSuccess = TRUE;         numLLactive--;         LLAddrs[P->myNum] = (PA) -1;      }   }      ret = MipsyWriteMem(vAddr, &data, WORD_SZ, SC_FLAVOR);   if (ret == STALL) {       if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         STATS_SET(P->myNum, syncStallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else if (ret == FAILURE || ret == BUSERROR) {      STATS_SET(P->myNum, syncStallStart, MipsyReadTime(P->myNum));      return FAILURE;   }      P->LLbit = 0;      P->R[RT(instr)] = (ret == SUCCESS) ? 1 : 0;      if (UNCACHED_LL_SC) {        if (scSuccess) {         P->R[RT(instr)] = 1;      } else {         P->R[RT(instr)] = 0;      }   }      STATS_INC(P->myNum, syncStats.scs, 1);   if (P->R[RT(instr)] == 0) {      STATS_INC(P->myNum, syncStats.scFailed, 1);   }   STATS_ADD_INTERVAL(P->myNum, syncStats.scStallTime, syncStallStart);   return SUCCESS;}OP(scdOp){   int immediate     = IMMED(instr);   VA  vAddr;   bool scSuccess = FALSE;   Reg base = P->R[RS(instr)];   Result ret;   uint64 data;   CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000007) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   }      if (UNCACHED_LL_SC) {        if (P->LLbit) {         /* This is a successful SC */         scSuccess = TRUE;         numLLactive--;         LLAddrs[P->myNum] = (PA) -1;      }   }   data = P->R[RT(instr)];   ret = MipsyWriteMem(vAddr, &data, DOUBLE_SZ, SC_FLAVOR);   if (ret == STALL) {       if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;                  STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         STATS_SET(P->myNum, syncStallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else if (ret == FAILURE || ret == BUSERROR) {      STATS_SET(P->myNum, syncStallStart, MipsyReadTime(P->myNum));      return FAILURE;   }      P->LLbit = 0;      P->R[RT(instr)] = (ret == SUCCESS) ? 1 : 0;      if (UNCACHED_LL_SC) {        if (scSuccess) {         P->R[RT(instr)] = 1;      } else {         P->R[RT(instr)] = 0;      }   }      STATS_INC(P->myNum, syncStats.scs, 1);   if (P->R[RT(instr)] == 0) {      STATS_INC(P->myNum, syncStats.scFailed, 1);   }   STATS_ADD_INTERVAL(P->myNum, syncStats.scStallTime, syncStallStart);   return SUCCESS;}OP(swOp){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   uint data = P->R[RT(instr)];   vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000003) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   }      if (MipsyWriteMem(vAddr, &data, WORD_SZ, NO_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   }   return SUCCESS;}OP(sdOp){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   uint64 data = 0;      CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;      if (vAddr & 0x00000007) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   } else {      data = P->R[RT(instr)];      if (MipsyWriteMem(vAddr, &data, DOUBLE_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }   }   return SUCCESS;}OP(sdc2Op){   int immediate     = IMMED(instr);   /*     * This instruction is different from the real machine.    * see note under ld_op for details.    */   VA  vAddr;   Reg base = P->R[RS(instr)];   uint64 data;      vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000007) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   }   if (SAME_ENDIAN) {       ((uint *)&data)[0] = P->R[RT(instr)];      ((uint *)&data)[1] = P->R[RT(instr)+1];   } else {       ((uint *)&data)[1] = P->R[RT(instr)];      ((uint *)&data)[0] = P->R[RT(instr)+1];   }          if (MipsyWriteMem(vAddr, &data, DOUBLE_SZ, NO_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   }   return SUCCESS;}OP(sdc1Op){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   uint64 data = 0;   StatusReg statusReg;      statusReg.ts_data = P->CP0[C0_SR];   if (!(statusReg.s32.ts_cu1)) {      CauseReg  causeReg;            causeReg.tc_data = P->CP0[C0_CAUSE];      causeReg.s32.tc_ce = 1;      P->CP0[C0_CAUSE] = causeReg.tc_data;      EXCEPTION(P,EXC_CPU);      return FAILURE;   }      vAddr = SIGN_EXTEND(16, immediate) + base;      if (vAddr & 0x00000007) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   } else {      *((double *)&data) = DoubleReg(RT(instr));      if (MipsyWriteMem(vAddr, &data, DOUBLE_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }   }   return SUCCESS;}OP(sdlOp){   int immediate     = IMMED(instr);   Reg64  data;   int  byte;   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg64  contents_rt = P->R[RT(instr)];      CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;   byte  = vAddr & 0x7;   vAddr &= (Reg32_s)~0x7;    if (MipsyReadMem(vAddr, &data, DOUBLE_SZ, GETX_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else {      /* Big Endian */      switch (byte) {      case 0:         data = contents_rt;         break;      case 1:         data =             (data & 0xff00000000000000LL)             | (contents_rt >> 8 & 0x00ffffffffffffffLL);         break;      case 2:         data =             (data & 0xffff000000000000LL)             | (contents_rt >> 16 & 0x0000ffffffffffffLL);         break;      case 3:         data =             (data & 0xffffff0000000000LL)             | (contents_rt >> 24 & 0x000000ffffffffffLL);         break;      case 4:         data =             (data & 0xffffffff00000000LL)             | (contents_rt >> 32 & 0x00000000ffffffffLL);         break;      case 5:         data =             (data & 0xffffffffff000000LL)             | (contents_rt >> 40 & 0x0000000000ffffffLL);         break;      case 6:         data =             (data & 0xffffffffffff0000LL)             | (contents_rt >> 48 & 0x000000000000ffffLL);         break;      case 7:         data =             (data & 0xffffffffffffff00LL)             | (contents_rt >> 56 & 0x00000000000000ffLL);         break;               }      if (MipsyWriteMem(vAddr, &data, DOUBLE_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }    }   return SUCCESS;}OP(sdrOp){   int immediate     = IMMED(instr);   Reg64 data;   uint byte;   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg64  contents_rt = P->R[RT(instr)];      CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;   byte = vAddr & 0x7;   vAddr &= (Reg32_s)~0x7;    if (MipsyReadMem(vAddr, &data, DOUBLE_SZ, GETX_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else {      /* Big Endian */      switch (byte) {      case 0:         data = ((contents_rt << 56) & 0xff00000000000000LL)             | (data & 0x00ffffffffffffffLL);         break;      case 1:         data = ((contents_rt << 48) & 0xffff000000000000LL)             | (data & 0x0000ffffffffffffLL);         break;      case 2:         data = ((contents_rt << 40) & 0xffffff0000000000LL)             | (data & 0x000000ffffffffffLL);         break;      case 3:         data = ((contents_rt << 32) & 0xffffffff00000000LL)             | (data & 0x00000000ffffffffLL);         break;      case 4:         data = ((contents_rt << 24) & 0xffffffffff000000LL)             | (data & 0x0000000000ffffffLL);         break;      case 5:         data = ((contents_rt << 16) & 0xffffffffffff0000LL)             | (data & 0x000000000000ffffLL);         break;      case 6:         data = ((contents_rt << 8) &  0xffffffffffffff00LL)             | (data & 0x00000000000000ffLL);         break;      case 7:         data = contents_rt;         break;      }            if (MipsyWriteMem(vAddr, &data, DOUBLE_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }   }   return SUCCESS;}OP(swc1Op){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   StatusReg statusReg;   uint data = IntReg(RT(instr));   statusReg.ts_data = P->CP0[C0_SR];   if (!(statusReg.s32.ts_cu1)) {      CauseReg  causeReg;            causeReg.tc_data = P->CP0[C0_CAUSE];      causeReg.s32.tc_ce = 1;      P->CP0[C0_CAUSE] = causeReg.tc_data;      EXCEPTION(P,EXC_CPU);      return FAILURE;   }      vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000003) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   } else {      if (MipsyWriteMem(vAddr, &data, WORD_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }   }   return SUCCESS;}OP(swc2Op){   int immediate     = IMMED(instr);   CPUError("SWCx not implemented!\n");   return FAILURE;}OP(swlOp){   int immediate     = IMMED(instr);   Reg32_s data;   int  byte;   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg  contents_rt = P->R[RT(instr)];      vAddr = SIGN_EXTEND(16, immediate) + base;   byte  = vAddr & 0x3;   vAddr &= (Reg32_s)~0x3;    if (MipsyReadMem(vAddr, &data, WORD_SZ, GETX_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else {      /* Big Endian */      switch (byte) {      case 0:         data = contents_rt;         break;      case 1:         data = (data & 0xff000000) | (contents_rt >> 8 & 0xffffff);         break;      case 2:         data = (data & 0xffff0000) | (contents_rt >> 16 & 0xffff);         break;      case 3:         data = (data & 0xffffff00) | (contents_rt >> 24 & 0xff);         break;      }      if (MipsyWriteMem(vAddr, &data, WORD_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }    }   return SUCCESS;}OP(swrOp){   int immediate     = IMMED(instr);   Reg32_s data;   uint byte;   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg  contents_rt = P->R[RT(instr)];      vAddr = SIGN_EXTEND(16, immediate) + base;   byte = vAddr & 0x3;   vAddr &= (Reg32_s)~0x3;    if (MipsyReadMem(vAddr, &data, WORD_SZ, GETX_FLAVOR) != SUCCESS) {      if (P->cpuStatus != cpu_running) {         P->stalledInst = instr;         STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      }      return FAILURE;   } else {      /* Big Endian */      switch (byte) {      case 0:         data = ((contents_rt << 24) & 0xff000000) | (data & 0xffffff);         break;      case 1:         data = ((contents_rt << 16) & 0xffff0000) | (data & 0xffff);         break;      case 2:         data = ((contents_rt << 8) & 0xffffff00)  | (data & 0xff) ;         break;      case 3:         data = contents_rt;         break;      }            if (MipsyWriteMem(vAddr, &data, WORD_SZ, NO_FLAVOR) != SUCCESS) {         if (P->cpuStatus != cpu_running) {            P->stalledInst = instr;            STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));         }         return FAILURE;      }   }   return SUCCESS;}OP(xoriOp){   int immediate     = IMMED(instr);   Reg_s contents_rs = P->R[RS(instr)];   P->R[RT(instr)] = contents_rs ^ (0x0000ffff & immediate);   return SUCCESS;}OP(cop0Op){   int immediate     = IMMED(instr);   int retval = 0;   VA  pcVal = P->PC;      retval = ExecuteC0Instruction(P, instr);      if (retval != C0_SUCCESS) {      if (retval == C0_ILLEGAL_INST) {         CPUWarning("Illegal inst at %#llx on CPU %d RA %#llx\n",                     (Reg64)P->PC, P->myNum, (Reg64)P->R[REG_RA]);         ASSERT(0);         EXCEPTION(P, EXC_II);      }      ASSERT(retval == C0_CONTINUE);      return FAILURE;   }   return SUCCESS;}

⌨️ 快捷键说明

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