📄 mips.igen
字号:
// -*- C -*-//// <insn> ::=// <insn-word> { "+" <insn-word> }// ":" <format-name>// ":" <filter-flags>// ":" <options>// ":" <name>// <nl>// { <insn-model> }// { <insn-mnemonic> }// <code-block>//// IGEN config - mips16// :option:16::insn-bit-size:16// :option:16::hi-bit-nr:15:option:16::insn-specifying-widths:true:option:16::gen-delayed-branch:false// IGEN config - mips32/64..// :option:32::insn-bit-size:32// :option:32::hi-bit-nr:31:option:32::insn-specifying-widths:true:option:32::gen-delayed-branch:false// Generate separate simulators for each target// :option:::multi-sim:true// Models known by this simulator are defined below.//// When placing models in the instruction descriptions, please place// them one per line, in the order given here.// MIPS ISAs://// Instructions and related functions for these models are included in// this file.:model:::mipsI:mips3000::model:::mipsII:mips6000::model:::mipsIII:mips4000::model:::mipsIV:mips8000::model:::mipsV:mipsisaV::model:::mips32:mipsisa32::model:::mips64:mipsisa64:// Vendor ISAs://// Standard MIPS ISA instructions used for these models are listed here,// as are functions needed by those standard instructions. Instructions// which are model-dependent and which are not in the standard MIPS ISAs// (or which pre-date or use different encodings than the standard// instructions) are (for the most part) in separate .igen files.:model:::vr4100:mips4100: // vr.igen:model:::vr4120:mips4120::model:::vr5000:mips5000::model:::vr5400:mips5400::model:::vr5500:mips5500::model:::r3900:mips3900: // tx.igen// MIPS Application Specific Extensions (ASEs)//// Instructions for the ASEs are in separate .igen files.// ASEs add instructions on to a base ISA.:model:::mips16:mips16: // m16.igen (and m16.dc):model:::mips3d:mips3d: // mips3d.igen:model:::mdmx:mdmx: // mdmx.igen// Vendor Extensions//// Instructions specific to these extensions are in separate .igen files.// Extensions add instructions on to a base ISA.:model:::sb1:sb1: // sb1.igen// Pseudo instructions known by IGEN:internal::::illegal:{ SignalException (ReservedInstruction, 0);}// Pseudo instructions known by interp.c// For grep - RSVD_INSTRUCTION, RSVD_INSTRUCTION_MASK000000,5.*,5.*,5.*,5.OP,000101:SPECIAL:32::RSVD"rsvd <OP>"{ SignalException (ReservedInstruction, instruction_0);}// Helper://// Simulate a 32 bit delayslot instruction//:function:::address_word:delayslot32:address_word target{ instruction_word delay_insn; sim_events_slip (SD, 1); DSPC = CIA; CIA = CIA + 4; /* NOTE not mips16 */ STATE |= simDELAYSLOT; delay_insn = IMEM32 (CIA); /* NOTE not mips16 */ ENGINE_ISSUE_PREFIX_HOOK(); idecode_issue (CPU_, delay_insn, (CIA)); STATE &= ~simDELAYSLOT; return target;}:function:::address_word:nullify_next_insn32:{ sim_events_slip (SD, 1); dotrace (SD, CPU, tracefh, 2, CIA + 4, 4, "load instruction"); return CIA + 8;}// Helper://// Calculate an effective address given a base and an offset.//:function:::address_word:loadstore_ea:address_word base, address_word offset*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*vr4100:*vr5000:*r3900:{ return base + offset;}:function:::address_word:loadstore_ea:address_word base, address_word offset*mips64:{#if 0 /* XXX FIXME: enable this only after some additional testing. */ /* If in user mode and UX is not set, use 32-bit compatibility effective address computations as defined in the MIPS64 Architecture for Programmers Volume III, Revision 0.95, section 4.9. */ if ((SR & (status_KSU_mask|status_EXL|status_ERL|status_UX)) == (ksu_user << status_KSU_shift)) return (address_word)((signed32)base + (signed32)offset);#endif return base + offset;}// Helper://// Check that a 32-bit register value is properly sign-extended.// (See NotWordValue in ISA spec.)//:function:::int:not_word_value:unsigned_word value*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*vr4100:*vr5000:*r3900:{ /* For historical simulator compatibility (until documentation is found that makes these operations unpredictable on some of these architectures), this check never returns true. */ return 0;}:function:::int:not_word_value:unsigned_word value*mips32:{ /* On MIPS32, since registers are 32-bits, there's no check to be done. */ return 0;}:function:::int:not_word_value:unsigned_word value*mips64:{ return ((value >> 32) != (value & 0x80000000 ? 0xFFFFFFFF : 0));}// Helper://// Handle UNPREDICTABLE operation behaviour. The goal here is to prevent// theoretically portable code which invokes non-portable behaviour from// running with no indication of the portability issue.// (See definition of UNPREDICTABLE in ISA spec.)//:function:::void:unpredictable:*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*vr4100:*vr5000:*r3900:{}:function:::void:unpredictable:*mips32:*mips64:{ unpredictable_action (CPU, CIA);}// Helpers://// Check that an access to a HI/LO register meets timing requirements//// In all MIPS ISAs,//// OP {HI and LO} followed by MT{LO or HI} (and not MT{HI or LO})// makes subsequent MF{HI or LO} UNPREDICTABLE. (1)//// The following restrictions exist for MIPS I - MIPS III://// MF{HI or LO} followed by MT{HI or LO} w/ less than 2 instructions// in between makes MF UNPREDICTABLE. (2)//// MF{HI or LO} followed by OP {HI and LO} w/ less than 2 instructions// in between makes MF UNPREDICTABLE. (3)//// On the r3900, restriction (2) is not present, and restriction (3) is not// present for multiplication.//// Unfortunately, there seems to be some confusion about whether the last// two restrictions should apply to "MIPS IV" as well. One edition of// the MIPS IV ISA says they do, but references in later ISA documents// suggest they don't.//// In reality, some MIPS IV parts, such as the VR5000 and VR5400, do have// these restrictions, while others, like the VR5500, don't. To accomodate// such differences, the MIPS IV and MIPS V version of these helper functions// use auxillary routines to determine whether the restriction applies.// check_mf_cycles://// Helper used by check_mt_hilo, check_mult_hilo, and check_div_hilo// to check for restrictions (2) and (3) above.//:function:::int:check_mf_cycles:hilo_history *history, signed64 time, const char *new{ if (history->mf.timestamp + 3 > time) { sim_engine_abort (SD, CPU, CIA, "HILO: %s: %s at 0x%08lx too close to MF at 0x%08lx\n", itable[MY_INDEX].name, new, (long) CIA, (long) history->mf.cia); return 0; } return 1;}// check_mt_hilo://// Check for restriction (2) above (for ISAs/processors that have it),// and record timestamps for restriction (1) above.//:function:::int:check_mt_hilo:hilo_history *history*mipsI:*mipsII:*mipsIII:*vr4100:*vr5000:{ signed64 time = sim_events_time (SD); int ok = check_mf_cycles (SD_, history, time, "MT"); history->mt.timestamp = time; history->mt.cia = CIA; return ok;}:function:::int:check_mt_hilo:hilo_history *history*mipsIV:*mipsV:{ signed64 time = sim_events_time (SD); int ok = (! MIPS_MACH_HAS_MT_HILO_HAZARD (SD) || check_mf_cycles (SD_, history, time, "MT")); history->mt.timestamp = time; history->mt.cia = CIA; return ok;}:function:::int:check_mt_hilo:hilo_history *history*mips32:*mips64:*r3900:{ signed64 time = sim_events_time (SD); history->mt.timestamp = time; history->mt.cia = CIA; return 1;}// check_mf_hilo://// Check for restriction (1) above, and record timestamps for// restriction (2) and (3) above.//:function:::int:check_mf_hilo:hilo_history *history, hilo_history *peer*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ signed64 time = sim_events_time (SD); int ok = 1; if (peer != NULL && peer->mt.timestamp > history->op.timestamp && history->mt.timestamp < history->op.timestamp && ! (history->mf.timestamp > history->op.timestamp && history->mf.timestamp < peer->mt.timestamp) && ! (peer->mf.timestamp > history->op.timestamp && peer->mf.timestamp < peer->mt.timestamp)) { /* The peer has been written to since the last OP yet we have not */ sim_engine_abort (SD, CPU, CIA, "HILO: %s: MF at 0x%08lx following OP at 0x%08lx corrupted by MT at 0x%08lx\n", itable[MY_INDEX].name, (long) CIA, (long) history->op.cia, (long) peer->mt.cia); ok = 0; } history->mf.timestamp = time; history->mf.cia = CIA; return ok;}// check_mult_hilo://// Check for restriction (3) above (for ISAs/processors that have it)// for MULT ops, and record timestamps for restriction (1) above.//:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo*mipsI:*mipsII:*mipsIII:*vr4100:*vr5000:{ signed64 time = sim_events_time (SD); int ok = (check_mf_cycles (SD_, hi, time, "OP") && check_mf_cycles (SD_, lo, time, "OP")); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return ok;}:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo*mipsIV:*mipsV:{ signed64 time = sim_events_time (SD); int ok = (! MIPS_MACH_HAS_MULT_HILO_HAZARD (SD) || (check_mf_cycles (SD_, hi, time, "OP") && check_mf_cycles (SD_, lo, time, "OP"))); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return ok;}:function:::int:check_mult_hilo:hilo_history *hi, hilo_history *lo*mips32:*mips64:*r3900:{ /* FIXME: could record the fact that a stall occured if we want */ signed64 time = sim_events_time (SD); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return 1;}// check_div_hilo://// Check for restriction (3) above (for ISAs/processors that have it)// for DIV ops, and record timestamps for restriction (1) above.//:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo*mipsI:*mipsII:*mipsIII:*vr4100:*vr5000:*r3900:{ signed64 time = sim_events_time (SD); int ok = (check_mf_cycles (SD_, hi, time, "OP") && check_mf_cycles (SD_, lo, time, "OP")); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return ok;}:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo*mipsIV:*mipsV:{ signed64 time = sim_events_time (SD); int ok = (! MIPS_MACH_HAS_DIV_HILO_HAZARD (SD) || (check_mf_cycles (SD_, hi, time, "OP") && check_mf_cycles (SD_, lo, time, "OP"))); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return ok;}:function:::int:check_div_hilo:hilo_history *hi, hilo_history *lo*mips32:*mips64:{ signed64 time = sim_events_time (SD); hi->op.timestamp = time; lo->op.timestamp = time; hi->op.cia = CIA; lo->op.cia = CIA; return 1;}// Helper://// Check that the 64-bit instruction can currently be used, and signal// a ReservedInstruction exception if not.//:function:::void:check_u64:instruction_word insn*mipsIII:*mipsIV:*mipsV:*vr4100:*vr5000:{ // The check should be similar to mips64 for any with PX/UX bit equivalents.}:function:::void:check_u64:instruction_word insn*mips64:{#if 0 /* XXX FIXME: enable this only after some additional testing. */ if (UserMode && (SR & (status_UX|status_PX)) == 0) SignalException (ReservedInstruction, insn);#endif}//// MIPS Architecture://// CPU Instruction Set (mipsI - mipsV, mips32, mips64)//000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD"add r<RD>, r<RS>, r<RT>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT])) Unpredictable (); TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]); { ALU32_BEGIN (GPR[RS]); ALU32_ADD (GPR[RT]); ALU32_END (GPR[RD]); /* This checks for overflow. */ } TRACE_ALU_RESULT (GPR[RD]);}001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI"addi r<RT>, r<RS>, <IMMEDIATE>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ if (NotWordValue (GPR[RS])) Unpredictable (); TRACE_ALU_INPUT2 (GPR[RS], EXTEND16 (IMMEDIATE)); { ALU32_BEGIN (GPR[RS]); ALU32_ADD (EXTEND16 (IMMEDIATE)); ALU32_END (GPR[RT]); /* This checks for overflow. */ } TRACE_ALU_RESULT (GPR[RT]);}:function:::void:do_addiu:int rs, int rt, unsigned16 immediate{ if (NotWordValue (GPR[rs])) Unpredictable (); TRACE_ALU_INPUT2 (GPR[rs], EXTEND16 (immediate)); GPR[rt] = EXTEND32 (GPR[rs] + EXTEND16 (immediate)); TRACE_ALU_RESULT (GPR[rt]);}001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU"addiu r<RT>, r<RS>, <IMMEDIATE>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ do_addiu (SD_, RS, RT, IMMEDIATE);}:function:::void:do_addu:int rs, int rt, int rd{ if (NotWordValue (GPR[rs]) || NotWordValue (GPR[rt])) Unpredictable (); TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); GPR[rd] = EXTEND32 (GPR[rs] + GPR[rt]); TRACE_ALU_RESULT (GPR[rd]);}000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU"addu r<RD>, r<RS>, r<RT>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ do_addu (SD_, RS, RT, RD);}:function:::void:do_and:int rs, int rt, int rd{ TRACE_ALU_INPUT2 (GPR[rs], GPR[rt]); GPR[rd] = GPR[rs] & GPR[rt]; TRACE_ALU_RESULT (GPR[rd]);}000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND"and r<RD>, r<RS>, r<RT>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ do_and (SD_, RS, RT, RD);}001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI"andi r<RT>, r<RS>, %#lx<IMMEDIATE>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE); GPR[RT] = GPR[RS] & IMMEDIATE; TRACE_ALU_RESULT (GPR[RT]);}000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ"beq r<RS>, r<RT>, <OFFSET>"*mipsI:*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ address_word offset = EXTEND16 (OFFSET) << 2; if ((signed_word) GPR[RS] == (signed_word) GPR[RT]) { DELAY_SLOT (NIA + offset); }}010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL"beql r<RS>, r<RT>, <OFFSET>"*mipsII:*mipsIII:*mipsIV:*mipsV:*mips32:*mips64:*vr4100:*vr5000:*r3900:{ address_word offset = EXTEND16 (OFFSET) << 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -