📄 funcs.cc
字号:
break; case CSb: if (iccCARRY) out=v2; break; case POSb: if (!iccNEG) out=v2; break; case NEGb: if (iccNEG) out=v2; break; case VCb: if (!iccOVERFLOW) out=v2; break; case VSb: default: if (iccOVERFLOW) out=v2; break; } } else /* use floating point condition codes */ { #define E (v1 == fccEQ) #define L (v1 == fccLT) #define G (v1 == fccGT) #define U (v1 == fccUO) switch(inst->code.aux2) { case Af: out=v2; break; case Nf: break; case Uf: if (U) out=v2; break; case Gf: if (G) out=v2; break; case UGf: if (U || G) out=v2; break; case Lf: if (L) out=v2; break; case ULf: if (U || L) out=v2; break; case LGf: if (L || G) out=v2; break; case NEf: if (L || G || U) out=v2; break; case Ef: if (E) out=v2; break; case UEf: if (E || U) out=v2; break; case GEf: if (G || E) out=v2; break; case UGEf: if (U || G || E) out=v2; break; case LEf: if (L||E) out=v2; break; case ULEf: if (U||L||E) out=v2; break; case Of: if (E||L||G) out=v2; break; } }}void fnSDIVX(instance *inst, ProcState *){ int v1 = inst->rs1vali; int 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 fnPOPC(instance *inst, ProcState *){ static int POPC_arr[16]={0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4}; unsigned v1; int &out=inst->rdvali; if (inst->code.aux1) v1=inst->code.imm; else v1=inst->rs1vali; out =0; while (v1 != 0) { out += POPC_arr[v1 & 15]; v1 >>= 4; }}void fnMOVR(instance *inst, ProcState *){ int &out=inst->rdvali; out=inst->rs1vali; int v1 = inst->rsccvali; int v2 = (inst->code.aux1) ? inst->code.imm : inst->rs2vali; switch (inst->code.aux2) { case 1: if (v1 == 0) out = v2; break; case 2: if (v1 <= 0) out = v2; break; case 3: if (v1 < 0) out = v2; break; case 5: if (v1 != 0) out = v2; break; case 6: if (v1 > 0) out = v2; break; case 7: if (v1 >= 0) out = v2; break; case 0: case 4: default: break; }}void fnarithSPECIAL2(instance *inst, ProcState *proc){ /* right now, only implement basic ones -- save others for later... */ if (inst->code.rd == STATE_Y || inst->code.rd == STATE_CCR || inst->code.rd == COND_ICC) { // these get renamed, so they can be rewritten whenever if (inst->code.aux1) inst->rdvali = inst->rs1vali ^ inst->code.imm; else inst->rdvali = inst->rs1vali ^ inst->rs2vali; } else if (inst->code.rd == STATE_ASI || inst->code.rd == STATE_FPRS) // These may be things of overall system-wide consequence, so handle // them appropriately by serializing before writing to these registers inst->exception_code = SERIALIZE; else YS__logmsg(proc->proc_id / ARCH_cpus, "Other cases (%i) of ArithSpecial2 (0x%08X) not yet implemented\n", inst->code.rd, inst->pc);}void fnSAVRESTD(instance *inst, ProcState *proc){ if (!PSTATE_GET_PRIV(proc->pstate)) inst->exception_code = PRIVILEGED; else inst->exception_code = SERIALIZE;}void fnWRPR(instance *inst, ProcState *proc){ if (!PSTATE_GET_PRIV(proc->pstate)) inst->exception_code = PRIVILEGED; else { if (inst->code.rd == PRIV_VER) inst->exception_code = ILLEGAL; else inst->exception_code = SERIALIZE; }}void fnIMPDEP1(instance *inst, ProcState *){ inst->exception_code = ILLEGAL; /* not currently supported */}void fnIMPDEP2(instance *inst, ProcState *){ inst->exception_code = ILLEGAL; /* not currently supported */}#define fnSAVE fnADD#define fnRESTORE fnADD#define fnFLUSHW fnADD // this is a no-op, %g0 + %g0 -> %g0/************* Floating-point instructions *************/#define FP_ENABLED \(PSTATE_GET_FPE(proc->pstate) && \ (proc->phy_int_reg_file[proc->intmapper[arch_to_log(proc, proc->cwp, \ STATE_FPRS)]] & FPRS_FEF)) // Treat FP values as ints for "non" operations, to prevent side effects// on intel processors... Shouldn't hurt on others.void fnFMOVs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; int *ip = (int *) &(inst->rs2valfh); *((int *) &(inst->rdvalfh)) = *ip;}void fnFMOVd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; long long *ip = (long long *) &(inst->rs2valf); *((long long *) &(inst->rdvalf)) = *ip;}void fnFMOVq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; // For some reason we are treating quads as doubles? (Also elsewhere // in the code.) I'm guessing quads aren't really supported, but if // that is the case, it seems like we should panic w/ an error message, // instead of fake it this way? Unless this is a legal architectural // thing to do??? long long *ip = (long long *) &(inst->rs2valf); *((long long *) &(inst->rdvalf)) = *ip;}void fnFNEGs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; inst->rdvalfh =- inst->rs2valfh;}void fnFNEGd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; inst->rdvalf =- inst->rs2valf;}void fnFNEGq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; inst->rdvalf =- inst->rs2valf;}void fnFABSs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; if (inst->rs2valfh >= 0) inst->rdvalfh = inst->rs2valfh; else inst->rdvalfh =- inst->rs2valfh;}void fnFABSd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; if (inst->rs2valf >= 0) inst->rdvalf = inst->rs2valf; else inst->rdvalf =- inst->rs2valf;}void fnFABSq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; if (inst->rs2valf >= 0) inst->rdvalf = inst->rs2valf; else inst->rdvalf =- inst->rs2valf;}void fnFSQRTs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalfh = sqrt(inst->rs2valfh); if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFSQRTd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = sqrt(inst->rs2valf); if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFSQRTq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = sqrt(inst->rs2valf); if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFADDs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalfh = inst->rs1valfh + inst->rs2valfh; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFADDd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf + inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFADDq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf + inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFSUBs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalfh = inst->rs1valfh - inst->rs2valfh; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFSUBd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf - inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFSUBq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf - inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFMULs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalfh = inst->rs1valfh * inst->rs2valfh; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFMULd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf * inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFMULq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf * inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFDIVs(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalfh = inst->rs1valfh / inst->rs2valfh; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFDIVd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf / inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFDIVq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf / inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFsMULd(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = double(inst->rs1valfh) * double(inst->rs2valfh); if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}void fnFdMULq(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; *fpstatus = 0; FPSETMASK(); inst->rdvalf = inst->rs1valf * inst->rs2valf; if (*fpstatus) set_fp754_exception(proc, inst, *fpstatus); FPCLRMASK();}// conversions from floating-point to 32-bit integer --------------------------void fnFsTOi(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; int *ip = (int *)&(inst->rdvalfh); *ip = (int)inst->rs2valfh;}void fnFdTOi(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; int *ip = (int *)&(inst->rdvalfh); *ip = (int)inst->rs2valf;}void fnFqTOi(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; int *ip = (int *)&(inst->rdvalfh); *ip = (int) inst->rs2valf;}// conversions from float to 64 bit integer -----------------------------------void fnFsTOx(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; long long *ip = (long long *)&(inst->rdvalf); *ip = (long long) inst->rs2valfh;}void fnFdTOx(instance *inst, ProcState *proc){ if (!FP_ENABLED) inst->exception_code = FPDISABLED; long long *ip = (long long *)&(inst->rdvalf); *ip = (long long) inst->rs2valf;}void fnFqTOx(instance *inst, ProcState *proc){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -