📄 predecode_instr.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. *//* predecode_instr.cc Code for the predecode part of RSIM -- splits up each tightly-encoded SPARC instruction into a loosely-encoded RSIM instruction. */#include <stdio.h>extern "C"{#include "sim_main/util.h"}#include "Processor/sync_asis.h"#include "Processor/registers.h"#include "Processor/instruction.h"#include "Processor/procstate.h"#include "Processor/pagetable.h"#include "Processor/endian_swap.h"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 SignExtend/* NOTE: The X condition code, but will be part of the Icondition code 0 -- fcc0 1 -- fcc1 2 -- fcc2 3 -- fcc3 4-7 -- icc (default) */int call_instr(instr *in, unsigned undec){ in->rd = 15; /* gets pc value of this instruction */ in->imm = Extract(undec,29,0); in->imm = SE(in->imm,30); /* sign extend it */ in->instruction = iCALL; in->uncond_branch = 3; /* take unconditionally plus add in RAS */ return 1;}int arith_instr(instr *in, unsigned undec){ IMF fp; int tmp = Extract(undec,24,19); in->instruction = iarithop[tmp]; fp=arithop[tmp]; return (*fp)(in,undec);}int branch_instr(instr *in, unsigned undec){ IMF fp; int tmp = Extract(undec,24,22); in->instruction=ibrop2[tmp]; fp=brop2[tmp]; return (*fp)(in,undec);}int illtrap(instr *in, unsigned undec){ in->rs1=8; /* o0 */ in->rd=8; /* o0 */ in->rs2=0; /* f0 */ in->rs2_regtype=REG_FP; in->aux1=Extract(undec,29,25); in->aux2=Extract(undec,21,0); /* We'll use all these different illegal instructions for all the functions we need */ return 1;}int bpcc(instr *in, unsigned undec){ int cond; in->rs1=COND_REGISTERS+ 4 /* + Extract(undec,21,20) */; in->imm=SE(Extract(undec,18,0),19); cond=in->aux1=Extract(undec,28,25); in->annul=Extract(undec,29,29); in->taken=Extract(undec,19,19); if (cond == 8) /* branch always */ { in->uncond_branch=2; in->rs1=0; } else // note: the "bn" is used as an instruction prefetch, so we should treat it as a conditional that we intentionally mispredict { in->cond_branch=1; } return 1;}int fbpfcc(instr *in, unsigned undec){ int cond; in->rs1=COND_REGISTERS+ Extract(undec,21,20); in->imm=SE(Extract(undec,18,0),19); cond=in->aux1=Extract(undec,28,25); if (cond == 8) /* branch always */ { in->uncond_branch=2; in->rs1=0; } else { in->cond_branch=1; } in->annul=Extract(undec,29,29); in->taken=Extract(undec,19,19); return 1;}int fbfcc(instr *in, unsigned undec){ in->rs1=COND_REGISTERS; in->imm=SE(Extract(undec,21,0),22); in->taken = (in->imm < 0); /* a backward branch */ int cond; cond=in->aux1=Extract(undec,28,25); in->annul=Extract(undec,29,29); if (cond == 8) /* branch always */ { in->uncond_branch=2; in->rs1=0; } else { in->cond_branch=1; } return 1;}int sethi(instr *in,unsigned undec){ in->imm=Extract(undec,21,0); in->rd=Extract(undec,29,25); return 1;}int bpr(instr *in, unsigned undec){ in->rs1=Extract(undec,18,14); in->imm=SE((Extract(undec,21,20) << 14)+Extract(undec,13,0),16); in->aux1=Extract(undec,27,25); in->annul=Extract(undec,29,29); in->taken=Extract(undec,19,19); in->cond_branch=1; return 1;}int bicc(instr *in, unsigned undec){ in->rs1=COND_REGISTERS+ 4; /* use icc */ in->imm=SE(Extract(undec,21,0),22); in->taken = (in->imm < 0); /* a backward branch */ int cond; cond=in->aux1=Extract(undec,28,25); in->annul=Extract(undec,29,29); if (cond == 8) /* branch always */ { in->uncond_branch=2; in->rs1=0; } else { in->cond_branch=1; } return 1;}int brres(instr *in, unsigned undec){ /* fprintf(stderr,"Reserved branch instruction encountered\n"); */ return 1;}int arith_res(instr *in, unsigned undec){ /* fprintf(stderr,"Reserved arithmetic instruction encountered\n"); */ return 1;}int arith_3(instr *in, unsigned undec){ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } return 1;}int arith_3y(instr *in, unsigned undec){ /* NOTE: several instructions must be handled here, and handled differently in each case. All of them take rs1 and rs2/imm inputs and have an rd output. The differences are with regard to ICC and Y SMUL/UMUL -- Y is an output. SMULcc/UMULcc -- Y and ICC are outputs. SDIV/UDIV -- Y is an input SDIVcc/UDIVcc -- Y is an input, ICC is an output MULScc -- Y is an input. ICC is an input. Y is an output. ICC is an output. Everything can be popped into the normal framework except for SMULcc, UMULcc, and MULScc. Either have a super-robust renaming structure or serialize those instructions -- anyway, they're all deprecated in the SPARC V9 (actually all of these are, but some will be needed for 32 bit code). In our implementation, we'll serialize the ones we don't like. */ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } if (in->instruction == iSMUL || in->instruction == iUMUL) { in->rcc = STATE_Y; } if (in->instruction == iSDIV || in->instruction == iUDIV || in->instruction == iSDIVcc || in->instruction == iUDIVcc) { in->rscc = STATE_Y; } if (in->instruction == iSDIVcc || in->instruction == iUDIVcc) { in->rcc = COND_ICC; } return 1;}int arith_3sc(instr *in, unsigned undec){ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); in->rscc=COND_REGISTERS + 4; if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } return 1;}int sarith_3(instr *in, unsigned undec){ in->wpchange=WPC_SAVE; in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } return 1;}int rarith_3(instr *in, unsigned undec){ in->wpchange=WPC_RESTORE; in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } return 1;}int arith_3cc(instr *in, unsigned undec){ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } /* NOTE : ANY op that writes integer rcc writes _BOTH_ icc and xcc */ in->rcc=COND_REGISTERS+4; return 1;}int arith_3sccc(instr *in, unsigned undec){ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); in->rscc=COND_REGISTERS + 4; if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } /* NOTE : ANY op that writes integer rcc writes _BOTH_ icc and xcc */ in->rcc=COND_REGISTERS+4; return 1;}int jmpl(instr *in, unsigned undec){ in->rd=Extract(undec,29,25); in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } if (in->imm == 8 && (in->rs1 == 15 || in->rs1 == 31)) in->uncond_branch = 4; /* return, so check RAS */ else in->uncond_branch=1; /* random jump */ return 1;}int ret(instr *in, unsigned undec) /* for RETURN instruction */{ in->rs1=Extract(undec,18,14); if ((in->aux1 = Extract(undec,13,13))) { /* it's an immediate */ in->imm=SE(Extract(undec,12,0),13); } else { in->rs2=Extract(undec,4,0); } in->uncond_branch=4; /* returns should always be predicted using RAS */ in->wpchange=WPC_RESTORE; return 1;}int flush(instr *in, unsigned undec){ /* fprintf(stderr,"flush encountered\n"); */ /* in->rs1 = Extract(undec,18,14); */ in->rs2 = Extract(undec,18,14); if (Extract(undec,13,13)) { /* immediate */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -