📄 ms_st_init.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * */ /* * ms_st_init - Initialize the MXS simulator state for one CPU * * Jim Bennett * 1993, 1994, 1995 */#include <stdlib.h>#include <string.h>#include <ieeefp.h>#include "ms.h"#include "simutil.h"int true_inst_hi = 0; /* Instruction count (optional) */int true_inst_lo = 0;int min_special_preg = -1; /* Range of special physical reg's */int max_special_preg = -1;#ifdef BREAKPOINTint brkpt = 0;int jmpbrk = 0x77650001; /* Unlikely value */int cycbrk = -1;int linbrk = -1;int membrk = 0;int opcbrk = -1;int trace_reg = -1; /* Register for tracing */int trace_preg = -1; /* Physical version of above */#endif#ifdef PRINT_INSTint enable_iprint = 0;int enable_fprint = 0;int enable_eprint = 0;int iprint_frequency = 1;#endifchar *statfilename = NULL;#ifdef TRACEchar *tracefilename = NULL;FILE *tracefile = NULL;int trace_writes = 0;#endif /* * ms_st_init - Initialize the simulator state structure */void ms_st_init (struct s_cpu_state *st) { THREAD *th; int i, j;/* Initialize floating point rounding mode. */ st->round_mode = 0; set_rm (0);/* Initialize the graduation point thread, or thread 0 if not precise */#ifdef PRECISE th = &st->grad;#else th = &st->threads [0];#endif th->thread_st = TH_ACTIVE; th->stall_fetch = 0; th->branch_dly = 0; th->branch_likely = 0; th->stall_branch = 0; th->stall_thread = 0; th->stall_fpc = 0; th->stall_icache = 0; th->stall_except = 0; th->stall_itlbmiss = 0; th->stall_cp0 = 0; th->stall_sc = 0; th->stall_sys = 0; th->branch_sp = 0; th->branch_node = 0; for (i=0, j=0; i<FPREG; i++, j+=2) th->regnames[i] = j; for (i=FPREG; i<MAX_FP; i++, j++ ) th->regnames[i] = j; for (i=MAX_FP; i<MAX_VAR; i++, j+=2) th->regnames[i] = j; for (i=0; i<MAX_VAR/2; i++) th->half_def[i] = 0;/* Initialize stall status of functional units. */ st->stall_issue = 0; st->stall_type = ST_NO_EXCUSE;/* Initialize the instruction window */ ms_iwin_init (st);/* Initialize exception handling mechanism */ st->exception_pending = 0;/* Initialize branch prediction tables */ for (i=0; i<BP_TABLE_SIZE; i++) { st->bp_bits [i] = BP_TAKEN; st->bp_targets [i] = -1; } for (i=0; i<BP_RETURN_STACK; i++) st->branch_stack [i] = -1; st->branch_sp = 0;/* Initialize the worklist mechanism. Put all items on the free list *//* to start with. Clear statistics counters. */ for (i=0; i<MAX_WORK_ITEMS; i++) st->worklist[i].next = &st->worklist[i+1]; st->free_head = &st->worklist[0]; st->free_tail = &st->worklist[MAX_WORK_ITEMS-1]; st->free_tail->next = NULL; st->work_head = NULL; st->work_tail = NULL; st->work_cycle = 0; st->work_ticks = 0; bzero((char *) &(st->stats[0]), sizeof(st->stats));/* Initialize the load/store queue and memory callbacks */ for (i=0; i<MAX_CALLBACK; i++) st->callbacks[i].next_cb = i + 1; st->cb_free = 0; st->callbacks[MAX_CALLBACK-1].next_cb = -1; } /* * ms_iwin_init - Initialization specific to the instruction * window. Called when restarting after an * exception. */void ms_iwin_init (struct s_cpu_state *st) { int i, reg_ix; THREAD *th; BrTREE *br;/* Initialize branch processing machinery. Put all the threads on the *//* free list, except the first, and initialize the first thread. */ for (i=0; i<THREAD_WIDTH; i++) { th = &st->threads [i]; th->pc = ((i+1) >= THREAD_WIDTH ? -1 : i+1); } th = &st->threads [0];#ifdef PRECISE *th = st->grad; /* Copy from the graduating */#endif /* (precise) thread. */ st->active_thread = th; st->free_thread = 1; st->nthreads = 1; st->nactive = 1;/* Then do the same for the branch tree nodes. */ for (i=0; i<2*THREAD_WIDTH; i++) { br = &st->branch_tree [i]; br->thread = ((i+1) >= (2*THREAD_WIDTH) ? -1 : i+1); } st->free_branch_node = 1; br = &st->branch_tree [0]; br->thread = 0; br->thread_st = th->thread_st; br->lchild = -1; br->rchild = -1; br->condition = 0; br->resolution = 0; br->indirect = 0; br->jret = 0; br->call = 0; br->uncond = 0; br->restore = 0; br->iwin_head_th = -1; br->iwin_tail_th = -1;/* Clear all of the registers and their associated state *//* (rename tables, etc.) */ for (i=0; i<MAX_PREG; i++) { st->regs [i] = 0; st->reg_owner [i] = 0; } for (i=0; i<MAX_PREG/2; i++) { st->reg_excuse [i] = ST_NO_EXCUSE; st->new_excuse [i] = ST_NO_EXCUSE; st->reg_rstat[i].reg_status = 0; st->reg_rstat[i].reg_ref = 0; st->reg_rstat[i].reg_nmap = 0; st->reg_rstat[i].reg_nclaims = 0; }/* Acquire mappings for all the registers belonging to this thread, *//* and put the other registers on the free list. */ for (i = 0; i < MAX_VAR; i++) { if ((i < FPREG) || (i >= MAX_FP)) { reg_ix = th->regnames[i] >> 1; AcquireRegMap (&st->reg_rstat[reg_ix], th, i); st->reg_rstat[reg_ix].reg_status |= REG_BUSY; } else if ((i < FPCTL) || (i >= TOT_REG)) { if ((i & 0x01) == 0) { reg_ix = th->regnames[i] >> 1; AcquireRegMap (&st->reg_rstat[reg_ix], th, i); st->reg_rstat[reg_ix].reg_status |= REG_BUSY; } } else { reg_ix = th->regnames[i] >> 1; AcquireRegMap (&st->reg_rstat[reg_ix], th, i); if (min_special_preg == -1) { min_special_preg = reg_ix; max_special_preg = reg_ix; } if (reg_ix < min_special_preg) min_special_preg = reg_ix; if (reg_ix > max_special_preg) max_special_preg = reg_ix; } } st->reg_nextfree = -1; for (i=0; i<MAX_PREG/2; i++) { if ((st->reg_rstat[i].reg_status & REG_MAPPED) == 0) { st->reg_freelist [i] = st->reg_nextfree; st->reg_nextfree = i; } }/* Initialize the instructions window fields. */ st->iwin_ninst = 0; for (i=0; i<TOTAL_INST; i++) { st->iwin_flags [i] = 0; st->iwin_freelist [i] = i+1; st->iwin_index2 [i] = 0; st->iwin_index3 [i] = 0; } st->iwin_freelist [TOTAL_INST-1] = -1; st->iwin_nextfree = 0; st->iwin_headpri = -1; st->iwin_tailpri = -1;#ifdef PRECISE st->iwin_headgrad = -1; st->iwin_tailgrad = -1;#endif st->iwin_next_avail = -1; st->iwin_last_avail = -1; st->iwin_head_ldst = -1; st->iwin_tail_ldst = -1; st->iwin_nldst = 0;#ifdef ONE_PHASE_LS st->iwin_nstores = 0;#endif/* Initialize execution unit. */ st->ex_count = 0;/* Initialize the ldst unit. */ ldst_init(st); }voidset_rm(int mode) { fp_rnd newmode; switch (mode) { case 0: newmode = FP_RN; break; case 1: newmode = FP_RZ; break; case 2: newmode = FP_RP; break; case 3: newmode = FP_RM; break; } fpsetround(newmode);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -