📄 iwmmxt.c
字号:
increment = - (offset * multiplier); state->Reg [Rn] = addr + increment; } } else { /* P == 0, W == 0, U == 0 is UNPREDICTABLE. */ if (BIT (23) == 0) {#ifdef DEBUG fprintf (stderr, "iWMMXt: undefined addressing mode\n");#endif * pFailed = 1; } } } return addr;}static ARMdwordIwmmxt_Load_Double_Word (ARMul_State * state, ARMword address){ ARMdword value; /* The address must be aligned on a 8 byte boundary. */ if (address & 0x7) { fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word load from 0x%x\n", (state->Reg[15] - 8) & ~0x3, address);#ifdef DEBUG#endif /* No need to check for alignment traps. An unaligned double word load with alignment trapping disabled is UNPREDICTABLE. */ ARMul_Abort (state, ARMul_DataAbortV); } /* Load the words. */ if (! state->bigendSig) { value = ARMul_LoadWordN (state, address + 4); value <<= 32; value |= ARMul_LoadWordN (state, address); } else { value = ARMul_LoadWordN (state, address); value <<= 32; value |= ARMul_LoadWordN (state, address + 4); } /* Check for data aborts. */ if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV); else ARMul_Icycles (state, 2, 0L); return value;}static ARMwordIwmmxt_Load_Word (ARMul_State * state, ARMword address){ ARMword value; /* Check for a misaligned address. */ if (address & 3) { if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) ARMul_Abort (state, ARMul_DataAbortV); else address &= ~ 3; } value = ARMul_LoadWordN (state, address); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV); else ARMul_Icycles (state, 1, 0L); return value;}static ARMwordIwmmxt_Load_Half_Word (ARMul_State * state, ARMword address){ ARMword value; /* Check for a misaligned address. */ if (address & 1) { if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) ARMul_Abort (state, ARMul_DataAbortV); else address &= ~ 1; } value = ARMul_LoadHalfWord (state, address); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV); else ARMul_Icycles (state, 1, 0L); return value;}static ARMwordIwmmxt_Load_Byte (ARMul_State * state, ARMword address){ ARMword value; value = ARMul_LoadByte (state, address); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV); else ARMul_Icycles (state, 1, 0L); return value;}static voidIwmmxt_Store_Double_Word (ARMul_State * state, ARMword address, ARMdword value){ /* The address must be aligned on a 8 byte boundary. */ if (address & 0x7) { fprintf (stderr, "iWMMXt: At addr 0x%x: Unaligned double word store to 0x%x\n", (state->Reg[15] - 8) & ~0x3, address);#ifdef DEBUG#endif /* No need to check for alignment traps. An unaligned double word store with alignment trapping disabled is UNPREDICTABLE. */ ARMul_Abort (state, ARMul_DataAbortV); } /* Store the words. */ if (! state->bigendSig) { ARMul_StoreWordN (state, address, value); ARMul_StoreWordN (state, address + 4, value >> 32); } else { ARMul_StoreWordN (state, address + 4, value); ARMul_StoreWordN (state, address, value >> 32); } /* Check for data aborts. */ if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV); else ARMul_Icycles (state, 2, 0L);}static voidIwmmxt_Store_Word (ARMul_State * state, ARMword address, ARMword value){ /* Check for a misaligned address. */ if (address & 3) { if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) ARMul_Abort (state, ARMul_DataAbortV); else address &= ~ 3; } ARMul_StoreWordN (state, address, value); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV);}static voidIwmmxt_Store_Half_Word (ARMul_State * state, ARMword address, ARMword value){ /* Check for a misaligned address. */ if (address & 1) { if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN)) ARMul_Abort (state, ARMul_DataAbortV); else address &= ~ 1; } ARMul_StoreHalfWord (state, address, value); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV);}static voidIwmmxt_Store_Byte (ARMul_State * state, ARMword address, ARMword value){ ARMul_StoreByte (state, address, value); if (state->Aborted) ARMul_Abort (state, ARMul_DataAbortV);}static intWLDR (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, "wldr\n");#endif address = Compute_Iwmmxt_Address (state, instr, & failed); if (failed) return ARMul_CANT; if (BITS (28, 31) == 0xf) { /* WLDRW wCx */ wC [BITS (12, 15)] = Iwmmxt_Load_Word (state, address); } else if (BIT (8) == 0) { if (BIT (22) == 0) /* WLDRB */ wR [BITS (12, 15)] = Iwmmxt_Load_Byte (state, address); else /* WLDRH */ wR [BITS (12, 15)] = Iwmmxt_Load_Half_Word (state, address); } else { if (BIT (22) == 0) /* WLDRW wRd */ wR [BITS (12, 15)] = Iwmmxt_Load_Word (state, address); else /* WLDRD */ wR [BITS (12, 15)] = Iwmmxt_Load_Double_Word (state, address); } wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWMAC (ARMword instr){ int i; ARMdword t = 0; ARMword a, b; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wmac\n");#endif for (i = 0; i < 4; i++) { if (BIT (21)) { /* Signed. */ signed long s; a = wRHALF (BITS (16, 19), i); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i); b = EXTEND16 (b); s = (signed long) a * (signed long) b; (signed long long) t += s; } else { /* Unsigned. */ a = wRHALF (BITS (16, 19), i); b = wRHALF (BITS ( 0, 3), i); t += a * b; } } if (BIT (20)) wR [BITS (12, 15)] = 0; if (BIT (21)) /* Signed. */ (signed long long) wR[BITS (12, 15)] += (signed long long) t; else wR [BITS (12, 15)] += t; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWMADD (ARMword instr){ ARMdword r = 0; int i; if ((read_cp15_reg (15, 0, 1) & 3) != 3) return ARMul_CANT;#ifdef DEBUG fprintf (stderr, "wmadd\n");#endif for (i = 0; i < 2; i++) { ARMdword s1, s2; if (BIT (21)) /* Signed. */ { signed long a, b; a = wRHALF (BITS (16, 19), i * 2); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i * 2); b = EXTEND16 (b); (signed long) s1 = a * b; a = wRHALF (BITS (16, 19), i * 2 + 1); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i * 2 + 1); b = EXTEND16 (b); (signed long) s2 = a * b; } else /* Unsigned. */ { unsigned long a, b; a = wRHALF (BITS (16, 19), i * 2); b = wRHALF (BITS ( 0, 3), i * 2); (unsigned long) s1 = a * b; a = wRHALF (BITS (16, 19), i * 2 + 1); b = wRHALF (BITS ( 0, 3), i * 2 + 1); (signed long) s2 = a * b; } r |= (ARMdword) ((s1 + s2) & 0xffffffff) << (i ? 32 : 0); } wR [BITS (12, 15)] = r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWMAX (ARMul_State * state, 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, "wmax\n");#endif switch (BITS (22, 23)) { case Bqual: for (i = 0; i < 8; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRBYTE (BITS (16, 19), i); a = EXTEND8 (a); b = wRBYTE (BITS (0, 3), i); b = EXTEND8 (b); if (a > b) s = a; else s = b; r |= (s & 0xff) << (i * 8); } else /* Unsigned. */ { unsigned int a, b; a = wRBYTE (BITS (16, 19), i); b = wRBYTE (BITS (0, 3), i); if (a > b) s = a; else s = b; r |= (s & 0xff) << (i * 8); } break; case Hqual: for (i = 0; i < 4; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRHALF (BITS (16, 19), i); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i); b = EXTEND16 (b); if (a > b) s = a; else s = b; r |= (s & 0xffff) << (i * 16); } else /* Unsigned. */ { unsigned int a, b; a = wRHALF (BITS (16, 19), i); b = wRHALF (BITS (0, 3), i); if (a > b) s = a; else s = b; r |= (s & 0xffff) << (i * 16); } break; case Wqual: for (i = 0; i < 2; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRWORD (BITS (16, 19), i); b = wRWORD (BITS (0, 3), i); if (a > b) s = a; else s = b; r |= (s & 0xffffffff) << (i * 32); } else { unsigned int a, b; a = wRWORD (BITS (16, 19), i); b = wRWORD (BITS (0, 3), i); if (a > b) s = a; else s = b; r |= (s & 0xffffffff) << (i * 32); } break; default: ARMul_UndefInstr (state, instr); return ARMul_DONE; } wR [BITS (12, 15)] = r; wC [wCon] |= WCON_MUP; return ARMul_DONE;}static intWMIN (ARMul_State * state, 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, "wmin\n");#endif switch (BITS (22, 23)) { case Bqual: for (i = 0; i < 8; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRBYTE (BITS (16, 19), i); a = EXTEND8 (a); b = wRBYTE (BITS (0, 3), i); b = EXTEND8 (b); if (a < b) s = a; else s = b; r |= (s & 0xff) << (i * 8); } else /* Unsigned. */ { unsigned int a, b; a = wRBYTE (BITS (16, 19), i); b = wRBYTE (BITS (0, 3), i); if (a < b) s = a; else s = b; r |= (s & 0xff) << (i * 8); } break; case Hqual: for (i = 0; i < 4; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRHALF (BITS (16, 19), i); a = EXTEND16 (a); b = wRHALF (BITS (0, 3), i); b = EXTEND16 (b); if (a < b) s = a; else s = b; r |= (s & 0xffff) << (i * 16); } else { /* Unsigned. */ unsigned int a, b; a = wRHALF (BITS (16, 19), i); b = wRHALF (BITS ( 0, 3), i); if (a < b) s = a; else s = b; r |= (s & 0xffff) << (i * 16); } break; case Wqual: for (i = 0; i < 2; i++) if (BIT (21)) /* Signed. */ { int a, b; a = wRWORD (BITS (16, 19), i); b = wRWORD (BITS ( 0, 3), i); if (a < b) s = a; else s = b; r |= (s & 0xffffffff) << (i * 32); } else { unsigned int a, b; a = wRWORD (BITS (16, 19), i); b = wRWORD (BITS (0, 3), i); if (a < b) s = a; else s = b; r |= (s & 0xffffffff) << (i * 32); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -