📄 iwmmxt.c
字号:
break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wR [BITS (12, 15)] = r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWMUL (ARMword instr){ ARMdword r = 0; ARMdword s; int i; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wmul\n");#endif for (i = 0; i < 4; i++) if (BIT (21)) /* Signed. */ { long a, b; a = wRHALF (BITS (16, 19), i); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i); b = EXTEND16 (b); s = a * b; if (BIT (20)) r |= ((s >> 16) & 0xffff) << (i * 16); else r |= (s & 0xffff) << (i * 16); } else /* Unsigned. */ { unsigned long a, b; a = wRHALF (BITS (16, 19), i); b = wRHALF (BITS (0, 3), i); s = a * b; if (BIT (20)) r |= ((s >> 16) & 0xffff) << (i * 16); else r |= (s & 0xffff) << (i * 16); } wR [BITS (12, 15)] = r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWOR (ARMword instr){ ARMword psr = 0; ARMdword result; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wor\n");#endif result = wR [BITS (16, 19)] | wR [BITS (0, 3)]; wR [BITS (12, 15)] = result; SIMD64_SET (psr, (result == 0), SIMD_ZBIT); SIMD64_SET (psr, (result & (1ULL << 63)), SIMD_NBIT); wC [wCASF] = psr; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWPACK (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMword psr = 0; ARMdword x; ARMdword s; int i; int satrv[8]; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wpack\n");#endif switch (BITS (22, 23)) { case Hqual: for (i = 0; i < 8; i++) { x = wRHALF (i < 4 ? BITS (16, 19) : BITS (0, 3), i & 3); switch (BITS (20, 21)) { case UnsignedSaturation: s = IwmmxtSaturateU8 (x, satrv + BITIDX8 (i)); break; case SignedSaturation: s = IwmmxtSaturateS8 (x, satrv + BITIDX8 (i)); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } r |= (s & 0xff) << (i * 8); SIMD8_SET (psr, NBIT8 (s), SIMD_NBIT, i); SIMD8_SET (psr, ZBIT8 (s), SIMD_ZBIT, i); } break; case Wqual: satrv[0] = satrv[2] = satrv[4] = satrv[6] = 0; for (i = 0; i < 4; i++) { x = wRWORD (i < 2 ? BITS (16, 19) : BITS (0, 3), i & 1); switch (BITS (20, 21)) { case UnsignedSaturation: s = IwmmxtSaturateU16 (x, satrv + BITIDX16 (i)); break; case SignedSaturation: s = IwmmxtSaturateS16 (x, satrv + BITIDX16 (i)); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } break; case Dqual: satrv[0] = satrv[1] = satrv[2] = satrv[4] = satrv[5] = satrv[6] = 0; for (i = 0; i < 2; i++) { x = wR [i ? BITS (0, 3) : BITS (16, 19)]; switch (BITS (20, 21)) { case UnsignedSaturation: s = IwmmxtSaturateU32 (x, satrv + BITIDX32 (i)); break; case SignedSaturation: s = IwmmxtSaturateS32 (x, satrv + BITIDX32 (i)); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } r |= (s & 0xffffffff) << (i * 32); SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); } break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wC [wCASF] = psr; wR [BITS (12, 15)] = r; SET_wCSSFvec (satrv); wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWROR (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMdword s; ARMword psr = 0; int i; int shift; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wror\n");#endif DECODE_G_BIT (state, instr, shift); switch (BITS (22, 23)) { case Hqual: shift &= 0xf; for (i = 0; i < 4; i++) { s = ((wRHALF (BITS (16, 19), i) & 0xffff) << (16 - shift)) | ((wRHALF (BITS (16, 19), i) & 0xffff) >> shift); r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } break; case Wqual: shift &= 0x1f; for (i = 0; i < 2; i++) { s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << (32 - shift)) | ((wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift); r |= (s & 0xffffffff) << (i * 32); SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); } break; case Dqual: shift &= 0x3f; r = (wR [BITS (16, 19)] >> shift) | (wR [BITS (16, 19)] << (64 - shift)); SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wC [wCASF] = psr; wR [BITS (12, 15)] = r; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWSAD (ARMword instr){ ARMdword r; int s; int i; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wsad\n");#endif /* Z bit. */ r = BIT (20) ? 0 : (wR [BITS (12, 15)] & 0xffffffff); if (BIT (22)) /* Half. */ for (i = 0; i < 4; i++) { s = (wRHALF (BITS (16, 19), i) - wRHALF (BITS (0, 3), i)); r += abs (s); } else /* Byte. */ for (i = 0; i < 8; i++) { s = (wRBYTE (BITS (16, 19), i) - wRBYTE (BITS (0, 3), i)); r += abs (s); } wR [BITS (12, 15)] = r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWSHUFH (ARMword instr){ ARMdword r = 0; ARMword psr = 0; ARMdword s; int i; int imm8; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wshufh\n");#endif imm8 = (BITS (20, 23) << 4) | BITS (0, 3); for (i = 0; i < 4; i++) { s = wRHALF (BITS (16, 19), ((imm8 >> (i * 2) & 3)) & 0xff); r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } wC [wCASF] = psr; wR [BITS (12, 15)] = r; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWSLL (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMdword s; ARMword psr = 0; int i; unsigned shift; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wsll\n");#endif DECODE_G_BIT (state, instr, shift); switch (BITS (22, 23)) { case Hqual: for (i = 0; i < 4; i++) { if (shift > 15) s = 0; else s = ((wRHALF (BITS (16, 19), i) & 0xffff) << shift); r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } break; case Wqual: for (i = 0; i < 2; i++) { if (shift > 31) s = 0; else s = ((wRWORD (BITS (16, 19), i) & 0xffffffff) << shift); r |= (s & 0xffffffff) << (i * 32); SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); } break; case Dqual: if (shift > 63) r = 0; else r = ((wR[BITS (16, 19)] & 0xffffffffffffffff) << shift); SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wC [wCASF] = psr; wR [BITS (12, 15)] = r; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWSRA (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMdword s; ARMword psr = 0; int i; unsigned shift; signed long t; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wsra\n");#endif DECODE_G_BIT (state, instr, shift); switch (BITS (22, 23)) { case Hqual: for (i = 0; i < 4; i++) { if (shift > 15) t = (wRHALF (BITS (16, 19), i) & 0x8000) ? 0xffff : 0; else { t = wRHALF (BITS (16, 19), i); t = EXTEND16 (t); t >>= shift; } s = t; r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } break; case Wqual: for (i = 0; i < 2; i++) { if (shift > 31) t = (wRWORD (BITS (16, 19), i) & 0x80000000) ? 0xffffffff : 0; else { t = wRWORD (BITS (16, 19), i); t >>= shift; } s = t; r |= (s & 0xffffffff) << (i * 32); SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); } break; case Dqual: if (shift > 63) r = (wR [BITS (16, 19)] & 0x8000000000000000) ? 0xffffffffffffffff : 0; else r = ((signed long long) (wR[BITS (16, 19)] & 0xffffffffffffffff) >> shift); SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wC [wCASF] = psr; wR [BITS (12, 15)] = r; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWSRL (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMdword s; ARMword psr = 0; int i; unsigned int shift; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wsrl\n");#endif DECODE_G_BIT (state, instr, shift); switch (BITS (22, 23)) { case Hqual: for (i = 0; i < 4; i++) { if (shift > 15) s = 0; else s = ((unsigned) (wRHALF (BITS (16, 19), i) & 0xffff) >> shift); r |= (s & 0xffff) << (i * 16); SIMD16_SET (psr, NBIT16 (s), SIMD_NBIT, i); SIMD16_SET (psr, ZBIT16 (s), SIMD_ZBIT, i); } break; case Wqual: for (i = 0; i < 2; i++) { if (shift > 31) s = 0; else s = ((unsigned long) (wRWORD (BITS (16, 19), i) & 0xffffffff) >> shift); r |= (s & 0xffffffff) << (i * 32); SIMD32_SET (psr, NBIT32 (s), SIMD_NBIT, i); SIMD32_SET (psr, ZBIT32 (s), SIMD_ZBIT, i); } break; case Dqual: if (shift > 63) r = 0; else r = (wR [BITS (16, 19)] & 0xffffffffffffffff) >> shift; SIMD64_SET (psr, NBIT64 (r), SIMD_NBIT); SIMD64_SET (psr, ZBIT64 (r), SIMD_ZBIT); break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wC [wCASF] = psr; wR [BITS (12, 15)] = r; wC [wCon] |= (WCON_CUP | WCON_MUP); return ARMul_DONE;}static intWSTR (ARMul_State * state, ARMword instr){ ARMword address; int failed; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wstr\n");#endif address = Compute_Iwmmxt_Address (state, instr, & failed); if (failed) return ARMul_CANT; if (BITS (28, 31) == 0xf) { /* WSTRW wCx */ Iwmmxt_Store_Word (state, address, wC [BITS (12, 15)]); } else if (BIT (8) == 0) { if (BIT (22) == 0) /* WSTRB */ Iwmmxt_Store_Byte (state, address, wR [BITS (12, 15)]); else /* WSTRH */ Iwmmxt_Store_Half_Word (state, address, wR [BITS (12, 15)]); } else { if (BIT (22) == 0) /* WSTRW wRd */ Iwmmxt_Store_Word (state, address, wR [BITS (12, 15)]); else /* WSTRD */ Iwmmxt_Store_Double_Word (state, address, wR [BITS (12, 15)]); } return ARMul_DONE;}static intWSUB (ARMul_State * state, ARMword instr){ ARMdword r = 0; ARMword psr = 0; ARMdword x; ARMdword s; int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -