📄 funcs.cc
字号:
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 + -