📄 simops.c
字号:
unsigned int SD = sfi >> 31; unsigned int R1 = 1; unsigned int OV; unsigned int DBZ = als == 0 ? 1 : 0; unsigned int Q = ~(SS ^ SD) & 1; unsigned int C; unsigned int S; unsigned int i; unsigned long alt = Q ? ~als : als; /* 1st Loop */ alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); Q = C ^ SS; R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); S = alo >> 31; sfi = (sfi << (32-N+1)) | Q; ald = (alo << 1) | (sfi >> 31); if ((alo >> 31) ^ (ald >> 31)) { DBZ = 1; } /* 2nd - N-1th Loop */ for (i = 2; i < N; i++) { alt = Q ? ~als : als; alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); Q = C ^ SS; R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); S = alo >> 31; sfi = (sfi << 1) | Q; ald = (alo << 1) | (sfi >> 31); if ((alo >> 31) ^ (ald >> 31)) { DBZ = 1; } } /* Nth Loop */ alt = Q ? ~als : als; alo = ald + alt + Q; C = (((alt >> 31) & (ald >> 31)) | (((alt >> 31) ^ (ald >> 31)) & (~alo >> 31))); Q = C ^ SS; R1 = (alo == 0) ? 0 : (R1 & (Q ^ (SS ^ SD))); sfi = (sfi << (32-N+1)); ald = alo; /* End */ if (alo != 0) { alt = Q ? ~als : als; alo = ald + alt + Q; } R1 = R1 & ((~alo >> 31) ^ SD); if ((alo != 0) && ((Q ^ (SS ^ SD)) ^ R1)) alo = ald; if (N != 32) ald = sfi = (long) ((sfi >> 1) | (SS ^ SD) << 31) >> (32-N-1) | Q; else ald = sfi = sfi | Q; OV = DBZ | ((alo == 0) ? 0 : R1); * remainder_ptr = alo; /* Adj */ if (((alo != 0) && ((SS ^ SD) ^ R1)) || ((alo == 0) && (SS ^ R1))) alo = ald + 1; else alo = ald; OV = (DBZ | R1) ? OV : ((alo >> 31) & (~ald >> 31)); * quotient_ptr = alo; * overflow_ptr = OV;}/* sdivun imm5, reg1, reg2, reg3 */intOP_1C207E0 (void){ unsigned32 /*unsigned long int*/ quotient; unsigned32 /*unsigned long int*/ remainder; unsigned long int divide_by; unsigned long int divide_this; int overflow = 0; unsigned int imm5; trace_input ("sdivun", OP_IMM_REG_REG_REG, 0); imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); divide_by = State.regs[ OP[0] ]; divide_this = State.regs[ OP[1] ] << imm5; divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); State.regs[ OP[1] ] = quotient; State.regs[ OP[2] >> 11 ] = remainder; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient & 0x80000000) PSW |= PSW_S; trace_output (OP_IMM_REG_REG_REG); return 4;}/* sdivn imm5, reg1, reg2, reg3 */intOP_1C007E0 (void){ signed32 /*signed long int*/ quotient; signed32 /*signed long int*/ remainder; signed long int divide_by; signed long int divide_this; int overflow = 0; unsigned int imm5; trace_input ("sdivn", OP_IMM_REG_REG_REG, 0); imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); divide_by = State.regs[ OP[0] ]; divide_this = State.regs[ OP[1] ] << imm5; divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); State.regs[ OP[1] ] = quotient; State.regs[ OP[2] >> 11 ] = remainder; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient < 0) PSW |= PSW_S; trace_output (OP_IMM_REG_REG_REG); return 4;}/* sdivhun imm5, reg1, reg2, reg3 */intOP_18207E0 (void){ unsigned32 /*unsigned long int*/ quotient; unsigned32 /*unsigned long int*/ remainder; unsigned long int divide_by; unsigned long int divide_this; int overflow = 0; unsigned int imm5; trace_input ("sdivhun", OP_IMM_REG_REG_REG, 0); imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); divide_by = State.regs[ OP[0] ] & 0xffff; divide_this = State.regs[ OP[1] ] << imm5; divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); State.regs[ OP[1] ] = quotient; State.regs[ OP[2] >> 11 ] = remainder; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient & 0x80000000) PSW |= PSW_S; trace_output (OP_IMM_REG_REG_REG); return 4;}/* sdivhn imm5, reg1, reg2, reg3 */intOP_18007E0 (void){ signed32 /*signed long int*/ quotient; signed32 /*signed long int*/ remainder; signed long int divide_by; signed long int divide_this; int overflow = 0; unsigned int imm5; trace_input ("sdivhn", OP_IMM_REG_REG_REG, 0); imm5 = 32 - ((OP[3] & 0x3c0000) >> 17); divide_by = EXTEND16 (State.regs[ OP[0] ]); divide_this = State.regs[ OP[1] ] << imm5; divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); State.regs[ OP[1] ] = quotient; State.regs[ OP[2] >> 11 ] = remainder; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient < 0) PSW |= PSW_S; trace_output (OP_IMM_REG_REG_REG); return 4;}/* divu reg1, reg2, reg3 */intOP_2C207E0 (void){ unsigned long int quotient; unsigned long int remainder; unsigned long int divide_by; unsigned long int divide_this; int overflow = 0; trace_input ("divu", OP_REG_REG_REG, 0); /* Compute the result. */ divide_by = State.regs[ OP[0] ]; divide_this = State.regs[ OP[1] ]; if (divide_by == 0) { overflow = 1; divide_by = 1; } State.regs[ OP[1] ] = quotient = divide_this / divide_by; State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient & 0x80000000) PSW |= PSW_S; trace_output (OP_REG_REG_REG); return 4;}/* div reg1, reg2, reg3 */intOP_2C007E0 (void){ signed long int quotient; signed long int remainder; signed long int divide_by; signed long int divide_this; int overflow = 0; trace_input ("div", OP_REG_REG_REG, 0); /* Compute the result. */ divide_by = State.regs[ OP[0] ]; divide_this = State.regs[ OP[1] ]; if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31))) { overflow = 1; divide_by = 1; } State.regs[ OP[1] ] = quotient = divide_this / divide_by; State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient < 0) PSW |= PSW_S; trace_output (OP_REG_REG_REG); return 4;}/* divhu reg1, reg2, reg3 */intOP_28207E0 (void){ unsigned long int quotient; unsigned long int remainder; unsigned long int divide_by; unsigned long int divide_this; int overflow = 0; trace_input ("divhu", OP_REG_REG_REG, 0); /* Compute the result. */ divide_by = State.regs[ OP[0] ] & 0xffff; divide_this = State.regs[ OP[1] ]; if (divide_by == 0) { overflow = 1; divide_by = 1; } State.regs[ OP[1] ] = quotient = divide_this / divide_by; State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient & 0x80000000) PSW |= PSW_S; trace_output (OP_REG_REG_REG); return 4;}/* divh reg1, reg2, reg3 */intOP_28007E0 (void){ signed long int quotient; signed long int remainder; signed long int divide_by; signed long int divide_this; int overflow = 0; trace_input ("divh", OP_REG_REG_REG, 0); /* Compute the result. */ divide_by = State.regs[ OP[0] ]; divide_this = EXTEND16 (State.regs[ OP[1] ]); if (divide_by == 0 || (divide_by == -1 && divide_this == (1 << 31))) { overflow = 1; divide_by = 1; } State.regs[ OP[1] ] = quotient = divide_this / divide_by; State.regs[ OP[2] >> 11 ] = remainder = divide_this % divide_by; /* Set condition codes. */ PSW &= ~(PSW_Z | PSW_S | PSW_OV); if (overflow) PSW |= PSW_OV; if (quotient == 0) PSW |= PSW_Z; if (quotient < 0) PSW |= PSW_S; trace_output (OP_REG_REG_REG); return 4;}/* mulu imm9, reg2, reg3 */intOP_24207E0 (void){ trace_input ("mulu", OP_IMM_REG_REG, 0); Multiply64 (0, (OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0)); trace_output (OP_IMM_REG_REG); return 4;}/* mul imm9, reg2, reg3 */intOP_24007E0 (void){ trace_input ("mul", OP_IMM_REG_REG, 0); Multiply64 (1, SEXT9 ((OP[3] & 0x1f) | ((OP[3] >> 13) & 0x1e0))); trace_output (OP_IMM_REG_REG); return 4;}/* ld.hu */intOP_107E0 (void){ int adr; trace_input ("ld.hu", OP_LOAD32, 2); adr = State.regs[ OP[0] ] + EXTEND16 (OP[2] & ~1); adr &= ~0x1; State.regs[ OP[1] ] = load_mem (adr, 2); trace_output (OP_LOAD32); return 4;}/* ld.bu */intOP_10780 (void){ int adr; trace_input ("ld.bu", OP_LOAD32, 1); adr = (State.regs[ OP[0] ] + (EXTEND16 (OP[2] & ~1) | ((OP[3] >> 5) & 1))); State.regs[ OP[1] ] = load_mem (adr, 1); trace_output (OP_LOAD32); return 4;}/* prepare list12, imm5, imm32 */intOP_1B0780 (void){ int i; trace_input ("prepare", OP_PUSHPOP1, 0); /* Store the registers with lower number registers being placed at higher addresses. */ for (i = 0; i < 12; i++) if ((OP[3] & (1 << type1_regs[ i ]))) { SP -= 4; store_mem (SP, 4, State.regs[ 20 + i ]); } SP -= (OP[3] & 0x3e) << 1; EP = load_mem (PC + 4, 4); trace_output (OP_PUSHPOP1); return 8;}/* prepare list12, imm5, imm16-32 */intOP_130780 (void){ int i; trace_input ("prepare", OP_PUSHPOP1, 0); /* Store the registers with lower number registers being placed at higher addresses. */ for (i = 0; i < 12; i++) if ((OP[3] & (1 << type1_regs[ i ]))) { SP -= 4; store_mem (SP, 4, State.regs[ 20 + i ]); } SP -= (OP[3] & 0x3e) << 1; EP = load_mem (PC + 4, 2) << 16; trace_output (OP_PUSHPOP1); return 6;}/* prepare list12, imm5, imm16 */intOP_B0780 (void){ int i; trace_input ("prepare", OP_PUSHPOP1, 0); /* Store the registers with lower number registers being placed at higher addresses. */ for (i = 0; i < 12; i++) if ((OP[3] & (1 << type1_regs[ i ]))) { SP -= 4; store_mem (SP, 4, State.regs[ 20 + i ]); } SP -= (OP[3] & 0x3e) << 1; EP = EXTEND16 (load_mem (PC + 4, 2)); trace_output (OP_PUSHPOP1); return 6;}/* prepare list12, imm5, sp */intOP_30780 (void){ int i; trace_input ("prepare", OP_PUSHPOP1, 0); /* Store the registers with lower number registers being placed at higher addresses. */ for (i = 0; i < 12; i++) if ((OP[3] & (1 << type1_regs[ i ]))) { SP -= 4; store_mem (SP, 4, State.regs[ 20 + i ]); } SP -= (OP[3] & 0x3e) << 1; EP = SP; trace_output (OP_PUSHPOP1); return 4;}/* mul reg1, reg2, reg3 */intOP_22007E0 (void){ trace_input ("mul", OP_REG_REG_REG, 0); Multiply64 (1, State.regs[ OP[0] ]); trace_output (OP_REG_REG_REG); return 4;}/* popmh list18 */intOP_307F0 (void){ int i; trace_input ("popmh", OP_PUSHPOP2, 0); if (OP[3] & (1 << 19)) { if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) { FEPSW = load_mem ( SP & ~ 3, 4); FEPC = load_mem ((SP + 4) & ~ 3, 4); } else { EIPSW = load_mem ( SP & ~ 3, 4); EIPC = load_mem ((SP + 4) & ~ 3, 4); } SP += 8; } /* Load the registers with lower number registers being retrieved from higher addresses. */ for (i = 16; i--;) if ((OP[3] & (1 << type2_regs[ i ]))) { State.regs[ i + 16 ] = load_mem (SP & ~ 3, 4); SP += 4; } trace_output (OP_PUSHPOP2); return 4;}/* popml lsit18 */intOP_107F0 (void){ int i; trace_input ("popml", OP_PUSHPOP3, 0); if (OP[3] & (1 << 19)) { if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) { FEPSW = load_mem ( SP & ~ 3, 4); FEPC = load_mem ((SP + 4) & ~ 3, 4); } else { EIPSW = load_mem ( SP & ~ 3, 4); EIPC = load_mem ((SP + 4) & ~ 3, 4); } SP += 8; } if (OP[3] & (1 << 3)) { PSW = load_mem (SP & ~ 3, 4); SP += 4; } /* Load the registers with lower number registers being retrieved from higher addresses. */ for (i = 15; i--;) if ((OP[3] & (1 << type3_regs[ i ]))) { State.regs[ i + 1 ] = load_mem (SP & ~ 3, 4); SP += 4; } trace_output (OP_PUSHPOP2); return 4;}/* pushmh list18 */intOP_307E0 (void){ int i; trace_input ("pushmh", OP_PUSHPOP2, 0); /* Store the registers with lower number registers being placed at higher addresses. */ for (i = 0; i < 16; i++) if ((OP[3] & (1 << type2_regs[ i ]))) { SP -= 4; store_mem (SP & ~ 3, 4, State.regs[ i + 16 ]); } if (OP[3] & (1 << 19)) { SP -= 8; if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) { store_mem ((SP + 4) & ~ 3, 4, FEPC); store_mem ( SP & ~ 3, 4, FEPSW); } else { store_mem ((SP + 4) & ~ 3, 4, EIPC); store_mem ( SP & ~ 3, 4, EIPSW); } } trace_output (OP_PUSHPOP2); return 4;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -