📄 translator.h
字号:
/* * 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. * */#ifndef TRANSLATOR_H#define TRANSLATOR_H#include "tc.h"/* TRANSLATOR POLICY *//* Barrier every basic block *//*#define CHAIN_BAR_SYNC*//* Defining this has the dispatch loop print the current pc to stdout. With NO_CHAINING*//* This prints the beginning of every basic block *//* Presently it skips the slave loop (who wants to see that?) *//*#define PRINT_PC*//* Enables recording of translations *//*#define RECORD_TRANSLATIONS*//* END TRANSLATOR POLICY *//* All offsets are relative to the one above it *//* This offset gets put in the pc_tc_lookup hash table. It is the *//* most conservative. It checks virtual and physical address match *//* (and so would be used by a jr) */#ifdef OLDCODE/* XXX ack! this doesn't work on vcode -BL */#define SPECULATIVE_ENTRY ((embra.emode == EMBRA_PAGE)?5:4)/* This is an offset relative to SPECULATIVE_ENTRY. It assumes that *//* the virtual address is correct, it just checks that the physical *//* page we want is mapped (and so would be used by branches or jumps *//* that span a page */#define CHECK_MAPPING_ENTRY (3)/* This is also an offset relative to CHECK_MAPPING_ENTRY. It assumes *//* that we know what virtual address we chained to, and it assumes *//* that the physical page we are chaining to is mapped. It is *//* therefore appropriate for branches and jumps within a page */#define SAME_PAGE_ENTRY (embra.MPinUP?7:5)#endif/* This is used by CP0 instructions that can except, and that have no *//* special parameters (like the move to/from ) */#ifdef OLDCODE#define DO_CALLOUT_LEN (6)#else#define DO_CALLOUT_LEN (6)#endif#ifndef _LANGUAGE_ASSEMBLYvoid Translator_Init(void);/* Both are called from continue_run */C_LINK TCA Translate( int cpuNum, VA current_pc, int* has_flushed );C_LINK TCA ChainBasicBlock(TCA jump_addr,VA new_pc);C_LINK void CountFP(void);extern TCA Get_TCA_No_Icache_Check( int cpuNum, VA vAddr );/* *************************************************************** * Code emission macros * ***************************************************************//* vcode versions of code emission macros *//* shifts */#define ECsh(funct, _rd, _rt, shamt) prev_store.real=0; \ VC_ ## funct(VREGS[_rd], VREGS[_rt], \ shamt)#define VC_srl_op_(_rd, _rt, shamt) v_rshui(_rd, _rt, shamt)#define VC_sra_op_(_rd, _rt, shamt) v_rshii(_rd, _rt, shamt)#define VC_sll_op_(_rd, _rt, shamt) v_lshui(_rd, _rt, shamt)/* arithmetic functions */#define ECs(funct, _rd, _rs, _rt) prev_store.real=0; \ VC_ ## funct(VREGS[_rd],VREGS[_rs], \ VREGS[_rt]) #define VC_add_op_(_rd, _rs, _rt) v_addi(_rd, _rs, _rt)#define VC_addi_op_(_rd, _rs, _immed) v_addii(_rd, _rs, _immed)#define VC_addu_op_(_rd, _rs, _rt) v_addu(_rd, _rs, _rt)#define VC_and_op_(_rd, _rs, _rt) v_andu(_rd, _rs, _rt)#define VC_andi_op_(_rd, _rs, _immed) v_andusi(_rd, _rs, (unsigned short) _immed)#define VC_jr_op_(_rd, _rs, _rt) v_jp(_rs)/* XXX this is cheesoid; should be more elegant... */#if defined(SIM_MIPS32)#define VC_mult_op_(_rd, _rs, _rt) { v_mulhii(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], HI_OFF); \ v_muli(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_multu_op_(_rd, _rs, _rt) { v_mulhiu(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], HI_OFF); \ v_mulu(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_div_op_(_rd, _rs, _rt) { v_modi(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divi(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_divu_op_(_rd, _rs, _rt) { v_modu(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divu(_rd, _rs, _rt); \ v_stui(_rd, VREGS[VSS_BASE], LO_OFF); }#else#define VC_mult_op_(_rd, _rs, _rt) { v_mulhii(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_muli(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_multu_op_(_rd, _rs, _rt) { v_mulhiu(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_mulu(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_div_op_(_rd, _rs, _rt) { v_modi(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divi(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_divu_op_(_rd, _rs, _rt) { v_modu(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divu(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_dmult_op_(_rd, _rs, _rt) { v_mulhil(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_mull(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_dmultu_op_(_rd, _rs, _rt) { v_mulhiul(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_mulul(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_ddiv_op_(_rd, _rs, _rt) { v_modl(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divul(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#define VC_ddivu_op_(_rd, _rs, _rt) { v_modul(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], HI_OFF); \ v_divul(_rd, _rs, _rt); \ v_stli(_rd, VREGS[VSS_BASE], LO_OFF); }#endif#define VC_nor_op_(_rd, _rs, _rt) v_noru(_rd, _rs, _rt)#define VC_or_op_(_rd, _rs, _rt) v_oru(_rd, _rs, _rt)#define VC_sllv_op_(_rd, _rs, _rt) v_lshu(_rd, _rt, _rs)#define VC_slt_op_(_rd, _rs, _rt) v_lti(_rd, _rs, _rt)#define VC_slti_op_(_rd, _rs, _immed) v_ltii(_rd, _rs, _immed)#define VC_sltiu_op_(_rd, _rs, _immed) v_ltui(_rd, _rs, _immed)#define VC_sltu_op_(_rd, _rs, _rt) v_ltu(_rd, _rs, _rt)#define VC_srav_op_(_rd, _rs, _rt) v_rshi(_rd, _rt, _rs)#define VC_srlv_op_(_rd, _rs, _rt) v_rshu(_rd, _rt, _rs)#define VC_sub_op_(_rd, _rs, _rt) v_subi(_rd, _rs, _rt)#define VC_subu_op_(_rd, _rs, _rt) v_subu(_rd, _rs, _rt)#define VC_xor_op_(_rd, _rs, _rt) v_xoru(_rd, _rs, _rt)#define VC_xori_op_(_rd, _rs, _immed) v_xorusi(_rd, _rs, \ (unsigned short) _immed)/* branches - note we only support one label deep!! * note also that you MUST follow a branch with a * VCTARGET (i.e. v_label(label)) at the appropriate point in the instruction * stream!! */#define ECb(funct, _rs, offset) {prev_store.real=0;label = v_genlabel(); \ VC_ ## funct(_rs, offset);}#define VC_bltz_op_(_rs, offset) v_bltii(VREGS[_rs], 0, label) #define VCTARGET v_label(label)#define SET_LABEL(_lab) {labels._lab = v_genlabel(); v_label(labels._lab); \ labels._lab##_addr = v_ip;}/* This says, subtract the two TC addresses and subtract 1 for the *//* instruction I am in */#define USE_LABEL(_lab) _lab#define USE_LABEL_VALUE(_lab) _lab/* immediate-mode instructions */#define ECi(opcode, _rt, _rs, _immed) {prev_store.real=0; \ VC_ ## opcode(VREGS[_rt], VREGS[_rs], \ _immed);}#define ECilab(opcode, _rt, _rs, _label) {prev_store.real=0; \ VCL_ ## opcode(VREGS[_rt], \ VREGS[_rs], _label);} #define EC1i(opcode, _rt, _rs, _immed) {prev_store.real=0; \ VC_ ## opcode(FVREGS[_rt],VREGS[_rs], \ _immed);}#define VC_andiu_op_(_rt, _rs, _immed) v_andusi(_rt, _rs, (unsigned short) _immed)#define VC_addiu_op_(_rt, _rs, _immed) v_addui(_rt, _rs, _immed)#define VCL_addiu_op_(_rt, _rs, _label) v_addui(_rt, _rs, \ ((unsigned long) (v_ip - (labels. ## _label ## _addr))))#define VC_bne_op_(_rt, _rs, _immed) {label = v_genlabel(); \ v_bnei(_rs, _rt, label);}#define VCL_bne_op_(_rt, _rs, _label) v_bnei(_rs, _rt, labels. ## _label)#define VC_beq_op_(_rt, _rs, _immed) {label = v_genlabel(); \ v_beqi(_rs, _rt, label);}#define VC_blez_op_(_rt, _rs, _immed) {label = v_genlabel(); \ v_bleii(_rs, 0, label);}#define VCL_blez_op_(_rt, _rs, _label) v_bleii(_rs, 0, (labels. ## _label))#define VC_bgez_op_(_rs, _immed) {label = v_genlabel(); \ v_bgeii(VREGS[_rs], 0, label);}#define VC_bgtz_op_(_rt, _rs, _immed) {label = v_genlabel();\ v_bgtii(_rs, 0, label);}#define VC_ori_op_(_rt, _rs, _immed) v_orusi(_rt, _rs, (unsigned short) (_immed))#define VC_lw_op_(_rt, _rs, _immed) v_ldui(_rt, _rs, _immed)#define VC_lwc1_op_(_rt, _rs, _immed) v_ldfi(_rt, _rs, _immed)#ifdef SIM_MIPS64/* XXX THIS STILL WON'T WORK -BL */#define VC_ldc1_op_(_rt, _rs, _immed) dldc1((_rt).reg,(_rs).reg, _immed)#else#define VC_ldc1_op_(_rt, _rs, _immed) v_lddi(_rt, _rs, _immed)#endif/** this is inefficient; probably can make one of these a NOP -BL *//* #define VC_lwl_op_(_rt, _rs, _immed) v_uldui(_rt, _rs, _immed) *//* #define VC_lwr_op_(_rt, _rs, _immed) v_uldui(_rt, _rs, _immed) */#define VC_lwl_op_(_rt, _rs, _immed) lwl((_rt).reg, (_rs).reg, _immed)#define VC_lwr_op_(_rt, _rs, _immed) lwr((_rt).reg, (_rs).reg, _immed)#define VC_ldl_op_(_rt, _rs, _immed) ldl((_rt).reg, (_rs).reg, _immed)#define VC_ldr_op_(_rt, _rs, _immed) ldr((_rt).reg, (_rs).reg, _immed)/** ugh!! we're hosed on these operations. Need to fix this!!! *//* #define VC_swl_op_(_rt, _rs, _immed) v_ustui(_rt, _rs, _immed) #define VC_swr_op_(_rt, _rs, _immed) v_ustui(_rt, _rs, _immed) right now, an ugly hack.... XXX -BL*/#define VC_swl_op_(_rt, _rs, _immed) swl((_rt).reg, (_rs).reg, _immed)#define VC_swr_op_(_rt, _rs, _immed) swr((_rt).reg, (_rs).reg, _immed)#define VC_sdl_op_(_rt, _rs, _immed) sdl((_rt).reg, (_rs).reg, _immed)#define VC_sdr_op_(_rt, _rs, _immed) sdr((_rt).reg, (_rs).reg, _immed)#define VC_lui_op_(_rt, _rs, _immed) v_seti(_rt,((_immed)<<16 & 0xffff0000))#define VC_sw_op_(_rt, _rs, _immed) v_stui(_rt, _rs, _immed)#define VC_swc1_op_(_rt, _rs, _immed) v_stfi(_rt, _rs, _immed)#ifdef SIM_MIPS64/* XXX THIS STILL WON'T WORK -BL */#define VC_sdc1_op_(_rt, _rs, _immed) dsdc1((_rt).reg, (_rs).reg, _immed)#else#define VC_sdc1_op_(_rt, _rs, _immed) v_stdi(_rt, _rs, _immed)#endif#define VC_lb_op_(_rt, _rs, _immed) v_ldci(_rt, _rs, _immed)#define VC_sb_op_(_rt, _rs, _immed) v_stci(_rt, _rs, _immed)#define VC_lbu_op_(_rt, _rs, _immed) v_lduci(_rt, _rs, _immed)#define VC_lh_op_(_rt, _rs, _immed) v_ldsi(_rt, _rs, _immed)#define VC_sh_op_(_rt, _rs, _immed) v_stsi(_rt, _rs, _immed)#define VC_lhu_op_(_rt, _rs, _immed) v_ldusi(_rt, _rs, _immed)/** XXX another ugly hack for now; need to implement in vcode -BL */#define VC_lwu_op_(_rt, _rs, _immed) { v_ldui(_rt, _rs, _immed); \ dsll32((_rt).reg, (_rt).reg, 0); \ dsrl32((_rt).reg, (_rt).reg, 0); \ }/* note we only support one label deep *//* jumps */#define ECj(opcode, target) prev_store.real=0; VC_ ## opcode(target)/* XXX this is a disgusting hack to make vcode generate a plain old* jal using r31; need a better way to do this -BL* should be: v_jalpi(_ra,target), if we had ra* this WILL NOT WORK on sparc, etc. - need to fix*/#define VC_jal_op_(target) {prev_store.real=0; jal((unsigned)target);v_nop();}#define VC_j_op_(target) {prev_store.real = 0; v_jpi(target);}/* nop */#define ECnop {prev_store.real = 0; } /* was v_nop(); *//* more immediates */#define ECImmed(_op1, _op2, _rs, _immed) prev_store.real=0; \ VC_ ## _op1 ## _op2(_rs, _immed)/* Coprocessor instructions *//* cop1move: move between integer register and fp data/control registers */#define ECCop1Move(_inst, _rt, _fs) VC_ ## _inst(_rt, _fs) /* RPB -- I changed these to be analogous to mtc/mfc below */#define VC_ctc_op_(_rt, _fs) { prev_store.real=0; ctc1(_fs, _rt); }#define VC_cfc_op_(_rt, _fs) { prev_store.real=0; cfc1(_rt, _fs); }/* XXX right now, this is efficient but non-portable; for SPARC add * new vcode operation?? or just go through memory? */#define VC_mtc_op_(_rt, _fs) { prev_store.real=0; movi2f(_fs, _rt); }#define VC_mfc_op_(_rt, _fs) { prev_store.real=0; movf2i(_rt, _fs); }#define VC_dmtc_op_(_rt, _fs) { prev_store.real=0; dmtc1(_fs, _rt); }#define VC_dmfc_op_(_rt, _fs) { prev_store.real=0; dmfc1(_rt, _fs); }/* Generate MIPS instructions - CHEESOID!! Yes, we have to * do this, at least right now!! -BL */#define VC_ComposeBCOND(rs,funct,offset) (prev_store.real = 0, (int)\(bcond_op << 26 | (rs) << 21 | (funct) << 16 | ((offset) & 0xffff ) ) )#define VC_ComposeImmed(opCode,rs,rt,immed) (prev_store.real = 0, (int)\ ((opCode) << 26 | (rs) << 21 | (rt) << 16 | ((uint)(immed) & 0xffff ) ) )/* temporary hack to test whether chaining is totally hosed */#define ComposeJump(opCode,target) (prev_store.real = 0, (int)\ ((opCode) << 26 |((uint)(target) & 0x3ffffff ) ) ) #if defined(SIM_MIPS64)/* 64-bit instructions */#define VC_dsll_op_(_rd, _rs, _rt) v_lshli(_rd, _rs, _rt)#define VC_dsll32_op_(_rd, _rs, _imm) dsll32(_rd.reg, _rs.reg, _imm)#define VC_dsrl_op_(_rd, _rs, _imm) v_rshuli(_rd, _rs, _imm)#define VC_dsra_op_(_rd, _rs, _imm) v_rshli(_rd, _rs, _imm)#define VC_dsra32_op_(_rd, _rs, _imm) dsra32(_rd.reg, _rs.reg, _imm)#define VC_dsrl32_op_(_rd, _rs, _imm) dsrl32(_rd.reg, _rs.reg, _imm)#define VC_dadd_op_(_rd, _rs, _rt) v_addl(_rd, _rs, _rt)#define VC_daddu_op_(_rd, _rs, _rt) v_addul(_rd, _rs, _rt)#define VC_dsllv_op_(_rd, _rs, _rt) v_lshl(_rd, _rs, _rt)#define VC_dsrlv_op_(_rd, _rs, _rt) v_rshul(_rd, _rs, _rt)#define VC_dsrav_op_(_rd, _rs, _rt) v_rshl(_rd, _rs, _rt)#define VC_dsub_op_(_rd, _rs, _rt) v_subl(_rd, _rs, _rt)#define VC_dsubu_op_(_rd, _rs, _rt) v_subul(_rd, _rs, _rt)#define VC_daddi_op_(_rd, _rs, _rt) v_addli(_rd, _rs, _rt)#define VC_daddiu_op_(_rd, _rs, _rt) v_adduli(_rd, _rs, _rt)#define VC_ld_op_(_rt, _rs, _immed) v_ldli(_rt, _rs, _immed)#define VC_sd_op_(_rt, _rs, _immed) v_stli(_rt, _rs, _immed)#endif/* allow vcode to do this for us */#define VCL_lw_op_(_reg, _addr) {Load_32_Bit_Immed (_reg, _addr); \ v_ldui(VREGS[_reg], VREGS[_reg], 0);}#define VCL_ld_op_(_reg, _addr) {Load_32_Bit_Immed (_reg, _addr); \ v_ldli(VREGS[_reg], VREGS[_reg], 0);}#define VCL_lb_op_(_reg, _addr) {Load_32_Bit_Immed(_reg, _addr); \ v_ldci(VREGS[_reg], VREGS[_reg], 0);}/* Convenience Functions (glorified macros) */#define Load_32_Bit_Immed(_reg, _immed){prev_store.real=0; \ v_seti(VREGS[_reg],(_immed) & 0xffff0000); \ v_orii(VREGS[_reg], VREGS[_reg], \ (_immed) & 0xffff);}/* #define Load_64_Bit_Immed(_reg, _immed){prev_store.real=0; \ v_setl(VREGS[_reg],(_immed));} */#if defined(SIM_MIPS32)#define Load_Reg_Immed Load_32_Bit_Immed#endif#endif /*_LANGUAGE_ASSEMBLY */#endif /* TRANSLATOR_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -