📄 iwmmxt.c
字号:
if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tandc\n");#endif /* The Rd field must be r15. */ if (BITS (12, 15) != 15) return ARMul_CANT; /* The CRn field must be r3. */ if (BITS (16, 19) != 3) return ARMul_CANT; /* The CRm field must be r0. */ if (BITS (0, 3) != 0) return ARMul_CANT; cpsr = ARMul_GetCPSR (state) & 0x0fffffff; switch (BITS (22, 23)) { case Bqual: cpsr |= ( (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 24, 27) & wCBITS (wCASF, 20, 23) & wCBITS (wCASF, 16, 19) & wCBITS (wCASF, 12, 15) & wCBITS (wCASF, 8, 11) & wCBITS (wCASF, 4, 7) & wCBITS (wCASF, 0, 3)) << 28); break; case Hqual: cpsr |= ( (wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 20, 23) & wCBITS (wCASF, 12, 15) & wCBITS (wCASF, 4, 7)) << 28); break; case Wqual: cpsr |= ((wCBITS (wCASF, 28, 31) & wCBITS (wCASF, 12, 15)) << 28); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } ARMul_SetCPSR (state, cpsr); return ARMul_DONE;}static intTBCST (ARMul_State * state, ARMword instr){ ARMdword Rn; int wRd; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tbcst\n");#endif Rn = state->Reg [BITS (12, 15)]; if (BITS (12, 15) == 15) Rn &= 0xfffffffc; wRd = BITS (16, 19); switch (BITS (6, 7)) { case Bqual: Rn &= 0xff; wR [wRd] = (Rn << 56) | (Rn << 48) | (Rn << 40) | (Rn << 32) | (Rn << 24) | (Rn << 16) | (Rn << 8) | Rn; break; case Hqual: Rn &= 0xffff; wR [wRd] = (Rn << 48) | (Rn << 32) | (Rn << 16) | Rn; break; case Wqual: Rn &= 0xffffffff; wR [wRd] = (Rn << 32) | Rn; break; default: ARMul_UndefInstr (state, instr); break; } wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTEXTRC (ARMul_State * state, ARMword instr){ ARMword cpsr; ARMword selector; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "textrc\n");#endif /* The Rd field must be r15. */ if (BITS (12, 15) != 15) return ARMul_CANT; /* The CRn field must be r3. */ if (BITS (16, 19) != 3) return ARMul_CANT; /* The CRm field must be 0xxx. */ if (BIT (3) != 0) return ARMul_CANT; selector = BITS (0, 2); cpsr = ARMul_GetCPSR (state) & 0x0fffffff; switch (BITS (22, 23)) { case Bqual: selector *= 4; break; case Hqual: selector = ((selector & 3) * 8) + 4; break; case Wqual: selector = ((selector & 1) * 16) + 12; break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } cpsr |= wCBITS (wCASF, selector, selector + 3) << 28; ARMul_SetCPSR (state, cpsr); return ARMul_DONE;}static intTEXTRM (ARMul_State * state, ARMword instr){ ARMword Rd; int offset; int wRn; int sign; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "textrm\n");#endif wRn = BITS (16, 19); sign = BIT (3); offset = BITS (0, 2); switch (BITS (22, 23)) { case Bqual: offset *= 8; Rd = wRBITS (wRn, offset, offset + 7); if (sign) Rd = EXTEND8 (Rd); break; case Hqual: offset = (offset & 3) * 16; Rd = wRBITS (wRn, offset, offset + 15); if (sign) Rd = EXTEND16 (Rd); break; case Wqual: offset = (offset & 1) * 32; Rd = wRBITS (wRn, offset, offset + 31); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } if (BITS (12, 15) == 15) ARMul_UndefInstr (state, instr); else state->Reg [BITS (12, 15)] = Rd; return ARMul_DONE;}static intTINSR (ARMul_State * state, ARMword instr){ ARMdword data; ARMword offset; int wRd; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tinsr\n");#endif wRd = BITS (16, 19); data = state->Reg [BITS (12, 15)]; offset = BITS (0, 2); switch (BITS (6, 7)) { case Bqual: data &= 0xff; switch (offset) { case 0: wR [wRd] = data | (wRBITS (wRd, 8, 63) << 8); break; case 1: wR [wRd] = wRBITS (wRd, 0, 7) | (data << 8) | (wRBITS (wRd, 16, 63) << 16); break; case 2: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 24, 63) << 24); break; case 3: wR [wRd] = wRBITS (wRd, 0, 23) | (data << 24) | (wRBITS (wRd, 32, 63) << 32); break; case 4: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 40, 63) << 40); break; case 5: wR [wRd] = wRBITS (wRd, 0, 39) | (data << 40) | (wRBITS (wRd, 48, 63) << 48); break; case 6: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48) | (wRBITS (wRd, 56, 63) << 56); break; case 7: wR [wRd] = wRBITS (wRd, 0, 55) | (data << 56); break; } break; case Hqual: data &= 0xffff; switch (offset & 3) { case 0: wR [wRd] = data | (wRBITS (wRd, 16, 63) << 16); break; case 1: wR [wRd] = wRBITS (wRd, 0, 15) | (data << 16) | (wRBITS (wRd, 32, 63) << 32); break; case 2: wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32) | (wRBITS (wRd, 48, 63) << 48); break; case 3: wR [wRd] = wRBITS (wRd, 0, 47) | (data << 48); break; } break; case Wqual: if (offset & 1) wR [wRd] = wRBITS (wRd, 0, 31) | (data << 32); else wR [wRd] = (wRBITS (wRd, 32, 63) << 32) | data; break; default: ARMul_UndefInstr (state, instr); break; } wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTMCR (ARMul_State * state, ARMword instr){ ARMword val; int wCreg; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmcr\n");#endif if (BITS (0, 3) != 0) return ARMul_CANT; val = state->Reg [BITS (12, 15)]; if (BITS (12, 15) == 15) val &= 0xfffffffc; wCreg = BITS (16, 19); switch (wCreg) { case wCID: /* The wCID register is read only. */ break; case wCon: /* Writing to the MUP or CUP bits clears them. */ wC [wCon] &= ~ (val & 0x3); break; case wCSSF: /* Only the bottom 8 bits can be written to. The higher bits write as zero. */ wC [wCSSF] = (val & 0xff); wC [wCon] |= WCON_CUP; break; default: wC [wCreg] = val; wC [wCon] |= WCON_CUP; break; } return ARMul_DONE;}static intTMCRR (ARMul_State * state, ARMword instr){ ARMdword RdHi = state->Reg [BITS (16, 19)]; ARMword RdLo = state->Reg [BITS (12, 15)]; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmcrr\n");#endif if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15)) return ARMul_CANT; wR [BITS (0, 3)] = (RdHi << 32) | RdLo; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTMIA (ARMul_State * state, ARMword instr){ signed long long a, b; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmia\n");#endif if ((BITS (0, 3) == 15) || (BITS (12, 15) == 15)) { ARMul_UndefInstr (state, instr); return ARMul_DONE; } a = state->Reg [BITS (0, 3)]; b = state->Reg [BITS (12, 15)]; a = EXTEND32 (a); b = EXTEND32 (b); wR [BITS (5, 8)] += a * b; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTMIAPH (ARMul_State * state, ARMword instr){ signed long a, b, result; signed long long r; ARMword Rm = state->Reg [BITS (0, 3)]; ARMword Rs = state->Reg [BITS (12, 15)]; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmiaph\n");#endif if (BITS (0, 3) == 15 || BITS (12, 15) == 15) { ARMul_UndefInstr (state, instr); return ARMul_DONE; } a = SUBSTR (Rs, ARMword, 16, 31); b = SUBSTR (Rm, ARMword, 16, 31); a = EXTEND16 (a); b = EXTEND16 (b); result = a * b; r = result; r = EXTEND32 (r); wR [BITS (5, 8)] += r; a = SUBSTR (Rs, ARMword, 0, 15); b = SUBSTR (Rm, ARMword, 0, 15); a = EXTEND16 (a); b = EXTEND16 (b); result = a * b; r = result; r = EXTEND32 (r); wR [BITS (5, 8)] += r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTMIAxy (ARMul_State * state, ARMword instr){ ARMword Rm; ARMword Rs; long long temp; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmiaxy\n");#endif if (BITS (0, 3) == 15 || BITS (12, 15) == 15) { ARMul_UndefInstr (state, instr); return ARMul_DONE; } Rm = state->Reg [BITS (0, 3)]; if (BIT (17)) Rm >>= 16; else Rm &= 0xffff; Rs = state->Reg [BITS (12, 15)]; if (BIT (16)) Rs >>= 16; else Rs &= 0xffff; if (Rm & (1 << 15)) Rm -= 1 << 16; if (Rs & (1 << 15)) Rs -= 1 << 16; Rm *= Rs; temp = Rm; if (temp & (1 << 31)) temp -= 1ULL << 32; wR [BITS (5, 8)] += temp; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intTMOVMSK (ARMul_State * state, ARMword instr){ ARMdword result; int wRn; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmovmsk\n");#endif /* The CRm field must be r0. */ if (BITS (0, 3) != 0) return ARMul_CANT; wRn = BITS (16, 19); switch (BITS (22, 23)) { case Bqual: result = ( (wRBITS (wRn, 63, 63) << 7) | (wRBITS (wRn, 55, 55) << 6) | (wRBITS (wRn, 47, 47) << 5) | (wRBITS (wRn, 39, 39) << 4) | (wRBITS (wRn, 31, 31) << 3) | (wRBITS (wRn, 23, 23) << 2) | (wRBITS (wRn, 15, 15) << 1) | (wRBITS (wRn, 7, 7) << 0)); break; case Hqual: result = ( (wRBITS (wRn, 63, 63) << 3) | (wRBITS (wRn, 47, 47) << 2) | (wRBITS (wRn, 31, 31) << 1) | (wRBITS (wRn, 15, 15) << 0)); break; case Wqual: result = (wRBITS (wRn, 63, 63) << 1) | wRBITS (wRn, 31, 31); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } state->Reg [BITS (12, 15)] = result; return ARMul_DONE;}static intTMRC (ARMul_State * state, ARMword instr){ int reg = BITS (12, 15); if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmrc\n");#endif if (BITS (0, 3) != 0) return ARMul_CANT; if (reg == 15) ARMul_UndefInstr (state, instr); else state->Reg [reg] = wC [BITS (16, 19)]; return ARMul_DONE;}static intTMRRC (ARMul_State * state, ARMword instr){ if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "tmrrc\n");#endif if ((BITS (16, 19) == 15) || (BITS (12, 15) == 15) || (BITS (4, 11) != 0)) ARMul_UndefInstr (state, instr); else { state->Reg [BITS (16, 19)] = wRBITS (BITS (0, 3), 32, 63); state->Reg [BITS (12, 15)] = wRBITS (BITS (0, 3), 0, 31); } return ARMul_DONE;}static intTORC (ARMul_State * state, ARMword instr){ ARMword cpsr = ARMul_GetCPSR (state); if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "torc\n");#endif /* The Rd field must be r15. */ if (BITS (12, 15) != 15) return ARMul_CANT; /* The CRn field must be r3. */ if (BITS (16, 19) != 3) return ARMul_CANT; /* The CRm field must be r0. */ if (BITS (0, 3) != 0) return ARMul_CANT; cpsr &= 0x0fffffff; switch (BITS (22, 23)) { case Bqual: cpsr |= ( (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 24, 27) | wCBITS (wCASF, 20, 23) | wCBITS (wCASF, 16, 19) | wCBITS (wCASF, 12, 15) | wCBITS (wCASF, 8, 11) | wCBITS (wCASF, 4, 7) | wCBITS (wCASF, 0, 3)) << 28); break; case Hqual: cpsr |= ( (wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 20, 23) | wCBITS (wCASF, 12, 15) | wCBITS (wCASF, 4, 7)) << 28); break; case Wqual: cpsr |= ((wCBITS (wCASF, 28, 31) | wCBITS (wCASF, 12, 15)) << 28); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } ARMul_SetCPSR (state, cpsr); return ARMul_DONE;}static intWACC (ARMul_State * state, ARMword instr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -