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

📄 koala.hh

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 HH
📖 第 1 页 / 共 2 页
字号:
	int wired = cp0[Wired];	int free = tlb_size - wired;	return (tlb_size - 1 - wired + (now - random_seed)) % free + wired;    }    // An ASID is represented by a 16 bit integer that is either a positive    // (non-zero) ASID, complemented  if the G bit is also set. asid_match()    // checks two ASIDs for equivalence. Yet another demonstration of the    // versatility of exclusive-or. ;)    static bool asid_match(Int16 asid1, Int16 asid2)	{ return (asid1 ^ asid2) <= 0; }    // Operations on the TLB lookup map. The map is a hash table indexed by a    // hash value computed from the ASID and the bits of virtual page number    // unaffected by any page mask. The result of the map lookup is a TLB    // entry. The hash function doesn't provide an ideal distribution, but as    // a minimum, it maintains a separate hash chain per ASID, and provides    // good distribution at least for sparse address spaces.  The hash table    // always has an extra entry pointing to an invalid page.    static int tlb_hash(VA va)	{ return (bits(va, 63, 25) % tlb_map_size); }    static bool va_match(VA va1, VA va2, VA mask)	{ return !((va1 ^ va2) & mask); }    // I-cache buffer operations.    static bool ibuf_match(VA va, VA tag)	{ return ((va >> log2_icache_line) ^ tag) == 0; }    // TLB operations.    void reset_tlb();    void dump_tlb();    TLBEntry* probe_tlb(VA va);    void set_tlb_entry(int index);    PA translate_vaddr(VA va, int type);    // Instruction cache operations.    void reset_icache();    void control_icache(VA va, PA pa, int op, int type);    Instr fetch(VA va, PA pa);    // Data cache operations.    void reset_dcache();    void control_dcache(VA va, PA pa, int op, int type);    template <int syscmd> UInt64 load(VA va, PA pa);		// data load    template <int syscmd> void store(UInt64 x, VA va, PA pa);	// data store    UInt64 load_left(UInt64 x, VA va, int syscmd);		// LDL, LWL    UInt64 load_right(UInt64 x, VA va, int syscmd);		// LDR, LWR    void store_left(UInt64 x, VA va, int syscmd);		// SDL, SWL    void store_right(UInt64 x, VA va, int syscmd);		// SDR, SWR    // Complete any pending memory operations.    void sync();    // Some state information constants.    bool allow_xinstr() const	{ return mode & (kmode|xmode); }    bool branch_delay_slot() const	{ return pipeline == branch_delay; }    // Exception operations. process_exception() sets the simulator state up    // for the exception handler as specified by 'cause' and 'vec'.    // process_reset() processes a reset exception as specified by the    // (events) word. All other functions handle particular exceptions by    // calling process_exception() after setting any exception-specific    // parameters.  Most of them never return as they longjmp to the start of    // the pipeline.    void process_reset();    void process_exception(UInt32 cause, int vec);    void process_address_error(int type, VA va)    {	int exc = (type == data_store) ? EXC_AdES : EXC_AdEL;	cp0[BadVAddr] = va;	process_exception(exc, common_vector);    }    void process_tlb_refill(int type, VA va, bool x)    {	int exc = (type == data_store) ? EXC_TLBS : EXC_TLBL;	int vec = (bit(cp0[SR], SR_EXL)) ? common_vector :	    (x) ? xtlb_refill_vector : tlb_refill_vector;	cp0[BadVAddr] = va;	cp0[Context] = set_bits(cp0[Context],				bits(cp0[BadVAddr], 31, 13), 22, 4);	VA badvpn2 = (bits(va, 63, 62) << 31) | bits(va, 39, 13);	cp0[XContext] = set_bits(cp0[XContext], badvpn2, 32, 4);	cp0[EntryHi] = (va & (bitmask(63,62) | bitmask(39, 13)))	    | bits(asid, 7, 0);	process_exception(exc, vec);    }    void process_tlb_invalid(int type, VA va)    {	int exc = (type == data_store) ? EXC_TLBS : EXC_TLBL;	cp0[BadVAddr] = va;	cp0[Context] = set_bits(cp0[Context],				bits(cp0[BadVAddr], 31, 13), 22, 4);	VA badvpn2 = (bits(va, 63, 62) << 31) | bits(va, 39, 13);	if (trace_level >= print_instructions) {		log("TLB Invalid: %p", va);		dump_tlb();	}	cp0[XContext] = set_bits(cp0[XContext], badvpn2, 32, 4);	cp0[EntryHi] = (va & (bitmask(63,62) | bitmask(39, 13)))	    | bits(asid, 7, 0);	process_exception(exc, common_vector);    }    void process_tlb_modified(VA va)    {	cp0[BadVAddr] = va;	cp0[Context] = set_bits(cp0[Context],				bits(cp0[BadVAddr], 31, 13), 22, 4);	VA badvpn2 = (bits(va, 63, 62) << 31) | bits(va, 39, 13);	if (trace_level >= print_instructions) {		log("Modified: %p\n", va);		dump_tlb();	}	cp0[XContext] = set_bits(cp0[XContext], badvpn2, 32, 4);	cp0[EntryHi] = (va & (bitmask(63,62) | bitmask(39, 13)))	    | bits(asid, 7, 0);	process_exception(EXC_Mod, common_vector);    }    void process_bus_error(int type)    {	int exc = (type == instr_fetch) ? EXC_IBE : EXC_DBE;	process_exception(exc, common_vector);    }    void process_integer_overflow()	{ process_exception(EXC_Ov, common_vector); }    void process_trap()	{ process_exception(EXC_Tr, common_vector); }    void process_syscall()	{ process_exception(EXC_Sys, common_vector); }    void process_breakpoint()	{ process_exception(EXC_Bp, common_vector); }    void process_reserved_instruction()	{ process_exception(EXC_RI, common_vector); }    void process_coprocessor_unusable(int c)	{ process_exception(EXC_CpU | (c << (Cause_CE_First)), common_vector); }    void process_fp_exception()	{ process_exception(EXC_FPE, common_vector); }    void process_interrupt()	{ process_exception(EXC_Int, common_vector); }    // Endianess parameters. The data received from the memory bus is always    // in the host byte order, and uses host byte addressing.    bool big_endian_mem() const	{ return bit(cp0[Config], Config_BE); }    bool reverse_endian() const	{ return mode & rmode; }    bool big_endian_cpu() const	{ return mode & bmode; }    // Helper used to extract data from a memory cell, taking into account    // current endianess.    template <int syscmd> typename FixedWidth<(syscmd + 1) * 8>::Unsigned    swizzle(UInt64 x, unsigned addr) const    {	if (syscmd == word) {	    // Optimization for instruction fetches.	    UInt32 y = (((big_endian_cpu() << 2) ^ addr) & 7) ? x >> 32 : x;	    return reverse_endian() ? byte_swap(y) : y;	}	else if (syscmd == doubleword) {	    // Optimization for doublewords, assuming (addr & 7) == 0.	    return reverse_endian() ? byte_swap(x) : x;	}	else {	    // Generic implementation for all other types.	    typedef typename FixedWidth<(syscmd + 1) * 8>::Unsigned T;	    int shift = big_endian_cpu() ?		(64 - IntTraits<T>::width) - (addr & 7) * 8 : (addr & 7) * 8;	    T y = x >> shift;	    return reverse_endian() ? byte_swap(y) : y;	}    }    // Helper used to fix an address for a given type.    template <int syscmd> PA swizzle(PA pa) const    {#if 0	const PA mask = (syscmd == byte     ? bitmask(2, 0) :			 syscmd == halfword ? bitmask(2, 1) :			 syscmd == word     ? bitmask(2, 2) : 0);	return (big_endian_cpu() == big_endian_host()) ? pa : pa ^ mask;#endif	return pa;    }    // Set the Coprocessor 0 timer interrupt.    void set_timer();    // Coprocessor 0 register access. This is necessary as some registers    // are computed on demand, and most registers have some read-only fields.    UInt64 read_cp0(int n) const;    void write_cp0(int n, UInt64 x);    // Coprocessor 1 (FPU) simulator:    // Floating point condition names    static const char* condname[16];    enum {	FCR0  =  0,	FP_Rev_Last = 7, FP_Rev_First = 0,	FP_Imp_Last = 15, FP_Imp_First = 8,	FCR31 = 31,	FP_RM_Last = 1, FP_RM_First = 0,	FP_Flag_Last = 6, FP_Flag_First = 2,	FP_Enable_Last = 11, FP_Enable_First = 7,	FP_Cause_Last = 17, FP_Cause_First = 12,	FP_C = 23,	FP_FS = 24    };    // Software IEC/IEEE floating-point rounding mode.    enum {	float_round_nearest_even	= 0,	float_round_to_zero      	= 1,	float_round_up           	= 2,	float_round_down         	= 3    };        // Software IEC/IEEE floating-point exception flags.    enum {	float_flag_inexact   		=  1,	float_flag_underflow 		=  2,	float_flag_overflow  		=  4,	float_flag_divbyzero 		=  8,	float_flag_invalid   		= 16,	float_flag_unimplemented	= 32    };    int float_rounding_mode() const	{ return bits(cp1[FCR31], FP_RM_Last, FP_RM_First); }    float convert_from_s(UInt32 value) const	{ return *(float *)(&value); }    double convert_from_d(UInt64 value)	{ return *(double *)(&value); }    UInt32 convert_to_s(float value)	{ return *(UInt32 *)(&value); }    UInt64 convert_to_d(double value)	{ return *(UInt64 *)(&value); }    int decode_cop1_s(Instr instr);    int decode_cop1_d(Instr instr);    int decode_cop1_w(Instr instr);    int decode_cop1_l(Instr instr);    // The main instruction decoder with satelite functions for some of the    // more elaborate instructions.    int decode(Instr instr);    int decode_cop0(Instr instr);    int decode_cop1(Instr instr);    int decode_cache(Instr instr);    int decode_ldc1(Instr instr);    int decode_lwc1(Instr instr);    int decode_sdc1(Instr instr);    int decode_swc1(Instr instr);    // Some debugging help.    void dump_gpr_registers() const;    void dump_fpr_registers() const;private:    // Finally, some configuration data.    struct {	char* bus;	int ec;	char* ep;	int be;	int trace;    } conf;};#endif // koala_hh_included

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -