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

📄 funcs.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 5 页
字号:
    if (inst->code.aux1)    {      destval=INT64(inst->rs1vali) * INT64(inst->code.imm);    }  else    {      destval=INT64(inst->rs1vali) * INT64(inst->rs2vali);    }	  inst->rdvali = destval; /* WRITE ALL 64 bits when supported... */  inst->rccvali = (UINT64(destval) >> 32); /* Y reg gets 32 MSBs */}void fnUDIVX(instance *inst, ProcState *){  unsigned v1 = inst->rs1vali;  unsigned v2;  v2 = (inst->code.aux1) ? inst->code.imm : inst->rs2vali;  if (v2 == 0) /* divide by 0 */    inst->exception_code = DIV0;  else    inst->rdvali=v1/v2;}void fnUDIV(instance *inst, ProcState *){  UINT64 v1 = (UINT64(UINT32(inst->rsccvali)) << 32) | UINT32(inst->rs1vali);  /* Y ## lower 32 of rs1 */  UINT64 quot;  UINT32 v2;  v2 = (inst->code.aux1) ? UINT32(inst->code.imm) : UINT32(inst->rs2vali);  if (inst->code.instruction == iUDIVcc)    {      inst->rccvali = 0;    }  if (v2 == 0) /* divide by 0 */    inst->exception_code = DIV0;  else    {      quot = v1/UINT64(v2);      if (quot > UINT64(UINT32_MAX))	{	  inst->rdvali = UINT32_MAX;	  if (inst->code.instruction == iUDIVcc)	    inst->rccvali |= iccOVERFLOW;	}      else	{	  inst->rdvali=quot;	}      if (inst->code.instruction == iUDIVcc)	{	  if (INT32(inst->rdvali) == 0)	    inst->rccvali |= iccZERO;	  if (INT32(inst->rdvali) < 0) /* if bit 31 is 1 */	    inst->rccvali |= iccNEG;	}    }}void fnSDIV(instance *inst, ProcState *proc){  INT64 v1 = INT64((UINT64(UINT32(inst->rsccvali)) << 32) | UINT32(inst->rs1vali));  /* Y ## lower 32 of rs1 */  INT64 quot;  INT32 v2;  v2 = (inst->code.aux1) ? INT32(inst->code.imm) : INT32(inst->rs2vali);  if (inst->code.instruction == iSDIVcc)    {      inst->rccvali = 0;    }  if (v2 == 0) /* divide by 0 */    inst->exception_code = DIV0;  else    {      quot = v1 / INT64(v2);      if (quot < INT64(INT32_MIN))	{	  inst->rdvali = INT32_MIN;	  if (inst->code.instruction == iSDIVcc)	    inst->rccvali |= iccOVERFLOW;	}      else if (quot > INT64(INT32_MAX))	{	  inst->rdvali = INT32_MAX;	  if (inst->code.instruction == iSDIVcc)	    inst->rccvali |= iccOVERFLOW;	}      else	{	  inst->rdvali = quot;	}            if (inst->code.instruction == iSDIVcc)	{	  if (INT32(inst->rdvali) == 0)	    inst->rccvali |= iccZERO;	  if (INT32(inst->rdvali) < 0) /* if bit 31 is 1 */	    inst->rccvali |= iccNEG;	}    }}void fnSUBC(instance *inst, ProcState *){  int vcc = inst->rsccvali;  if (inst->code.rscc == COND_XCC)    vcc = xccTOicc(vcc);  if (inst->code.aux1)    {      inst->rdvali=inst->rs1vali - inst->code.imm - (vcc&icCARRY);    }  else    {      inst->rdvali=inst->rs1vali - inst->rs2vali - (vcc&icCARRY);    }}void fnADDcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1+v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;  if ((v1 >= 0 && v2 >= 0 && tmp < 0) || (v1<0 && v2<0 && tmp>=0))    inst->rccvali |= icOVERFLOW;    if ((v1 < 0 && v2 < 0) || (tmp >= 0 && (v1 < 0 || v2 < 0)))    inst->rccvali |= icCARRY;}void fnADDCcc(instance *inst, ProcState *){  int v1,v2,v3,tmp;  v1=inst->rs1vali;    int vcc=inst->rsccvali;  if (inst->code.rscc == COND_XCC)    vcc = xccTOicc(vcc);  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp = v1 + v2 + ( vcc & icCARRY);  inst->rdvali = tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;  if ((v1 >= 0 && v2 >= 0 && tmp < 0) || (v1 < 0 && v2 < 0 && tmp >= 0))    inst->rccvali |= icOVERFLOW;  if ((v1 < 0 && v2 < 0) || (tmp >= 0 && (v1 < 0 || v2 < 0)))    inst->rccvali |= icCARRY;}void fnANDcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 & v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnORcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 | v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnXORcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 ^ v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnSUBcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 - v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;  if ((v1 >= 0 && v2 < 0 && tmp < 0) || (v1<0 && v2>=0 && tmp>=0))    inst->rccvali |= icOVERFLOW;  if ((unsigned)v1 < (unsigned) v2)    inst->rccvali |= icCARRY;}void fnSUBCcc(instance *inst, ProcState *){  int v1, v2, tmp, icbit;  v1 = inst->rs1vali;  int vcc=inst->rsccvali;  if (inst->code.rscc == COND_XCC)    vcc = xccTOicc(vcc);  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  icbit = vcc & icCARRY;  tmp = v1 - v2 - icbit;   inst->rdvali = tmp;     inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;  if ((v1 >= 0 && v2 < 0 && tmp < 0) || (v1 < 0 && v2 >= 0 && tmp >= 0))    inst->rccvali |= icOVERFLOW;  if (((unsigned) v1 < (unsigned) v2) || (v1 == v2 && icbit))    inst->rccvali |= icCARRY;}void fnANDNcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 & ~ v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnORNcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=v1 |~ v2;  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnXNORcc(instance *inst, ProcState *){  int v1,v2,tmp;  v1=inst->rs1vali;  if (inst->code.aux1)    {      v2 = inst->code.imm;    }  else    {      v2 = inst->rs2vali;    }  tmp=~(v1 ^ v2);  inst->rdvali=tmp;  inst->rccvali = 0;  if (tmp < 0)    inst->rccvali |= icNEG;   if (tmp == 0)    inst->rccvali |= icZERO;}void fnUMULcc(instance *inst, ProcState *){  inst->exception_code = SERIALIZE;}void fnSMULcc(instance *inst, ProcState *){  inst->exception_code = SERIALIZE;}void fnMULScc(instance *inst, ProcState *){  inst->exception_code = SERIALIZE;}void fnUMULcc_serialized(instance *inst, ProcState *proc){  fnUMUL(inst,proc);  /* this will set dest val in rdvali, Y val in rccvali */  proc->phy_int_reg_file[proc->intmapper[inst->lrd]] =    proc->log_int_reg_file[inst->lrd] = inst->rdvali;  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, STATE_Y)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_Y)] =    inst->rccvali;  int vcc = 0;  if (INT32(inst->rdvali) < 0)    vcc |= icNEG;  if (INT32(inst->rdvali) == 0)    vcc |= icZERO;  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, COND_ICC)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, COND_ICC)] =    vcc;}void fnSMULcc_serialized(instance *inst, ProcState *proc){  fnSMUL(inst,proc); /* this will set dest val in rdvali, Y val in rccvali */  proc->phy_int_reg_file[proc->intmapper[inst->lrd]] =    proc->log_int_reg_file[inst->lrd] =    inst->rdvali;  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, STATE_Y)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_Y)] =    inst->rccvali;  int vcc = 0;  if (INT32(inst->rdvali) < 0)    vcc |= icNEG;  if (INT32(inst->rdvali) == 0)    vcc |= icZERO;  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, COND_ICC)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, COND_ICC)] =    vcc;}void fnMULScc_serialized(instance *inst, ProcState *proc){  /* this is a very messed up instruction. In this     instruction, Y and ICC are both inputs and outputs */    /* First, form a 32-bit value by shifting rs1 right by     one bit and shifting in N^V as the high bit */  INT32 vcc = proc->log_int_reg_file[arch_to_log(proc, proc->cwp,							COND_ICC)], vy =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_Y)];  int neg = (vcc & icNEG), ovf = (vcc & icOVERFLOW);  INT32 nxorv = (neg && !ovf) || (!neg && ovf);  INT32 tmpval = (UINT32(inst->rs1vali) >> 1) | (nxorv<< 31);  INT32 multiplicand, oldtmpval;  if (inst->code.aux1)    multiplicand = INT32(inst->code.imm);  else    multiplicand = INT32(inst->rs2vali);    /* Now, iff LSB of Y is 1, multiplicand is added to tmpval;     otherwise 0 is added; set ICC based on addition */    vcc = 0;  oldtmpval = tmpval;  if (vy & 1)    {      tmpval += multiplicand;      if ((oldtmpval < 0 && multiplicand < 0 && tmpval >= 0) ||	  (oldtmpval >= 0 && multiplicand >= 0 && tmpval < 0))	vcc |= icOVERFLOW;    }    if (tmpval < 0)    vcc |= icNEG;  if (tmpval == 0)    vcc |= icZERO;    /* put those sums/conditions in the dest and ICC */  proc->phy_int_reg_file[proc->intmapper[inst->lrd]] =    proc->log_int_reg_file[inst->lrd] = tmpval;  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, COND_ICC)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, COND_ICC)] =    vcc;  /* the Y reg is shifted right one bit, with the old LSB of rs1 moving     into the MSB */  vy = (UINT32(vy) >> 1) | (UINT32(inst->rs1vali & 1) << 31);  proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, STATE_Y)]] =    proc->log_int_reg_file[arch_to_log(proc, proc->cwp, STATE_Y)] =    vy;}#define fnUDIVcc fnUDIV#define fnSDIVcc fnSDIVvoid fnSLL(instance *inst, ProcState *){  int v1=inst->rs1vali;  int v2;  if (inst->code.aux1 & 2)    v2=inst->code.imm;  else    v2=inst->rs2vali;  inst->rdvali=v1<<v2;}void fnSRL(instance *inst, ProcState *){  unsigned v1=inst->rs1vali;  unsigned v2;  if (inst->code.aux1 & 2)    v2=inst->code.imm;  else    v2=inst->rs2vali;  inst->rdvali=v1 >> v2;}void fnSRA(instance *inst, ProcState *){  int v1=inst->rs1vali;  int v2;    if (inst->code.aux1 & 2)    v2 = inst->code.imm;  else    v2 = inst->rs2vali;  v2 &= 0x1f;  inst->rdvali = v1 >> v2;  if (v1 < 0)    inst->rdvali |= (-1) << (32 - v2);}void fnarithSPECIAL1(instance *inst, ProcState *){  if (inst->code.rs1 == STATE_MEMBAR)         // stbar/membar    {      // nothing to do, but make sure not illegal...      if (inst->code.rd != 0)                 // membar shouldn't have this...	inst->exception_code = ILLEGAL;    }  else    inst->exception_code = SERIALIZE;}void fnRDPR(instance *inst, ProcState *proc){  if (!PSTATE_GET_PRIV(proc->pstate))    inst->exception_code = PRIVILEGED;  else    inst->exception_code = SERIALIZE;}void fnMOVcc(instance *inst, ProcState *){  int v1, v2;  int& out = inst->rdvali;  out = inst->rs1vali;  if (inst->code.aux1)    v2 = inst->code.imm;  else    v2 = inst->rs2vali;  v1 = inst->rsccvali;  if (inst->code.rscc >= COND_ICC) /* the integer condition code register */    {      if (inst->code.rscc == COND_XCC)	v1 = xccTOicc(v1);      switch (inst->code.aux2) /* these will be cases of bp_conds */	{	case Ab:	  out=v2;	  break;	case Nb:	  break;	case NEb:	  if (!iccZERO)	    out=v2;	  break;	case Eb:	  if (iccZERO)	    out=v2;	  break;	case Gb:	  if (!(iccZERO || Xor(iccNEG,iccOVERFLOW)))	    out = v2;	  break;	case LEb:	  if (iccZERO || Xor(iccNEG,iccOVERFLOW))	    out = v2;	  break;	case GEb:	  if (!Xor(iccNEG ,iccOVERFLOW))	    out = v2;	  break;	case Lb:	  if (Xor(iccNEG,iccOVERFLOW))	    out = v2;	  break;	case GUb:	  if (!(iccCARRY || iccZERO))	    out = v2;	  break;	case LEUb:	  if (iccCARRY || iccZERO)	    out = v2;	  break;	case CCb:	  if (!iccCARRY)	    out=v2;

⌨️ 快捷键说明

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