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

📄 opcodes.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
   return SUCCESS;}OP(lwOp){   int immediate     = IMMED(instr);   Reg32_s data;   VA   vAddr;   Reg base = P->R[RS(instr)];      vAddr  = SIGN_EXTEND(16, immediate) + base;#ifndef SOLO   /* check for unaligned loads of vaddr 3 -    * this is a syscall exception left over from base mode days    * and can be removed when all the old disks are gone    */   if ((vAddr == 3) && (RS(instr) == 0)) {      int syscallNum = P->R[REG_V0] - 1000;            STATS_INC(P->myNum, numSyscalls, 1);      if ((syscallNum < MAX_SYSCALL) && (syscallNum >= 0)) {          STATS_INC(P->myNum, syscallCount[syscallNum], 1);      }      EXCEPTION(P, EXC_SYSCALL);      return FAILURE;   }#endif      if (vAddr & 0x00000003) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      return FAILURE;   }      if (MipsyReadMem(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;   } else {      P->R[RT(instr)]   = data;      return SUCCESS;   }}OP(ldOp){   int immediate     = IMMED(instr);   uint64  data;   VA   vAddr;   Reg base = P->R[RS(instr)];      CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000007) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      return FAILURE;   }   if (MipsyReadMem(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;   } else {      P->R[RT(instr)] = data;   }   return SUCCESS;}OP(ldc2Op){   int immediate     = IMMED(instr);   /* NOTE: This is not a real "ld" instruction since a real     * ld instruction would load a 64bit value into a 64bit     * registers. Since our registers are only 32bits we    * load into two adjacent registers.     * BEWARE: THIS IS A HACK.    */   uint64 data;   VA   vAddr;   Reg base = P->R[RS(instr)];      vAddr  = SIGN_EXTEND(16, immediate) + base;      if (vAddr & 0x00000007) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      /* EXCEPTION(P->myNum,EXC_RADE); */      return FAILURE;   }   if (MipsyReadMem(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;   } else {      if (SAME_ENDIAN) {          P->R[RT(instr)]   = ((Reg32_s *)&data)[0];         P->R[RT(instr)+1] = ((Reg32_s *)&data)[1];      } else {          P->R[RT(instr)]   = ((Reg32_s *)&data)[1];         P->R[RT(instr)+1] = ((Reg32_s *)&data)[0];      }         }   return SUCCESS;}OP(lwc1Op){   int immediate     = IMMED(instr);   Reg32_s data;   VA   vAddr;   Reg base = P->R[RS(instr)];   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 & 0x00000003) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      /* EXCEPTION(P->myNum,EXC_RADE); */      return FAILURE;   }      if (MipsyReadMem(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;   } else {      IntReg(RT(instr)) = data;      return SUCCESS;   }}OP(ldc1Op){   int immediate     = IMMED(instr);   uint64  data;   VA   vAddr;   Reg base = P->R[RS(instr)];   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) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      /* EXCEPTION(P->myNum,EXC_RADE); */      return FAILURE;   }   if (MipsyReadMem(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;   } else {      DoubleReg(RT(instr)) = *((double *)&data);      return SUCCESS;   }}OP(ldlOp){   int immediate     = IMMED(instr);   int  byte;   Reg64 data;   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg  contents_rt = P->R[RT(instr)];      CHECK_64BIT_ALLOWED(P);      vAddr = SIGN_EXTEND(16, immediate) + base;   byte  = vAddr & 0x7;      vAddr = vAddr & (Reg32_s)0xfffffff8;   if (MipsyReadMem(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;   } else {      /* Big Endian */      switch (byte) {      case 0:         P->R[RT(instr)] = data;         break;      case 1:         P->R[RT(instr)] = ((data & 0x00ffffffffffffffLL) << 8) |             (contents_rt & 0x00000000000000ffLL);         break;      case 2:         P->R[RT(instr)] = ((data & 0x0000ffffffffffffLL) << 16) |             (contents_rt & 0x000000000000ffffLL);         break;      case 3:         P->R[RT(instr)] = ((data & 0x000000ffffffffffLL) << 24) |             (contents_rt & 0x0000000000ffffffLL);         break;      case 4:         P->R[RT(instr)] = ((data & 0x00000000ffffffffLL) << 32) |             (contents_rt & 0x00000000ffffffffLL);         break;      case 5:         P->R[RT(instr)] = ((data & 0x0000000000ffffffLL) << 40) |             (contents_rt & 0x000000ffffffffffLL);         break;      case 6:         P->R[RT(instr)] = ((data & 0x000000000000ffffLL) << 48) |             (contents_rt & 0x0000ffffffffffffLL);         break;      case 7:         P->R[RT(instr)] = ((data & 0x00000000000000ffLL) << 56) |             (contents_rt & 0x00ffffffffffffffLL);         break;      }   }   return SUCCESS;}OP(ldrOp){   int immediate     = IMMED(instr);   Reg64 data;   int  byte;   VA   vAddr;   Reg  contents_rt = P->R[RT(instr)];   Reg base = P->R[RS(instr)];      CHECK_64BIT_ALLOWED(P);   vAddr = SIGN_EXTEND(16, immediate) + base;   byte  = vAddr & 0x7;      vAddr = vAddr & (Reg32_s)0xfffffff8;      if (MipsyReadMem(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;   } else {      /* Big Endian */      switch (byte) {      case 0:         P->R[RT(instr)] = ((data & 0xff00000000000000LL) >> 56) |             (contents_rt & 0xffffffffffffff00LL);         break;      case 1:         P->R[RT(instr)] = ((data & 0xffff000000000000LL) >> 48) |             (contents_rt & 0xffffffffffff0000LL);         break;      case 2:         P->R[RT(instr)] = ((data & 0xffffff0000000000LL) >> 40) |             (contents_rt & 0xffffffffff000000LL);         break;      case 3:         P->R[RT(instr)] = ((data & 0xffffffff00000000LL) >> 32) |             (contents_rt & 0xffffffff00000000LL);         break;      case 4:         P->R[RT(instr)] = ((data & 0xffffffffff000000LL) >> 24) |             (contents_rt & 0xffffff0000000000LL);         break;      case 5:         P->R[RT(instr)] = ((data & 0xffffffffffff0000LL) >> 16) |             (contents_rt & 0xffff000000000000LL);         break;      case 6:         P->R[RT(instr)] = ((data & 0xffffffffffffff00LL) >> 8) |             (contents_rt & 0xff00000000000000LL);         break;      case 7:         P->R[RT(instr)] = data;         break;      }   }   return SUCCESS;}OP(lwc2Op){   int immediate     = IMMED(instr);   CPUError("LWC2 operations not implemented\n");    return FAILURE;}OP(lwlOp) {   int immediate     = IMMED(instr);   int  byte;   Reg32_s data;   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 = vAddr & (Reg32_s)0xfffffffc;   if (MipsyReadMem(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;   } else {      /* Big Endian */      switch (byte) {      case 0:         P->R[RT(instr)] = data;            break;      case 1:         P->R[RT(instr)] = ((data & 0x00ffffff) << 8) |             ((Reg32_s)contents_rt & 0x000000ff);         break;      case 2:         P->R[RT(instr)] = ((data & 0x0000ffff) << 16) |             ((Reg32_s)contents_rt & 0x0000ffff);         break;      case 3:         P->R[RT(instr)] = ((data & 0x000000ff) << 24) |             ((Reg32_s)contents_rt & 0x00ffffff);         break;      }   }   return SUCCESS;}OP(lwrOp) {   int immediate     = IMMED(instr);   Reg32_s data;   int  byte;   VA   vAddr;   Reg  contents_rt = P->R[RT(instr)];   Reg base = P->R[RS(instr)];      vAddr = SIGN_EXTEND(16, immediate) + base;   byte  = vAddr & 0x3;      vAddr = vAddr & (Reg32_s)0xfffffffc;      if (MipsyReadMem(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;   } else {      /* Big Endian */      switch (byte) {      case 0:         P->R[RT(instr)] = ((data & 0xff000000) >> 24) |             ((Reg32_s)contents_rt & 0xffffff00);         break;      case 1:         P->R[RT(instr)] = ((data & 0xffff0000) >> 16) |             ((Reg32_s)contents_rt & 0xffff0000);         break;               case 2:         P->R[RT(instr)] = ((data & 0xffffff00) >> 8) |             ((Reg32_s)contents_rt & 0xff000000);         break;               case 3:         P->R[RT(instr)] = data;         break;      }   }   return SUCCESS;}OP(lwuOp){   int immediate     = IMMED(instr);   VA   vAddr;   Reg base = P->R[RS(instr)];   Reg32 data = 0;      CHECK_64BIT_ALLOWED(P);   vAddr  = SIGN_EXTEND(16, immediate) + base;      if (vAddr & 0x00000003) {      RECORD_EXCEPTION(P, EXC_RADE, E_VEC, vAddr,                       P->CP0[C0_TLBHI], P->CP0[C0_CTXT], P->CP0[C0_XCTXT]);      return FAILURE;   }      if (MipsyReadMem(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;   } else {      P->R[RT(instr)]   = data;   }   return SUCCESS;}OP(prefOp){   int immediate     = IMMED(instr);   VA   vAddr;   Result tRet;   Reg base = P->R[RS(instr)];   uint  hint = RT(instr);      vAddr = (SIGN_EXTEND(16, immediate) + base);      tRet = Prefetch(P,vAddr, hint);      if (tRet == STALL) {      P->cpuStatus = cpu_stalled;      P->stalledInst = instr;      STATS_SET(P->myNum, stallStart, MipsyReadTime(P->myNum));      return FAILURE;   }   return SUCCESS;}            OP(oriOp){   int immediate     = IMMED(instr);   Reg_s contents_rs = P->R[RS(instr)];   P->R[RT(instr)] = contents_rs | (0x0000ffff & immediate);   return SUCCESS;}OP(sbOp){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   byte data = P->R[RT(instr)];   vAddr = SIGN_EXTEND(16, immediate) + base;      if (MipsyWriteMem(vAddr, &data, BYTE_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(shOp){   int immediate     = IMMED(instr);   VA  vAddr;   Reg base = P->R[RS(instr)];   short data = P->R[RT(instr)];   vAddr = SIGN_EXTEND(16, immediate) + base;   if (vAddr & 0x00000001) {      EXCEPTION(P,EXC_WADE);      return FAILURE;   }   if (MipsyWriteMem(vAddr, &data, HALF_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(sltiOp){   int immediate     = IMMED(instr);   Reg_s contents_rs = P->R[RS(instr)];   if (contents_rs < (Reg32_s)SIGN_EXTEND(16, immediate)) {      P->R[RT(instr)] = 1;   } else {      P->R[RT(instr)] = 0;   }   return SUCCESS;}OP(sltiuOp){   int immediate     = IMMED(instr);   Reg_s contents_rs = P->R[RS(instr)];   if ((Reg)contents_rs < (Reg)(Reg32_s)SIGN_EXTEND(16, immediate)) {      P->R[RT(instr)] = 1;   } else {      P->R[RT(instr)] = 0;   }   return SUCCESS;}OP(scOp){   int immediate     = IMMED(instr);   VA  vAddr;   bool scSuccess = FALSE;

⌨️ 快捷键说明

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