📄 funcs.cc
字号:
/* * Copyright (c) 2002 The Board of Trustees of the University of Illinois and * William Marsh Rice University * Copyright (c) 2002 The University of Utah * Copyright (c) 2002 The University of Notre Dame du Lac * * All rights reserved. * * Based on RSIM 1.0, developed by: * Professor Sarita Adve's RSIM research group * University of Illinois at Urbana-Champaign and William Marsh Rice University * http://www.cs.uiuc.edu/rsim and http://www.ece.rice.edu/~rsim/dist.html * ML-RSIM/URSIM extensions by: * The Impulse Research Group, University of Utah * http://www.cs.utah.edu/impulse * Lambert Schaelicke, University of Utah and University of Notre Dame du Lac * http://www.cse.nd.edu/~lambert * Mike Parker, University of Utah * http://www.cs.utah.edu/~map * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal with the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimers. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimers in the * documentation and/or other materials provided with the distribution. * 3. Neither the names of Professor Sarita Adve's RSIM research group, * the University of Illinois at Urbana-Champaign, William Marsh Rice * University, nor the names of its contributors may be used to endorse * or promote products derived from this Software without specific prior * written permission. * 4. Neither the names of the ML-RSIM project, the URSIM project, the * Impulse research group, the University of Utah, the University of * Notre Dame du Lac, nor the names of its contributors may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS WITH THE SOFTWARE. */#include <sys/time.h>#include <math.h>#ifndef NO_IEEE_FP# ifdef linux# include <ieee754.h># include "Processor/linuxfp.h"# else# include <ieeefp.h># endif#endifextern "C"{#include "sim_main/util.h"}#include "Processor/procstate.h"#include "Processor/exec.h"#include "Processor/mainsim.h"#include "Processor/memunit.h"#include "Processor/simio.h"#include "Processor/branchpred.h"#include "Processor/fastnews.h"#include "Processor/fsr.h"#include "Processor/tagcvt.hh"#include "Processor/branchpred.hh"#include "Processor/procstate.hh"#include "Processor/active.hh"#include "Processor/registers.h"#include "Processor/endian_swap.h"/* here are the functions that actually emulate the instructions */#define icCARRY 1#define icOVERFLOW 2#define icZERO 4#define icNEG 8#define iccCARRY (v1 & icCARRY)#define iccOVERFLOW (v1 & icOVERFLOW)#define iccZERO (v1 & icZERO)#define iccNEG (v1 & icNEG)#define xcSHIFT 16#define xccTOicc(x) ((x) >> xcSHIFT)/* icc/xcc definitions get anded with the icc/xcc value for testing and ored for setting */#define fccEQ 0#define fccLT 1#define fccGT 2#define fccUO 3 /* unordered *//* need additional indirection to get gcc to respect the volatile attribute */volatile int *fpstatus = &fpfailed;/* in all cases its frs1 [relop] frs2 */inline int Xor(int a, int b){ return (a||b) && (!(a&&b));}inline int SignExtend(int num, int width){ /* So, we want to sign extend an int field of size num */ int bit = num & (1 << (width-1)); if (bit ==0) return num; unsigned left = ((unsigned)-1) ^ ((1<<width)-1); return (unsigned) num | left;}#define SE SignExtendvoid fnRESERVED(instance *inst, ProcState *){ inst->exception_code = ILLEGAL;}void fnILLTRAP(instance *inst, ProcState *){ inst->exception_code = ILLEGAL;}/************* Control flow instructions *************/void fnCALL(instance *inst, ProcState *){ /* a call is always properly predicted, so leave it alone */ inst->rdvali = inst->pc;}void fnJMPL(instance *inst, ProcState *){ int tmp; inst->rdvali = inst->pc; if (inst->code.aux1) tmp = inst->rs1vali + inst->code.imm; else tmp = inst->rs1vali + inst->rs2vali; inst->newpc = tmp; inst->mispredicted = (tmp != inst->branch_pred);}void fnRETURN(instance *inst, ProcState *){ int tmp; if (inst->code.aux1) tmp = inst->rs1vali + inst->code.imm; else tmp = inst->rs1vali + inst->rs2vali; inst->newpc = tmp; /* proc->BPBComplete(inst->pc,inst->newpc); */ inst->mispredicted = (inst->newpc != inst->branch_pred);}void fnTcc(instance *inst, ProcState *){ except *out = &(inst->exception_code); int v1; except code; if (inst->code.aux1) inst->rdvali = inst->rs1vali + inst->code.imm; else inst->rdvali = inst->rs1vali + inst->rs2vali; code = (enum except)(SYSTRAP_00 + inst->rdvali); v1 = inst->rsccvali; if (inst->code.rscc == COND_XCC) v1 = xccTOicc(v1); switch (inst->code.aux2) /* these will be cases of bp_conds */ { case Ab: *out = code; break; case Nb: break; case NEb: if (!iccZERO) *out = code; break; case Eb: if (iccZERO) *out = code; break; case Gb: if (!(iccZERO || Xor(iccNEG,iccOVERFLOW))) *out = code; break; case LEb: if (iccZERO || Xor(iccNEG,iccOVERFLOW)) *out = code; break; case GEb: if (!Xor(iccNEG ,iccOVERFLOW)) *out = code; break; case Lb: if (Xor(iccNEG,iccOVERFLOW)) *out = code; break; case GUb: if (!(iccCARRY || iccZERO)) *out = code; break; case LEUb: if (iccCARRY || iccZERO) *out = code; break; case CCb: if (!iccCARRY) *out = code; break; case CSb: if (iccCARRY) *out = code; break; case POSb: if (!iccNEG) *out = code; break; case NEGb: if (iccNEG) *out = code; break; case VCb: if (!iccOVERFLOW) *out = code; break; case VSb: default: if (iccOVERFLOW) *out = code; break; }}void fnDONERETRY(instance *inst, ProcState *proc){ if (!PSTATE_GET_PRIV(proc->pstate)) inst->exception_code = PRIVILEGED; else inst->exception_code = SERIALIZE;}void fnBPcc(instance *inst, ProcState *proc){ int v1; int taken=0; v1 = inst->rs1vali; if (inst->code.rs1 == COND_XCC) v1 = xccTOicc(v1); switch (inst->code.aux1) /* these will be cases of bp_conds */ { case Ab: taken=1; break; case Nb: break; case Eb: if (iccZERO) taken=1; break; case NEb: if (!iccZERO) taken=1; break; case Gb: if (!(iccZERO || Xor(iccNEG,iccOVERFLOW))) taken = 1; break; case LEb: if (iccZERO || Xor(iccNEG,iccOVERFLOW)) taken = 1; break; case GEb: if (!Xor(iccNEG, iccOVERFLOW)) taken = 1; break; case Lb: if (Xor(iccNEG,iccOVERFLOW)) taken = 1; break; case GUb: if (!(iccCARRY || iccZERO)) taken = 1; break; case LEUb: if (iccCARRY || iccZERO) taken = 1; break; case CCb: if (!iccCARRY) taken=1; break; case CSb: if (iccCARRY) taken=1; break; case POSb: if (!iccNEG) taken=1; break; case NEGb: if (iccNEG) taken=1; break; case VCb: if (!iccOVERFLOW) taken=1; break; case VSb: default: if (iccOVERFLOW) taken=1; break; } if (taken) inst->newpc = inst->pc + (inst->code.imm * SIZE_OF_SPARC_INSTRUCTION); else inst->newpc = inst->pc + (2 * SIZE_OF_SPARC_INSTRUCTION); if (inst->code.aux1 != Nb) /* don't mark it for bn */ proc->BPBComplete(inst->pc, taken, inst->code.taken); inst->mispredicted = (inst->taken != taken);}#define fnBicc fnBPccvoid fnBPr(instance *inst, ProcState *proc){ int v1; int taken=0; v1 = inst->rs1vali; switch (inst->code.aux1) /* these will be cases of bp_conds */ { case 1: if (v1 == 0) taken = 1; break; case 2: if (v1 <= 0) taken = 1; break; case 3: if (v1 < 0) taken = 1; break; case 5: if (v1 != 0) taken = 1; break; case 6: if (v1 > 0) taken = 1; break; case 7: if (v1 >= 0) taken = 1; break; case 0: case 4: default: break; } if (taken) inst->newpc = inst->pc + (inst->code.imm * SIZE_OF_SPARC_INSTRUCTION); else inst->newpc = inst->pc + (2 * SIZE_OF_SPARC_INSTRUCTION); proc->BPBComplete(inst->pc, taken, inst->code.taken); inst->mispredicted = (inst->taken != taken);}void fnFBPfcc(instance *inst, ProcState *proc){ double v1; int taken=0; v1 = inst->rs1vali; #define E (v1 == fccEQ)#define L (v1 == fccLT)#define G (v1 == fccGT)#define U (v1 == fccUO) switch (inst->code.aux1) { case Af: taken=1; break; case Uf: if (U) taken=1; break; case Gf: if (G) taken=1; break; case UGf: if (U || G) taken=1; break; case Lf: if (L) taken=1; break; case ULf: if (U || L) taken=1; break; case LGf: if (L || G) taken=1; break; case NEf: if (L || G || U) taken=1; break; case Nf: break; case Ef: if (E) taken=1; break; case UEf: if (E || U) taken=1; break; case GEf: if (G || E) taken=1; break; case UGEf: if (U || G || E) taken=1; break; case LEf: if (L || E) taken=1; break; case ULEf: if (U||L||E) taken=1; break; case Of: if (E||L||G) taken=1; break; } if (taken) inst->newpc = inst->pc + (inst->code.imm * SIZE_OF_SPARC_INSTRUCTION); else inst->newpc = inst->pc + (2 * SIZE_OF_SPARC_INSTRUCTION); if (inst->code.aux1 != Nf) /* don't mark it for bn */ proc->BPBComplete(inst->pc, taken, inst->code.taken); inst->mispredicted = (inst->taken != taken);}#define fnFBfcc fnFBPfcc/************* Arithmetic instructions *************/void fnSETHI(instance *inst, ProcState *){ unsigned tmp = inst->code.imm; inst->rdvali=tmp << 10;}void fnADD(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali + inst->code.imm; } else { inst->rdvali=inst->rs1vali + inst->rs2vali; }}void fnAND(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali & inst->code.imm; } else { inst->rdvali=inst->rs1vali & inst->rs2vali; }}void fnOR(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali | inst->code.imm; } else { inst->rdvali=inst->rs1vali | inst->rs2vali; }}void fnXOR(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali ^ inst->code.imm; } else { inst->rdvali=inst->rs1vali ^ inst->rs2vali; }}void fnSUB(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali - inst->code.imm; } else { inst->rdvali=inst->rs1vali - inst->rs2vali; }}void fnANDN(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali & (~inst->code.imm); } else { inst->rdvali=inst->rs1vali & (~inst->rs2vali); }}void fnORN(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali | (~ inst->code.imm); } else { inst->rdvali=inst->rs1vali | (~ inst->rs2vali); }}void fnXNOR(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=~(inst->rs1vali ^ inst->code.imm); } else { inst->rdvali=~(inst->rs1vali ^ inst->rs2vali); }}void fnADDC(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 fnMULX(instance *inst, ProcState *){ if (inst->code.aux1) { inst->rdvali=inst->rs1vali * inst->code.imm; } else { inst->rdvali=inst->rs1vali * inst->rs2vali; }}void fnUMUL(instance *inst, ProcState *){ UINT64 destval; if (inst->code.aux1) { destval=UINT64((unsigned)inst->rs1vali)*UINT64((unsigned)inst->code.imm); //destval=UINT64(inst->rs1vali)*UINT64(inst->code.imm); } else { destval=UINT64((unsigned)inst->rs1vali)*UINT64((unsigned)inst->rs2vali); //destval=UINT64(inst->rs1vali)*UINT64(inst->rs2vali); } inst->rdvali = destval; /* WRITE ALL 64 bits when supported... */ inst->rccvali = (destval >> 32); /* Y reg gets 32 MSBs */}void fnSMUL(instance *inst, ProcState *){ INT64 destval;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -