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

📄 funcs.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
📖 第 1 页 / 共 5 页
字号:
/* * 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 + -