diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 896 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 1 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpsingle.cpp | 7 |
3 files changed, 485 insertions, 419 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index 825955ade..ec40881f8 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -1166,7 +1166,7 @@ mainswitch: | |||
| 1166 | else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) { | 1166 | else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) { |
| 1167 | //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) | 1167 | //(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) |
| 1168 | unsigned msb ,tmp_rn, tmp_rd, dst; | 1168 | unsigned msb ,tmp_rn, tmp_rd, dst; |
| 1169 | msb = tmp_rd = tmp_rn = dst = 0; | 1169 | tmp_rd = tmp_rn = dst = 0; |
| 1170 | Rd = BITS(12, 15); | 1170 | Rd = BITS(12, 15); |
| 1171 | Rn = BITS(0, 3); | 1171 | Rn = BITS(0, 3); |
| 1172 | lsb = BITS(7, 11); | 1172 | lsb = BITS(7, 11); |
| @@ -1737,7 +1737,7 @@ mainswitch: | |||
| 1737 | //chy 2006-02-15 if in user mode, can not set cpsr 0:23 | 1737 | //chy 2006-02-15 if in user mode, can not set cpsr 0:23 |
| 1738 | //from p165 of ARMARM book | 1738 | //from p165 of ARMARM book |
| 1739 | state->Cpsr = GETSPSR (state->Bank); | 1739 | state->Cpsr = GETSPSR (state->Bank); |
| 1740 | //ARMul_CPSRAltered (state); | 1740 | ARMul_CPSRAltered (state); |
| 1741 | #else | 1741 | #else |
| 1742 | rhs = DPRegRHS; | 1742 | rhs = DPRegRHS; |
| 1743 | temp = LHS & rhs; | 1743 | temp = LHS & rhs; |
| @@ -1877,7 +1877,7 @@ mainswitch: | |||
| 1877 | /* TEQP reg */ | 1877 | /* TEQP reg */ |
| 1878 | #ifdef MODE32 | 1878 | #ifdef MODE32 |
| 1879 | state->Cpsr = GETSPSR (state->Bank); | 1879 | state->Cpsr = GETSPSR (state->Bank); |
| 1880 | //ARMul_CPSRAltered (state); | 1880 | ARMul_CPSRAltered (state); |
| 1881 | #else | 1881 | #else |
| 1882 | rhs = DPRegRHS; | 1882 | rhs = DPRegRHS; |
| 1883 | temp = LHS ^ rhs; | 1883 | temp = LHS ^ rhs; |
| @@ -1993,7 +1993,7 @@ mainswitch: | |||
| 1993 | /* CMPP reg. */ | 1993 | /* CMPP reg. */ |
| 1994 | #ifdef MODE32 | 1994 | #ifdef MODE32 |
| 1995 | state->Cpsr = GETSPSR (state->Bank); | 1995 | state->Cpsr = GETSPSR (state->Bank); |
| 1996 | //ARMul_CPSRAltered (state); | 1996 | ARMul_CPSRAltered (state); |
| 1997 | #else | 1997 | #else |
| 1998 | rhs = DPRegRHS; | 1998 | rhs = DPRegRHS; |
| 1999 | temp = LHS - rhs; | 1999 | temp = LHS - rhs; |
| @@ -2112,7 +2112,7 @@ mainswitch: | |||
| 2112 | if (DESTReg == 15) { | 2112 | if (DESTReg == 15) { |
| 2113 | #ifdef MODE32 | 2113 | #ifdef MODE32 |
| 2114 | state->Cpsr = GETSPSR (state->Bank); | 2114 | state->Cpsr = GETSPSR (state->Bank); |
| 2115 | //ARMul_CPSRAltered (state); | 2115 | ARMul_CPSRAltered (state); |
| 2116 | #else | 2116 | #else |
| 2117 | rhs = DPRegRHS; | 2117 | rhs = DPRegRHS; |
| 2118 | temp = LHS + rhs; | 2118 | temp = LHS + rhs; |
| @@ -2200,17 +2200,57 @@ mainswitch: | |||
| 2200 | Handle_Store_Double (state, instr); | 2200 | Handle_Store_Double (state, instr); |
| 2201 | break; | 2201 | break; |
| 2202 | } | 2202 | } |
| 2203 | if (BITS(4, 11) == 0xF9) { //strexd | ||
| 2204 | u32 l = LHSReg; | ||
| 2205 | |||
| 2206 | bool enter = false; | ||
| 2207 | |||
| 2208 | if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&& | ||
| 2209 | state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4)) | ||
| 2210 | enter = true; | ||
| 2211 | |||
| 2212 | |||
| 2213 | //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html | ||
| 2214 | |||
| 2215 | |||
| 2216 | if (enter) { | ||
| 2217 | ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]); | ||
| 2218 | ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]); | ||
| 2219 | state->Reg[DESTReg] = 0; | ||
| 2220 | } else { | ||
| 2221 | state->Reg[DESTReg] = 1; | ||
| 2222 | } | ||
| 2223 | |||
| 2224 | break; | ||
| 2225 | } | ||
| 2203 | #endif | 2226 | #endif |
| 2204 | dest = DPRegRHS; | 2227 | dest = DPRegRHS; |
| 2205 | WRITEDEST (dest); | 2228 | WRITEDEST (dest); |
| 2206 | break; | 2229 | break; |
| 2207 | 2230 | ||
| 2208 | case 0x1b: /* MOVS reg */ | 2231 | case 0x1B: /* MOVS reg */ |
| 2209 | #ifdef MODET | 2232 | #ifdef MODET |
| 2233 | /* ldrexd ichfly */ | ||
| 2234 | if (BITS(0, 11) == 0xF9F) { //strexd | ||
| 2235 | lhs = LHS; | ||
| 2236 | |||
| 2237 | state->currentexaddr = lhs; | ||
| 2238 | state->currentexval = (u32)ARMul_ReadWord(state, lhs); | ||
| 2239 | state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4); | ||
| 2240 | |||
| 2241 | state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs); | ||
| 2242 | state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4); | ||
| 2243 | break; | ||
| 2244 | } | ||
| 2245 | |||
| 2210 | if ((BITS (4, 11) & 0xF9) == 0x9) | 2246 | if ((BITS (4, 11) & 0xF9) == 0x9) |
| 2211 | /* LDR register offset, write-back, up, pre indexed. */ | 2247 | /* LDR register offset, write-back, up, pre indexed. */ |
| 2212 | LHPREUPWB (); | 2248 | LHPREUPWB (); |
| 2213 | /* Continue with remaining instruction decoding. */ | 2249 | /* Continue with remaining instruction decoding. */ |
| 2250 | |||
| 2251 | |||
| 2252 | |||
| 2253 | |||
| 2214 | #endif | 2254 | #endif |
| 2215 | dest = DPSRegRHS; | 2255 | dest = DPSRegRHS; |
| 2216 | WRITESDEST (dest); | 2256 | WRITESDEST (dest); |
| @@ -2297,12 +2337,12 @@ mainswitch: | |||
| 2297 | if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; | 2337 | if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; |
| 2298 | 2338 | ||
| 2299 | 2339 | ||
| 2300 | ARMul_StoreHalfWord(state, lhs, RHS); | ||
| 2301 | //StoreWord(state, lhs, RHS) | 2340 | //StoreWord(state, lhs, RHS) |
| 2302 | if (state->Aborted) { | 2341 | if (state->Aborted) { |
| 2303 | TAKEABORT; | 2342 | TAKEABORT; |
| 2304 | } | 2343 | } |
| 2305 | if (enter) { | 2344 | if (enter) { |
| 2345 | ARMul_StoreHalfWord(state, lhs, RHS); | ||
| 2306 | state->Reg[DESTReg] = 0; | 2346 | state->Reg[DESTReg] = 0; |
| 2307 | } else { | 2347 | } else { |
| 2308 | state->Reg[DESTReg] = 1; | 2348 | state->Reg[DESTReg] = 1; |
| @@ -2520,7 +2560,7 @@ mainswitch: | |||
| 2520 | /* TSTP immed. */ | 2560 | /* TSTP immed. */ |
| 2521 | #ifdef MODE32 | 2561 | #ifdef MODE32 |
| 2522 | state->Cpsr = GETSPSR (state->Bank); | 2562 | state->Cpsr = GETSPSR (state->Bank); |
| 2523 | //ARMul_CPSRAltered (state); | 2563 | ARMul_CPSRAltered (state); |
| 2524 | #else | 2564 | #else |
| 2525 | temp = LHS & DPImmRHS; | 2565 | temp = LHS & DPImmRHS; |
| 2526 | SETR15PSR (temp); | 2566 | SETR15PSR (temp); |
| @@ -2547,7 +2587,7 @@ mainswitch: | |||
| 2547 | /* TEQP immed. */ | 2587 | /* TEQP immed. */ |
| 2548 | #ifdef MODE32 | 2588 | #ifdef MODE32 |
| 2549 | state->Cpsr = GETSPSR (state->Bank); | 2589 | state->Cpsr = GETSPSR (state->Bank); |
| 2550 | //ARMul_CPSRAltered (state); | 2590 | ARMul_CPSRAltered (state); |
| 2551 | #else | 2591 | #else |
| 2552 | temp = LHS ^ DPImmRHS; | 2592 | temp = LHS ^ DPImmRHS; |
| 2553 | SETR15PSR (temp); | 2593 | SETR15PSR (temp); |
| @@ -2568,7 +2608,7 @@ mainswitch: | |||
| 2568 | /* CMPP immed. */ | 2608 | /* CMPP immed. */ |
| 2569 | #ifdef MODE32 | 2609 | #ifdef MODE32 |
| 2570 | state->Cpsr = GETSPSR (state->Bank); | 2610 | state->Cpsr = GETSPSR (state->Bank); |
| 2571 | //ARMul_CPSRAltered (state); | 2611 | ARMul_CPSRAltered (state); |
| 2572 | #else | 2612 | #else |
| 2573 | temp = LHS - DPImmRHS; | 2613 | temp = LHS - DPImmRHS; |
| 2574 | SETR15PSR (temp); | 2614 | SETR15PSR (temp); |
| @@ -2604,7 +2644,7 @@ mainswitch: | |||
| 2604 | /* CMNP immed. */ | 2644 | /* CMNP immed. */ |
| 2605 | #ifdef MODE32 | 2645 | #ifdef MODE32 |
| 2606 | state->Cpsr = GETSPSR (state->Bank); | 2646 | state->Cpsr = GETSPSR (state->Bank); |
| 2607 | //ARMul_CPSRAltered (state); | 2647 | ARMul_CPSRAltered (state); |
| 2608 | #else | 2648 | #else |
| 2609 | temp = LHS + DPImmRHS; | 2649 | temp = LHS + DPImmRHS; |
| 2610 | SETR15PSR (temp); | 2650 | SETR15PSR (temp); |
| @@ -3055,17 +3095,14 @@ mainswitch: | |||
| 3055 | 3095 | ||
| 3056 | case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ | 3096 | case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ |
| 3057 | //ichfly PKHBT PKHTB todo check this | 3097 | //ichfly PKHBT PKHTB todo check this |
| 3058 | if ((instr & 0x70) == 0x10) //pkhbt | 3098 | if ((instr & 0x70) == 0x10) { //pkhbt |
| 3059 | { | ||
| 3060 | u8 idest = BITS(12, 15); | 3099 | u8 idest = BITS(12, 15); |
| 3061 | u8 rfis = BITS(16, 19); | 3100 | u8 rfis = BITS(16, 19); |
| 3062 | u8 rlast = BITS(0, 3); | 3101 | u8 rlast = BITS(0, 3); |
| 3063 | u8 ishi = BITS(7,11); | 3102 | u8 ishi = BITS(7,11); |
| 3064 | state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); | 3103 | state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); |
| 3065 | break; | 3104 | break; |
| 3066 | } | 3105 | } else if ((instr & 0x70) == 0x50) { //pkhtb |
| 3067 | else if ((instr & 0x70) == 0x50)//pkhtb | ||
| 3068 | { | ||
| 3069 | u8 idest = BITS(12, 15); | 3106 | u8 idest = BITS(12, 15); |
| 3070 | u8 rfis = BITS(16, 19); | 3107 | u8 rfis = BITS(16, 19); |
| 3071 | u8 rlast = BITS(0, 3); | 3108 | u8 rlast = BITS(0, 3); |
| @@ -3073,8 +3110,7 @@ mainswitch: | |||
| 3073 | if (ishi == 0)ishi = 0x20; | 3110 | if (ishi == 0)ishi = 0x20; |
| 3074 | state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000); | 3111 | state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000); |
| 3075 | break; | 3112 | break; |
| 3076 | } | 3113 | } else if (BIT (4)) { |
| 3077 | else if (BIT (4)) { | ||
| 3078 | #ifdef MODE32 | 3114 | #ifdef MODE32 |
| 3079 | if (state->is_v6 | 3115 | if (state->is_v6 |
| 3080 | && handle_v6_insn (state, instr)) | 3116 | && handle_v6_insn (state, instr)) |
| @@ -3686,13 +3722,11 @@ mainswitch: | |||
| 3686 | 3722 | ||
| 3687 | /* Co-Processor Data Transfers. */ | 3723 | /* Co-Processor Data Transfers. */ |
| 3688 | case 0xc4: | 3724 | case 0xc4: |
| 3689 | if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 | 3725 | if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 |
| 3690 | { | ||
| 3691 | state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)]; | 3726 | state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)]; |
| 3692 | state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; | 3727 | state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; |
| 3693 | break; | 3728 | break; |
| 3694 | } | 3729 | } else if (state->is_v5) { |
| 3695 | else if (state->is_v5) { | ||
| 3696 | /* Reading from R15 is UNPREDICTABLE. */ | 3730 | /* Reading from R15 is UNPREDICTABLE. */ |
| 3697 | if (BITS (12, 15) == 15 || BITS (16, 19) == 15) | 3731 | if (BITS (12, 15) == 15 || BITS (16, 19) == 15) |
| 3698 | ARMul_UndefInstr (state, instr); | 3732 | ARMul_UndefInstr (state, instr); |
| @@ -3712,22 +3746,18 @@ mainswitch: | |||
| 3712 | break; | 3746 | break; |
| 3713 | 3747 | ||
| 3714 | case 0xc5: | 3748 | case 0xc5: |
| 3715 | if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 | 3749 | if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 |
| 3716 | { | ||
| 3717 | state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1]; | 3750 | state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1]; |
| 3718 | state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; | 3751 | state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; |
| 3719 | break; | 3752 | break; |
| 3720 | } | 3753 | } else if (state->is_v5) { |
| 3721 | else if (state->is_v5) { | ||
| 3722 | /* Writes to R15 are UNPREDICATABLE. */ | 3754 | /* Writes to R15 are UNPREDICATABLE. */ |
| 3723 | if (DESTReg == 15 || LHSReg == 15) | 3755 | if (DESTReg == 15 || LHSReg == 15) |
| 3724 | ARMul_UndefInstr (state, instr); | 3756 | ARMul_UndefInstr (state, instr); |
| 3725 | /* Is access to the coprocessor allowed ? */ | 3757 | /* Is access to the coprocessor allowed ? */ |
| 3726 | else if (!CP_ACCESS_ALLOWED(state, CPNum)) | 3758 | else if (!CP_ACCESS_ALLOWED(state, CPNum)) { |
| 3727 | { | ||
| 3728 | ARMul_UndefInstr(state, instr); | 3759 | ARMul_UndefInstr(state, instr); |
| 3729 | } | 3760 | } else { |
| 3730 | else { | ||
| 3731 | /* MRRC, ARMv5TE and up */ | 3761 | /* MRRC, ARMv5TE and up */ |
| 3732 | ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); | 3762 | ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); |
| 3733 | break; | 3763 | break; |
| @@ -4565,7 +4595,7 @@ out: | |||
| 4565 | #ifdef MODE32 | 4595 | #ifdef MODE32 |
| 4566 | if (state->Bank > 0) { | 4596 | if (state->Bank > 0) { |
| 4567 | state->Cpsr = state->Spsr[state->Bank]; | 4597 | state->Cpsr = state->Spsr[state->Bank]; |
| 4568 | //ARMul_CPSRAltered (state); | 4598 | ARMul_CPSRAltered (state); |
| 4569 | } | 4599 | } |
| 4570 | #ifdef MODET | 4600 | #ifdef MODET |
| 4571 | if (TFLAG) | 4601 | if (TFLAG) |
| @@ -5256,7 +5286,7 @@ L_ldm_s_makeabort: | |||
| 5256 | //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode | 5286 | //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode |
| 5257 | if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { | 5287 | if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { |
| 5258 | state->Cpsr = GETSPSR (state->Bank); | 5288 | state->Cpsr = GETSPSR (state->Bank); |
| 5259 | //ARMul_CPSRAltered (state); | 5289 | ARMul_CPSRAltered (state); |
| 5260 | } | 5290 | } |
| 5261 | 5291 | ||
| 5262 | WriteR15 (state, PC); | 5292 | WriteR15 (state, PC); |
| @@ -5641,30 +5671,9 @@ L_stm_s_takeabort: | |||
| 5641 | 5671 | ||
| 5642 | static int | 5672 | static int |
| 5643 | handle_v6_insn (ARMul_State * state, ARMword instr) { | 5673 | handle_v6_insn (ARMul_State * state, ARMword instr) { |
| 5644 | switch (BITS (20, 27)) { | 5674 | ARMword lhs, temp; |
| 5645 | //ichfly | ||
| 5646 | case 0x66: //UQSUB8 | ||
| 5647 | if ((instr & 0x0FF00FF0) == 0x06600FF0) { | ||
| 5648 | u32 rd = (instr >> 12) & 0xF; | ||
| 5649 | u32 rm = (instr >> 16) & 0xF; | ||
| 5650 | u32 rn = (instr >> 0) & 0xF; | ||
| 5651 | u32 subfrom = state->Reg[rm]; | ||
| 5652 | u32 tosub = state->Reg[rn]; | ||
| 5653 | 5675 | ||
| 5654 | u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub)); | 5676 | switch (BITS (20, 27)) { |
| 5655 | if (b1 > (u8)(subfrom)) b1 = 0; | ||
| 5656 | u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8)); | ||
| 5657 | if (b2 > (u8)(subfrom >> 8)) b2 = 0; | ||
| 5658 | u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16)); | ||
| 5659 | if (b3 > (u8)(subfrom >> 16)) b3 = 0; | ||
| 5660 | u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24)); | ||
| 5661 | if (b4 > (u8)(subfrom >> 24)) b4 = 0; | ||
| 5662 | state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24); | ||
| 5663 | return 1; | ||
| 5664 | } else { | ||
| 5665 | printf("UQSUB8 decoding fail %08X",instr); | ||
| 5666 | } | ||
| 5667 | #if 0 | ||
| 5668 | case 0x03: | 5677 | case 0x03: |
| 5669 | printf ("Unhandled v6 insn: ldr\n"); | 5678 | printf ("Unhandled v6 insn: ldr\n"); |
| 5670 | break; | 5679 | break; |
| @@ -5678,9 +5687,43 @@ L_stm_s_takeabort: | |||
| 5678 | printf ("Unhandled v6 insn: smi\n"); | 5687 | printf ("Unhandled v6 insn: smi\n"); |
| 5679 | break; | 5688 | break; |
| 5680 | case 0x18: | 5689 | case 0x18: |
| 5690 | if (BITS(4, 7) == 0x9) { | ||
| 5691 | /* strex */ | ||
| 5692 | u32 l = LHSReg; | ||
| 5693 | u32 r = RHSReg; | ||
| 5694 | lhs = LHS; | ||
| 5695 | |||
| 5696 | bool enter = false; | ||
| 5697 | |||
| 5698 | if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; | ||
| 5699 | //StoreWord(state, lhs, RHS) | ||
| 5700 | if (state->Aborted) { | ||
| 5701 | TAKEABORT; | ||
| 5702 | } | ||
| 5703 | |||
| 5704 | if (enter) { | ||
| 5705 | ARMul_StoreWordS(state, lhs, RHS); | ||
| 5706 | state->Reg[DESTReg] = 0; | ||
| 5707 | } | ||
| 5708 | else { | ||
| 5709 | state->Reg[DESTReg] = 1; | ||
| 5710 | } | ||
| 5711 | |||
| 5712 | return 1; | ||
| 5713 | } | ||
| 5681 | printf ("Unhandled v6 insn: strex\n"); | 5714 | printf ("Unhandled v6 insn: strex\n"); |
| 5682 | break; | 5715 | break; |
| 5683 | case 0x19: | 5716 | case 0x19: |
| 5717 | /* ldrex */ | ||
| 5718 | if (BITS(4, 7) == 0x9) { | ||
| 5719 | lhs = LHS; | ||
| 5720 | |||
| 5721 | state->currentexaddr = lhs; | ||
| 5722 | state->currentexval = ARMul_ReadWord(state, lhs); | ||
| 5723 | |||
| 5724 | LoadWord(state, instr, lhs); | ||
| 5725 | return 1; | ||
| 5726 | } | ||
| 5684 | printf ("Unhandled v6 insn: ldrex\n"); | 5727 | printf ("Unhandled v6 insn: ldrex\n"); |
| 5685 | break; | 5728 | break; |
| 5686 | case 0x1a: | 5729 | case 0x1a: |
| @@ -5690,9 +5733,52 @@ L_stm_s_takeabort: | |||
| 5690 | printf ("Unhandled v6 insn: ldrexd\n"); | 5733 | printf ("Unhandled v6 insn: ldrexd\n"); |
| 5691 | break; | 5734 | break; |
| 5692 | case 0x1c: | 5735 | case 0x1c: |
| 5736 | if (BITS(4, 7) == 0x9) { | ||
| 5737 | /* strexb */ | ||
| 5738 | lhs = LHS; | ||
| 5739 | |||
| 5740 | bool enter = false; | ||
| 5741 | |||
| 5742 | if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; | ||
| 5743 | |||
| 5744 | BUSUSEDINCPCN; | ||
| 5745 | if (state->Aborted) { | ||
| 5746 | TAKEABORT; | ||
| 5747 | } | ||
| 5748 | |||
| 5749 | |||
| 5750 | if (enter) { | ||
| 5751 | ARMul_StoreByte(state, lhs, RHS); | ||
| 5752 | state->Reg[DESTReg] = 0; | ||
| 5753 | } | ||
| 5754 | else { | ||
| 5755 | state->Reg[DESTReg] = 1; | ||
| 5756 | } | ||
| 5757 | |||
| 5758 | //printf("In %s, strexb not implemented\n", __FUNCTION__); | ||
| 5759 | UNDEF_LSRBPC; | ||
| 5760 | /* WRITESDEST (dest); */ | ||
| 5761 | return 1; | ||
| 5762 | } | ||
| 5693 | printf ("Unhandled v6 insn: strexb\n"); | 5763 | printf ("Unhandled v6 insn: strexb\n"); |
| 5694 | break; | 5764 | break; |
| 5695 | case 0x1d: | 5765 | case 0x1d: |
| 5766 | if ((BITS(4, 7)) == 0x9) { | ||
| 5767 | /* ldrexb */ | ||
| 5768 | temp = LHS; | ||
| 5769 | LoadByte(state, instr, temp, LUNSIGNED); | ||
| 5770 | |||
| 5771 | state->currentexaddr = temp; | ||
| 5772 | state->currentexval = (u32)ARMul_ReadByte(state, temp); | ||
| 5773 | |||
| 5774 | //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); | ||
| 5775 | //printf("ldrexb\n"); | ||
| 5776 | //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); | ||
| 5777 | //exit(-1); | ||
| 5778 | |||
| 5779 | //printf("In %s, ldrexb not implemented\n", __FUNCTION__); | ||
| 5780 | return 1; | ||
| 5781 | } | ||
| 5696 | printf ("Unhandled v6 insn: ldrexb\n"); | 5782 | printf ("Unhandled v6 insn: ldrexb\n"); |
| 5697 | break; | 5783 | break; |
| 5698 | case 0x1e: | 5784 | case 0x1e: |
| @@ -5713,10 +5799,8 @@ L_stm_s_takeabort: | |||
| 5713 | case 0x3f: | 5799 | case 0x3f: |
| 5714 | printf ("Unhandled v6 insn: rbit\n"); | 5800 | printf ("Unhandled v6 insn: rbit\n"); |
| 5715 | break; | 5801 | break; |
| 5716 | #endif | ||
| 5717 | case 0x61: | 5802 | case 0x61: |
| 5718 | if ((instr & 0xFF0) == 0xf70)//ssub16 | 5803 | if ((instr & 0xFF0) == 0xf70) { //ssub16 |
| 5719 | { | ||
| 5720 | u8 tar = BITS(12, 15); | 5804 | u8 tar = BITS(12, 15); |
| 5721 | u8 src1 = BITS(16, 19); | 5805 | u8 src1 = BITS(16, 19); |
| 5722 | u8 src2 = BITS(0, 3); | 5806 | u8 src2 = BITS(0, 3); |
| @@ -5724,11 +5808,9 @@ L_stm_s_takeabort: | |||
| 5724 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5808 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5725 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5809 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5726 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5810 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5727 | state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2)&0xFFFF)<< 0x10); | 5811 | state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2) & 0xFFFF) << 0x10); |
| 5728 | return 1; | 5812 | return 1; |
| 5729 | } | 5813 | } else if ((instr & 0xFF0) == 0xf10) { //sadd16 |
| 5730 | else if ((instr & 0xFF0) == 0xf10)//sadd16 | ||
| 5731 | { | ||
| 5732 | u8 tar = BITS(12, 15); | 5814 | u8 tar = BITS(12, 15); |
| 5733 | u8 src1 = BITS(16, 19); | 5815 | u8 src1 = BITS(16, 19); |
| 5734 | u8 src2 = BITS(0, 3); | 5816 | u8 src2 = BITS(0, 3); |
| @@ -5736,11 +5818,9 @@ L_stm_s_takeabort: | |||
| 5736 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5818 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5737 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5819 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5738 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5820 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5739 | state->Reg[tar] = ((a1 + a2) & 0xFFFF) | (((b1 + b2)&0xFFFF)<< 0x10); | 5821 | state->Reg[tar] = ((a1 + a2) & 0xFFFF) | (((b1 + b2) & 0xFFFF) << 0x10); |
| 5740 | return 1; | 5822 | return 1; |
| 5741 | } | 5823 | } else if ((instr & 0xFF0) == 0xf50) { //ssax |
| 5742 | else if ((instr & 0xFF0) == 0xf50)//ssax | ||
| 5743 | { | ||
| 5744 | u8 tar = BITS(12, 15); | 5824 | u8 tar = BITS(12, 15); |
| 5745 | u8 src1 = BITS(16, 19); | 5825 | u8 src1 = BITS(16, 19); |
| 5746 | u8 src2 = BITS(0, 3); | 5826 | u8 src2 = BITS(0, 3); |
| @@ -5748,11 +5828,9 @@ L_stm_s_takeabort: | |||
| 5748 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5828 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5749 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5829 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5750 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5830 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5751 | state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); | 5831 | state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); |
| 5752 | return 1; | 5832 | return 1; |
| 5753 | } | 5833 | } else if ((instr & 0xFF0) == 0xf30) { //sasx |
| 5754 | else if ((instr & 0xFF0) == 0xf30)//sasx | ||
| 5755 | { | ||
| 5756 | u8 tar = BITS(12, 15); | 5834 | u8 tar = BITS(12, 15); |
| 5757 | u8 src1 = BITS(16, 19); | 5835 | u8 src1 = BITS(16, 19); |
| 5758 | u8 src2 = BITS(0, 3); | 5836 | u8 src2 = BITS(0, 3); |
| @@ -5760,14 +5838,12 @@ L_stm_s_takeabort: | |||
| 5760 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | 5838 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); |
| 5761 | s16 b1 = (state->Reg[src2] & 0xFFFF); | 5839 | s16 b1 = (state->Reg[src2] & 0xFFFF); |
| 5762 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | 5840 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5763 | state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10); | 5841 | state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10); |
| 5764 | return 1; | 5842 | return 1; |
| 5765 | } | 5843 | } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); |
| 5766 | else printf ("Unhandled v6 insn: sadd/ssub\n"); | ||
| 5767 | break; | 5844 | break; |
| 5768 | case 0x62: | 5845 | case 0x62: |
| 5769 | if ((instr & 0xFF0) == 0xf70)//QSUB16 | 5846 | if ((instr & 0xFF0) == 0xf70) { //QSUB16 |
| 5770 | { | ||
| 5771 | u8 tar = BITS(12, 15); | 5847 | u8 tar = BITS(12, 15); |
| 5772 | u8 src1 = BITS(16, 19); | 5848 | u8 src1 = BITS(16, 19); |
| 5773 | u8 src2 = BITS(0, 3); | 5849 | u8 src2 = BITS(0, 3); |
| @@ -5783,9 +5859,7 @@ L_stm_s_takeabort: | |||
| 5783 | if (res2 < 0x7FFF) res2 = -0x8000; | 5859 | if (res2 < 0x7FFF) res2 = -0x8000; |
| 5784 | state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); | 5860 | state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); |
| 5785 | return 1; | 5861 | return 1; |
| 5786 | } | 5862 | } else if ((instr & 0xFF0) == 0xf10) { //QADD16 |
| 5787 | else if ((instr & 0xFF0) == 0xf10)//QADD16 | ||
| 5788 | { | ||
| 5789 | u8 tar = BITS(12, 15); | 5863 | u8 tar = BITS(12, 15); |
| 5790 | u8 src1 = BITS(16, 19); | 5864 | u8 src1 = BITS(16, 19); |
| 5791 | u8 src2 = BITS(0, 3); | 5865 | u8 src2 = BITS(0, 3); |
| @@ -5801,29 +5875,234 @@ L_stm_s_takeabort: | |||
| 5801 | if (res2 < 0x7FFF) res2 = -0x8000; | 5875 | if (res2 < 0x7FFF) res2 = -0x8000; |
| 5802 | state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); | 5876 | state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); |
| 5803 | return 1; | 5877 | return 1; |
| 5804 | } | 5878 | } else printf ("Unhandled v6 insn: qadd16/qsub16\n"); |
| 5805 | else printf ("Unhandled v6 insn: qadd/qsub\n"); | ||
| 5806 | break; | 5879 | break; |
| 5807 | #if 0 | ||
| 5808 | case 0x63: | 5880 | case 0x63: |
| 5809 | printf ("Unhandled v6 insn: shadd/shsub\n"); | 5881 | printf ("Unhandled v6 insn: shadd/shsub\n"); |
| 5810 | break; | 5882 | break; |
| 5811 | case 0x65: | 5883 | case 0x65: |
| 5812 | printf ("Unhandled v6 insn: uadd/usub\n"); | 5884 | { |
| 5885 | u32 rd = (instr >> 12) & 0xF; | ||
| 5886 | u32 rn = (instr >> 16) & 0xF; | ||
| 5887 | u32 rm = (instr >> 0) & 0xF; | ||
| 5888 | u32 from = state->Reg[rn]; | ||
| 5889 | u32 to = state->Reg[rm]; | ||
| 5890 | |||
| 5891 | if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16 | ||
| 5892 | u32 h1, h2; | ||
| 5893 | state->Cpsr &= 0xfff0ffff; | ||
| 5894 | if ((instr & 0x0F0) == 0x070) { // USUB16 | ||
| 5895 | h1 = ((u16)from - (u16)to); | ||
| 5896 | h2 = ((u16)(from >> 16) - (u16)(to >> 16)); | ||
| 5897 | if (!(h1 & 0xffff0000)) state->Cpsr |= (3 << 16); | ||
| 5898 | if (!(h2 & 0xffff0000)) state->Cpsr |= (3 << 18); | ||
| 5899 | } | ||
| 5900 | else { // UADD16 | ||
| 5901 | h1 = ((u16)from + (u16)to); | ||
| 5902 | h2 = ((u16)(from >> 16) + (u16)(to >> 16)); | ||
| 5903 | if (h1 & 0xffff0000) state->Cpsr |= (3 << 16); | ||
| 5904 | if (h2 & 0xffff0000) state->Cpsr |= (3 << 18); | ||
| 5905 | } | ||
| 5906 | state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16)); | ||
| 5907 | return 1; | ||
| 5908 | } | ||
| 5909 | else | ||
| 5910 | if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8 | ||
| 5911 | u32 b1, b2, b3, b4; | ||
| 5912 | state->Cpsr &= 0xfff0ffff; | ||
| 5913 | if ((instr & 0x0F0) == 0x0F0) { // USUB8 | ||
| 5914 | b1 = ((u8)from - (u8)to); | ||
| 5915 | b2 = ((u8)(from >> 8) - (u8)(to >> 8)); | ||
| 5916 | b3 = ((u8)(from >> 16) - (u8)(to >> 16)); | ||
| 5917 | b4 = ((u8)(from >> 24) - (u8)(to >> 24)); | ||
| 5918 | if (!(b1 & 0xffffff00)) state->Cpsr |= (1 << 16); | ||
| 5919 | if (!(b2 & 0xffffff00)) state->Cpsr |= (1 << 17); | ||
| 5920 | if (!(b3 & 0xffffff00)) state->Cpsr |= (1 << 18); | ||
| 5921 | if (!(b4 & 0xffffff00)) state->Cpsr |= (1 << 19); | ||
| 5922 | } | ||
| 5923 | else { // UADD8 | ||
| 5924 | b1 = ((u8)from + (u8)to); | ||
| 5925 | b2 = ((u8)(from >> 8) + (u8)(to >> 8)); | ||
| 5926 | b3 = ((u8)(from >> 16) + (u8)(to >> 16)); | ||
| 5927 | b4 = ((u8)(from >> 24) + (u8)(to >> 24)); | ||
| 5928 | if (b1 & 0xffffff00) state->Cpsr |= (1 << 16); | ||
| 5929 | if (b2 & 0xffffff00) state->Cpsr |= (1 << 17); | ||
| 5930 | if (b3 & 0xffffff00) state->Cpsr |= (1 << 18); | ||
| 5931 | if (b4 & 0xffffff00) state->Cpsr |= (1 << 19); | ||
| 5932 | } | ||
| 5933 | state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); | ||
| 5934 | return 1; | ||
| 5935 | } | ||
| 5936 | } | ||
| 5937 | printf("Unhandled v6 insn: uasx/usax\n"); | ||
| 5813 | break; | 5938 | break; |
| 5814 | case 0x66: | 5939 | case 0x66: |
| 5815 | printf ("Unhandled v6 insn: uqadd/uqsub\n"); | 5940 | if ((instr & 0x0FF00FF0) == 0x06600FF0) { //uqsub8 |
| 5941 | u32 rd = (instr >> 12) & 0xF; | ||
| 5942 | u32 rm = (instr >> 16) & 0xF; | ||
| 5943 | u32 rn = (instr >> 0) & 0xF; | ||
| 5944 | u32 subfrom = state->Reg[rm]; | ||
| 5945 | u32 tosub = state->Reg[rn]; | ||
| 5946 | |||
| 5947 | u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub)); | ||
| 5948 | if (b1 > (u8)(subfrom)) b1 = 0; | ||
| 5949 | u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8)); | ||
| 5950 | if (b2 > (u8)(subfrom >> 8)) b2 = 0; | ||
| 5951 | u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16)); | ||
| 5952 | if (b3 > (u8)(subfrom >> 16)) b3 = 0; | ||
| 5953 | u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24)); | ||
| 5954 | if (b4 > (u8)(subfrom >> 24)) b4 = 0; | ||
| 5955 | state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24); | ||
| 5956 | return 1; | ||
| 5957 | } else { | ||
| 5958 | printf ("Unhandled v6 insn: uqsub16\n"); | ||
| 5959 | } | ||
| 5816 | break; | 5960 | break; |
| 5817 | case 0x67: | 5961 | case 0x67: |
| 5818 | printf ("Unhandled v6 insn: uhadd/uhsub\n"); | 5962 | printf ("Unhandled v6 insn: uhadd/uhsub\n"); |
| 5819 | break; | 5963 | break; |
| 5820 | case 0x68: | 5964 | case 0x68: |
| 5821 | printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); | 5965 | { |
| 5966 | u32 rd = (instr >> 12) & 0xF; | ||
| 5967 | u32 rn = (instr >> 16) & 0xF; | ||
| 5968 | u32 rm = (instr >> 0) & 0xF; | ||
| 5969 | u32 from = state->Reg[rn]; | ||
| 5970 | u32 to = state->Reg[rm]; | ||
| 5971 | u32 cpsr = state->Cpsr; | ||
| 5972 | if ((instr & 0xFF0) == 0xFB0) { // SEL | ||
| 5973 | u32 result; | ||
| 5974 | if (cpsr & (1 << 16)) | ||
| 5975 | result = from & 0xff; | ||
| 5976 | else | ||
| 5977 | result = to & 0xff; | ||
| 5978 | if (cpsr & (1 << 17)) | ||
| 5979 | result |= from & 0x0000ff00; | ||
| 5980 | else | ||
| 5981 | result |= to & 0x0000ff00; | ||
| 5982 | if (cpsr & (1 << 18)) | ||
| 5983 | result |= from & 0x00ff0000; | ||
| 5984 | else | ||
| 5985 | result |= to & 0x00ff0000; | ||
| 5986 | if (cpsr & (1 << 19)) | ||
| 5987 | result |= from & 0xff000000; | ||
| 5988 | else | ||
| 5989 | result |= to & 0xff000000; | ||
| 5990 | state->Reg[rd] = result; | ||
| 5991 | return 1; | ||
| 5992 | } | ||
| 5993 | } | ||
| 5994 | printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); | ||
| 5822 | break; | 5995 | break; |
| 5823 | #endif | 5996 | case 0x6a: { |
| 5997 | ARMword Rm; | ||
| 5998 | int ror = -1; | ||
| 5999 | |||
| 6000 | switch (BITS(4, 11)) { | ||
| 6001 | case 0x07: | ||
| 6002 | ror = 0; | ||
| 6003 | break; | ||
| 6004 | case 0x47: | ||
| 6005 | ror = 8; | ||
| 6006 | break; | ||
| 6007 | case 0x87: | ||
| 6008 | ror = 16; | ||
| 6009 | break; | ||
| 6010 | case 0xc7: | ||
| 6011 | ror = 24; | ||
| 6012 | break; | ||
| 6013 | |||
| 6014 | case 0x01: | ||
| 6015 | case 0xf3: | ||
| 6016 | //ichfly | ||
| 6017 | //SSAT16 | ||
| 6018 | { | ||
| 6019 | u8 tar = BITS(12, 15); | ||
| 6020 | u8 src = BITS(0, 3); | ||
| 6021 | u8 val = BITS(16, 19) + 1; | ||
| 6022 | s16 a1 = (state->Reg[src]); | ||
| 6023 | s16 a2 = (state->Reg[src] >> 0x10); | ||
| 6024 | s16 min = (s16)(0x8000 >> (16 - val)); | ||
| 6025 | s16 max = 0x7FFF >> (16 - val); | ||
| 6026 | if (min > a1) a1 = min; | ||
| 6027 | if (max < a1) a1 = max; | ||
| 6028 | if (min > a2) a2 = min; | ||
| 6029 | if (max < a2) a2 = max; | ||
| 6030 | u32 temp2 = ((u32)(a2)) << 0x10; | ||
| 6031 | state->Reg[tar] = (a1 & 0xFFFF) | (temp2); | ||
| 6032 | } | ||
| 6033 | |||
| 6034 | return 1; | ||
| 6035 | default: | ||
| 6036 | break; | ||
| 6037 | } | ||
| 6038 | |||
| 6039 | if (ror == -1) { | ||
| 6040 | if (BITS(4, 6) == 0x7) { | ||
| 6041 | printf("Unhandled v6 insn: ssat\n"); | ||
| 6042 | return 0; | ||
| 6043 | } | ||
| 6044 | break; | ||
| 6045 | } | ||
| 6046 | |||
| 6047 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); | ||
| 6048 | if (Rm & 0x80) | ||
| 6049 | Rm |= 0xffffff00; | ||
| 6050 | |||
| 6051 | if (BITS(16, 19) == 0xf) | ||
| 6052 | /* SXTB */ | ||
| 6053 | state->Reg[BITS(12, 15)] = Rm; | ||
| 6054 | else | ||
| 6055 | /* SXTAB */ | ||
| 6056 | state->Reg[BITS(12, 15)] += Rm; | ||
| 6057 | |||
| 6058 | return 1; | ||
| 6059 | } | ||
| 6060 | case 0x6b: { | ||
| 6061 | ARMword Rm; | ||
| 6062 | int ror = -1; | ||
| 6063 | |||
| 6064 | switch (BITS(4, 11)) { | ||
| 6065 | case 0x07: | ||
| 6066 | ror = 0; | ||
| 6067 | break; | ||
| 6068 | case 0x47: | ||
| 6069 | ror = 8; | ||
| 6070 | break; | ||
| 6071 | case 0x87: | ||
| 6072 | ror = 16; | ||
| 6073 | break; | ||
| 6074 | case 0xc7: | ||
| 6075 | ror = 24; | ||
| 6076 | break; | ||
| 6077 | |||
| 6078 | case 0xf3: | ||
| 6079 | DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); | ||
| 6080 | return 1; | ||
| 6081 | case 0xfb: | ||
| 6082 | DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); | ||
| 6083 | return 1; | ||
| 6084 | default: | ||
| 6085 | break; | ||
| 6086 | } | ||
| 6087 | |||
| 6088 | if (ror == -1) | ||
| 6089 | break; | ||
| 6090 | |||
| 6091 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); | ||
| 6092 | if (Rm & 0x8000) | ||
| 6093 | Rm |= 0xffff0000; | ||
| 6094 | |||
| 6095 | if (BITS(16, 19) == 0xf) | ||
| 6096 | /* SXTH */ | ||
| 6097 | state->Reg[BITS(12, 15)] = Rm; | ||
| 6098 | else | ||
| 6099 | /* SXTAH */ | ||
| 6100 | state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; | ||
| 6101 | |||
| 6102 | return 1; | ||
| 6103 | } | ||
| 5824 | case 0x6c: | 6104 | case 0x6c: |
| 5825 | if ((instr & 0xf03f0) == 0xf0070) //uxtb16 | 6105 | if ((instr & 0xf03f0) == 0xf0070) { //uxtb16 |
| 5826 | { | ||
| 5827 | u8 src1 = BITS(0, 3); | 6106 | u8 src1 = BITS(0, 3); |
| 5828 | u8 tar = BITS(12, 15); | 6107 | u8 tar = BITS(12, 15); |
| 5829 | u32 base = state->Reg[src1]; | 6108 | u32 base = state->Reg[src1]; |
| @@ -5831,13 +6110,119 @@ L_stm_s_takeabort: | |||
| 5831 | u32 in = ((base << (32 - shamt)) | (base >> shamt)); | 6110 | u32 in = ((base << (32 - shamt)) | (base >> shamt)); |
| 5832 | state->Reg[tar] = in & 0x00FF00FF; | 6111 | state->Reg[tar] = in & 0x00FF00FF; |
| 5833 | return 1; | 6112 | return 1; |
| 5834 | } | 6113 | } else |
| 5835 | else | 6114 | printf ("Unhandled v6 insn: uxtab16\n"); |
| 5836 | printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); | ||
| 5837 | break; | 6115 | break; |
| 6116 | case 0x6e: { | ||
| 6117 | ARMword Rm; | ||
| 6118 | int ror = -1; | ||
| 6119 | |||
| 6120 | switch (BITS(4, 11)) { | ||
| 6121 | case 0x07: | ||
| 6122 | ror = 0; | ||
| 6123 | break; | ||
| 6124 | case 0x47: | ||
| 6125 | ror = 8; | ||
| 6126 | break; | ||
| 6127 | case 0x87: | ||
| 6128 | ror = 16; | ||
| 6129 | break; | ||
| 6130 | case 0xc7: | ||
| 6131 | ror = 24; | ||
| 6132 | break; | ||
| 6133 | |||
| 6134 | case 0x01: | ||
| 6135 | case 0xf3: | ||
| 6136 | //ichfly | ||
| 6137 | //USAT16 | ||
| 6138 | { | ||
| 6139 | u8 tar = BITS(12, 15); | ||
| 6140 | u8 src = BITS(0, 3); | ||
| 6141 | u8 val = BITS(16, 19); | ||
| 6142 | s16 a1 = (state->Reg[src]); | ||
| 6143 | s16 a2 = (state->Reg[src] >> 0x10); | ||
| 6144 | s16 max = 0xFFFF >> (16 - val); | ||
| 6145 | if (max < a1) a1 = max; | ||
| 6146 | if (max < a2) a2 = max; | ||
| 6147 | u32 temp2 = ((u32)(a2)) << 0x10; | ||
| 6148 | state->Reg[tar] = (a1 & 0xFFFF) | (temp2); | ||
| 6149 | } | ||
| 6150 | return 1; | ||
| 6151 | default: | ||
| 6152 | break; | ||
| 6153 | } | ||
| 6154 | |||
| 6155 | if (ror == -1) { | ||
| 6156 | if (BITS(4, 6) == 0x7) { | ||
| 6157 | printf("Unhandled v6 insn: usat\n"); | ||
| 6158 | return 0; | ||
| 6159 | } | ||
| 6160 | break; | ||
| 6161 | } | ||
| 6162 | |||
| 6163 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); | ||
| 6164 | |||
| 6165 | if (BITS(16, 19) == 0xf) | ||
| 6166 | /* UXTB */ | ||
| 6167 | state->Reg[BITS(12, 15)] = Rm; | ||
| 6168 | else | ||
| 6169 | /* UXTAB */ | ||
| 6170 | state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; | ||
| 6171 | |||
| 6172 | return 1; | ||
| 6173 | } | ||
| 6174 | |||
| 6175 | case 0x6f: { | ||
| 6176 | ARMword Rm; | ||
| 6177 | int ror = -1; | ||
| 6178 | |||
| 6179 | switch (BITS(4, 11)) { | ||
| 6180 | case 0x07: | ||
| 6181 | ror = 0; | ||
| 6182 | break; | ||
| 6183 | case 0x47: | ||
| 6184 | ror = 8; | ||
| 6185 | break; | ||
| 6186 | case 0x87: | ||
| 6187 | ror = 16; | ||
| 6188 | break; | ||
| 6189 | case 0xc7: | ||
| 6190 | ror = 24; | ||
| 6191 | break; | ||
| 6192 | |||
| 6193 | case 0xfb: | ||
| 6194 | printf("Unhandled v6 insn: revsh\n"); | ||
| 6195 | return 0; | ||
| 6196 | default: | ||
| 6197 | break; | ||
| 6198 | } | ||
| 6199 | |||
| 6200 | if (ror == -1) | ||
| 6201 | break; | ||
| 6202 | |||
| 6203 | Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); | ||
| 6204 | |||
| 6205 | /* UXT */ | ||
| 6206 | /* state->Reg[BITS (12, 15)] = Rm; */ | ||
| 6207 | /* dyf add */ | ||
| 6208 | if (BITS(16, 19) == 0xf) { | ||
| 6209 | state->Reg[BITS(12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; | ||
| 6210 | } | ||
| 6211 | else { | ||
| 6212 | /* UXTAH */ | ||
| 6213 | /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */ | ||
| 6214 | // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)] | ||
| 6215 | // , Rm, BITS(10, 11)); | ||
| 6216 | // printf("icounter is %lld\n", state->NumInstrs); | ||
| 6217 | state->Reg[BITS(12, 15)] = (state->Reg[BITS(16, 19)] >> (8 * (BITS(10, 11)))) + Rm; | ||
| 6218 | // printf("rd is %x\n", state->Reg[BITS (12, 15)]); | ||
| 6219 | // exit(-1); | ||
| 6220 | } | ||
| 6221 | |||
| 6222 | return 1; | ||
| 6223 | } | ||
| 5838 | case 0x70: | 6224 | case 0x70: |
| 5839 | if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly | 6225 | if ((instr & 0xf0d0) == 0xf010) { //smuad //ichfly |
| 5840 | { | ||
| 5841 | u8 tar = BITS(16, 19); | 6226 | u8 tar = BITS(16, 19); |
| 5842 | u8 src1 = BITS(0, 3); | 6227 | u8 src1 = BITS(0, 3); |
| 5843 | u8 src2 = BITS(8, 11); | 6228 | u8 src2 = BITS(8, 11); |
| @@ -5849,9 +6234,7 @@ L_stm_s_takeabort: | |||
| 5849 | state->Reg[tar] = a1*a2 + b1*b2; | 6234 | state->Reg[tar] = a1*a2 + b1*b2; |
| 5850 | return 1; | 6235 | return 1; |
| 5851 | 6236 | ||
| 5852 | } | 6237 | } else if ((instr & 0xf0d0) == 0xf050) { //smusd |
| 5853 | else if ((instr & 0xf0d0) == 0xf050)//smusd | ||
| 5854 | { | ||
| 5855 | u8 tar = BITS(16, 19); | 6238 | u8 tar = BITS(16, 19); |
| 5856 | u8 src1 = BITS(0, 3); | 6239 | u8 src1 = BITS(0, 3); |
| 5857 | u8 src2 = BITS(8, 11); | 6240 | u8 src2 = BITS(8, 11); |
| @@ -5862,9 +6245,7 @@ L_stm_s_takeabort: | |||
| 5862 | s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); | 6245 | s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5863 | state->Reg[tar] = a1*a2 - b1*b2; | 6246 | state->Reg[tar] = a1*a2 - b1*b2; |
| 5864 | return 1; | 6247 | return 1; |
| 5865 | } | 6248 | } else if ((instr & 0xd0) == 0x10) { //smlad |
| 5866 | else if ((instr & 0xd0) == 0x10)//smlad | ||
| 5867 | { | ||
| 5868 | u8 tar = BITS(16, 19); | 6249 | u8 tar = BITS(16, 19); |
| 5869 | u8 src1 = BITS(0, 3); | 6250 | u8 src1 = BITS(0, 3); |
| 5870 | u8 src2 = BITS(8, 11); | 6251 | u8 src2 = BITS(8, 11); |
| @@ -5879,8 +6260,7 @@ L_stm_s_takeabort: | |||
| 5879 | s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); | 6260 | s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); |
| 5880 | state->Reg[tar] = a1*a2 + b1*b2 + a3; | 6261 | state->Reg[tar] = a1*a2 + b1*b2 + a3; |
| 5881 | return 1; | 6262 | return 1; |
| 5882 | } | 6263 | } else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); |
| 5883 | else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); | ||
| 5884 | break; | 6264 | break; |
| 5885 | case 0x74: | 6265 | case 0x74: |
| 5886 | printf ("Unhandled v6 insn: smlald/smlsld\n"); | 6266 | printf ("Unhandled v6 insn: smlald/smlsld\n"); |
| @@ -5891,332 +6271,18 @@ L_stm_s_takeabort: | |||
| 5891 | case 0x78: | 6271 | case 0x78: |
| 5892 | printf ("Unhandled v6 insn: usad/usada8\n"); | 6272 | printf ("Unhandled v6 insn: usad/usada8\n"); |
| 5893 | break; | 6273 | break; |
| 5894 | #if 0 | ||
| 5895 | case 0x7a: | 6274 | case 0x7a: |
| 5896 | printf ("Unhandled v6 insn: usbfx\n"); | 6275 | printf ("Unhandled v6 insn: usbfx\n"); |
| 5897 | break; | 6276 | break; |
| 5898 | case 0x7c: | 6277 | case 0x7c: |
| 5899 | printf ("Unhandled v6 insn: bfc/bfi\n"); | 6278 | printf ("Unhandled v6 insn: bfc/bfi\n"); |
| 5900 | break; | 6279 | break; |
| 5901 | #endif | ||
| 5902 | |||
| 5903 | |||
| 5904 | /* add new instr for arm v6. */ | ||
| 5905 | ARMword lhs, temp; | ||
| 5906 | case 0x18: { /* ORR reg */ | ||
| 5907 | /* dyf add armv6 instr strex 2010.9.17 */ | ||
| 5908 | if (BITS (4, 7) == 0x9) { | ||
| 5909 | u32 l = LHSReg; | ||
| 5910 | u32 r = RHSReg; | ||
| 5911 | lhs = LHS; | ||
| 5912 | |||
| 5913 | bool enter = false; | ||
| 5914 | |||
| 5915 | if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; | ||
| 5916 | ARMul_StoreWordS(state, lhs, RHS); | ||
| 5917 | //StoreWord(state, lhs, RHS) | ||
| 5918 | if (state->Aborted) { | ||
| 5919 | TAKEABORT; | ||
| 5920 | } | ||
| 5921 | |||
| 5922 | if (enter) { | ||
| 5923 | state->Reg[DESTReg] = 0; | ||
| 5924 | } else { | ||
| 5925 | state->Reg[DESTReg] = 1; | ||
| 5926 | } | ||
| 5927 | |||
| 5928 | return 1; | ||
| 5929 | } | ||
| 5930 | break; | ||
| 5931 | } | ||
| 5932 | |||
| 5933 | case 0x19: { /* orrs reg */ | ||
| 5934 | /* dyf add armv6 instr ldrex */ | ||
| 5935 | if (BITS (4, 7) == 0x9) { | ||
| 5936 | lhs = LHS; | ||
| 5937 | |||
| 5938 | state->currentexaddr = lhs; | ||
| 5939 | state->currentexval = ARMul_ReadWord(state, lhs); | ||
| 5940 | |||
| 5941 | LoadWord (state, instr, lhs); | ||
| 5942 | return 1; | ||
| 5943 | } | ||
| 5944 | break; | ||
| 5945 | } | ||
| 5946 | |||
| 5947 | case 0x1c: { /* BIC reg */ | ||
| 5948 | /* dyf add for STREXB */ | ||
| 5949 | if (BITS (4, 7) == 0x9) { | ||
| 5950 | lhs = LHS; | ||
| 5951 | |||
| 5952 | bool enter = false; | ||
| 5953 | |||
| 5954 | if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; | ||
| 5955 | |||
| 5956 | ARMul_StoreByte (state, lhs, RHS); | ||
| 5957 | BUSUSEDINCPCN; | ||
| 5958 | if (state->Aborted) { | ||
| 5959 | TAKEABORT; | ||
| 5960 | } | ||
| 5961 | |||
| 5962 | |||
| 5963 | if (enter) { | ||
| 5964 | state->Reg[DESTReg] = 0; | ||
| 5965 | } else { | ||
| 5966 | state->Reg[DESTReg] = 1; | ||
| 5967 | } | ||
| 5968 | |||
| 5969 | //printf("In %s, strexb not implemented\n", __FUNCTION__); | ||
| 5970 | UNDEF_LSRBPC; | ||
| 5971 | /* WRITESDEST (dest); */ | ||
| 5972 | return 1; | ||
| 5973 | } | ||
| 5974 | break; | ||
| 5975 | } | ||
| 5976 | |||
| 5977 | case 0x1d: { /* BICS reg */ | ||
| 5978 | if ((BITS (4, 7)) == 0x9) { | ||
| 5979 | /* ldrexb */ | ||
| 5980 | temp = LHS; | ||
| 5981 | LoadByte (state, instr, temp, LUNSIGNED); | ||
| 5982 | |||
| 5983 | state->currentexaddr = temp; | ||
| 5984 | state->currentexval = (u32)ARMul_ReadByte(state, temp); | ||
| 5985 | |||
| 5986 | //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); | ||
| 5987 | //printf("ldrexb\n"); | ||
| 5988 | //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); | ||
| 5989 | //exit(-1); | ||
| 5990 | |||
| 5991 | //printf("In %s, ldrexb not implemented\n", __FUNCTION__); | ||
| 5992 | return 1; | ||
| 5993 | } | ||
| 5994 | break; | ||
| 5995 | } | ||
| 5996 | /* add end */ | ||
| 5997 | |||
| 5998 | case 0x6a: { | ||
| 5999 | ARMword Rm; | ||
| 6000 | int ror = -1; | ||
| 6001 | |||
| 6002 | switch (BITS (4, 11)) { | ||
| 6003 | case 0x07: | ||
| 6004 | ror = 0; | ||
| 6005 | break; | ||
| 6006 | case 0x47: | ||
| 6007 | ror = 8; | ||
| 6008 | break; | ||
| 6009 | case 0x87: | ||
| 6010 | ror = 16; | ||
| 6011 | break; | ||
| 6012 | case 0xc7: | ||
| 6013 | ror = 24; | ||
| 6014 | break; | ||
| 6015 | |||
| 6016 | case 0x01: | ||
| 6017 | case 0xf3: | ||
| 6018 | //ichfly | ||
| 6019 | //SSAT16 | ||
| 6020 | { | ||
| 6021 | u8 tar = BITS(12,15); | ||
| 6022 | u8 src = BITS(0, 3); | ||
| 6023 | u8 val = BITS(16, 19) + 1; | ||
| 6024 | s16 a1 = (state->Reg[src]); | ||
| 6025 | s16 a2 = (state->Reg[src] >> 0x10); | ||
| 6026 | s16 min = (s16)(0x8000) >> (16 - val); | ||
| 6027 | s16 max = 0x7FFF >> (16 - val); | ||
| 6028 | if (min > a1) a1 = min; | ||
| 6029 | if (max < a1) a1 = max; | ||
| 6030 | if (min > a2) a2 = min; | ||
| 6031 | if (max < a2) a2 = max; | ||
| 6032 | u32 temp2 = ((u32)(a2)) << 0x10; | ||
| 6033 | state->Reg[tar] = (a1&0xFFFF) | (temp2); | ||
| 6034 | } | ||
| 6035 | |||
| 6036 | return 1; | ||
| 6037 | default: | ||
| 6038 | break; | ||
| 6039 | } | ||
| 6040 | |||
| 6041 | if (ror == -1) { | ||
| 6042 | if (BITS (4, 6) == 0x7) { | ||
| 6043 | printf ("Unhandled v6 insn: ssat\n"); | ||
| 6044 | return 0; | ||
| 6045 | } | ||
| 6046 | break; | ||
| 6047 | } | ||
| 6048 | |||
| 6049 | Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); | ||
| 6050 | if (Rm & 0x80) | ||
| 6051 | Rm |= 0xffffff00; | ||
| 6052 | |||
| 6053 | if (BITS (16, 19) == 0xf) | ||
| 6054 | /* SXTB */ | ||
| 6055 | state->Reg[BITS (12, 15)] = Rm; | ||
| 6056 | else | ||
| 6057 | /* SXTAB */ | ||
| 6058 | state->Reg[BITS (12, 15)] += Rm; | ||
| 6059 | } | ||
| 6060 | return 1; | ||
| 6061 | |||
| 6062 | case 0x6b: { | ||
| 6063 | ARMword Rm; | ||
| 6064 | int ror = -1; | ||
| 6065 | |||
| 6066 | switch (BITS (4, 11)) { | ||
| 6067 | case 0x07: | ||
| 6068 | ror = 0; | ||
| 6069 | break; | ||
| 6070 | case 0x47: | ||
| 6071 | ror = 8; | ||
| 6072 | break; | ||
| 6073 | case 0x87: | ||
| 6074 | ror = 16; | ||
| 6075 | break; | ||
| 6076 | case 0xc7: | ||
| 6077 | ror = 24; | ||
| 6078 | break; | ||
| 6079 | |||
| 6080 | case 0xf3: | ||
| 6081 | DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); | ||
| 6082 | return 1; | ||
| 6083 | case 0xfb: | ||
| 6084 | DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); | ||
| 6085 | return 1; | ||
| 6086 | default: | ||
| 6087 | break; | ||
| 6088 | } | ||
| 6089 | |||
| 6090 | if (ror == -1) | ||
| 6091 | break; | ||
| 6092 | |||
| 6093 | Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); | ||
| 6094 | if (Rm & 0x8000) | ||
| 6095 | Rm |= 0xffff0000; | ||
| 6096 | |||
| 6097 | if (BITS (16, 19) == 0xf) | ||
| 6098 | /* SXTH */ | ||
| 6099 | state->Reg[BITS (12, 15)] = Rm; | ||
| 6100 | else | ||
| 6101 | /* SXTAH */ | ||
| 6102 | state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; | ||
| 6103 | } | ||
| 6104 | return 1; | ||
| 6105 | |||
| 6106 | case 0x6e: { | ||
| 6107 | ARMword Rm; | ||
| 6108 | int ror = -1; | ||
| 6109 | |||
| 6110 | switch (BITS (4, 11)) { | ||
| 6111 | case 0x07: | ||
| 6112 | ror = 0; | ||
| 6113 | break; | ||
| 6114 | case 0x47: | ||
| 6115 | ror = 8; | ||
| 6116 | break; | ||
| 6117 | case 0x87: | ||
| 6118 | ror = 16; | ||
| 6119 | break; | ||
| 6120 | case 0xc7: | ||
| 6121 | ror = 24; | ||
| 6122 | break; | ||
| 6123 | |||
| 6124 | case 0x01: | ||
| 6125 | case 0xf3: | ||
| 6126 | //ichfly | ||
| 6127 | //USAT16 | ||
| 6128 | { | ||
| 6129 | u8 tar = BITS(12, 15); | ||
| 6130 | u8 src = BITS(0, 3); | ||
| 6131 | u8 val = BITS(16, 19); | ||
| 6132 | s16 a1 = (state->Reg[src]); | ||
| 6133 | s16 a2 = (state->Reg[src] >> 0x10); | ||
| 6134 | s16 max = 0xFFFF >> (16 - val); | ||
| 6135 | if (max < a1) a1 = max; | ||
| 6136 | if (max < a2) a2 = max; | ||
| 6137 | u32 temp2 = ((u32)(a2)) << 0x10; | ||
| 6138 | state->Reg[tar] = (a1 & 0xFFFF) | (temp2); | ||
| 6139 | } | ||
| 6140 | return 1; | ||
| 6141 | default: | ||
| 6142 | break; | ||
| 6143 | } | ||
| 6144 | |||
| 6145 | if (ror == -1) { | ||
| 6146 | if (BITS (4, 6) == 0x7) { | ||
| 6147 | printf ("Unhandled v6 insn: usat\n"); | ||
| 6148 | return 0; | ||
| 6149 | } | ||
| 6150 | break; | ||
| 6151 | } | ||
| 6152 | |||
| 6153 | Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); | ||
| 6154 | |||
| 6155 | if (BITS (16, 19) == 0xf) | ||
| 6156 | /* UXTB */ | ||
| 6157 | state->Reg[BITS (12, 15)] = Rm; | ||
| 6158 | else | ||
| 6159 | /* UXTAB */ | ||
| 6160 | state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm; | ||
| 6161 | } | ||
| 6162 | return 1; | ||
| 6163 | |||
| 6164 | case 0x6f: { | ||
| 6165 | ARMword Rm; | ||
| 6166 | int ror = -1; | ||
| 6167 | |||
| 6168 | switch (BITS (4, 11)) { | ||
| 6169 | case 0x07: | ||
| 6170 | ror = 0; | ||
| 6171 | break; | ||
| 6172 | case 0x47: | ||
| 6173 | ror = 8; | ||
| 6174 | break; | ||
| 6175 | case 0x87: | ||
| 6176 | ror = 16; | ||
| 6177 | break; | ||
| 6178 | case 0xc7: | ||
| 6179 | ror = 24; | ||
| 6180 | break; | ||
| 6181 | |||
| 6182 | case 0xfb: | ||
| 6183 | printf ("Unhandled v6 insn: revsh\n"); | ||
| 6184 | return 0; | ||
| 6185 | default: | ||
| 6186 | break; | ||
| 6187 | } | ||
| 6188 | |||
| 6189 | if (ror == -1) | ||
| 6190 | break; | ||
| 6191 | |||
| 6192 | Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); | ||
| 6193 | |||
| 6194 | /* UXT */ | ||
| 6195 | /* state->Reg[BITS (12, 15)] = Rm; */ | ||
| 6196 | /* dyf add */ | ||
| 6197 | if (BITS (16, 19) == 0xf) { | ||
| 6198 | state->Reg[BITS (12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; | ||
| 6199 | } else { | ||
| 6200 | /* UXTAH */ | ||
| 6201 | /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */ | ||
| 6202 | // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)] | ||
| 6203 | // , Rm, BITS(10, 11)); | ||
| 6204 | // printf("icounter is %lld\n", state->NumInstrs); | ||
| 6205 | state->Reg[BITS (12, 15)] = (state->Reg[BITS (16, 19)] >> (8 * (BITS(10, 11)))) + Rm; | ||
| 6206 | // printf("rd is %x\n", state->Reg[BITS (12, 15)]); | ||
| 6207 | // exit(-1); | ||
| 6208 | } | ||
| 6209 | } | ||
| 6210 | return 1; | ||
| 6211 | |||
| 6212 | #if 0 | ||
| 6213 | case 0x84: | 6280 | case 0x84: |
| 6214 | printf ("Unhandled v6 insn: srs\n"); | 6281 | printf ("Unhandled v6 insn: srs\n"); |
| 6215 | break; | 6282 | break; |
| 6216 | #endif | ||
| 6217 | default: | 6283 | default: |
| 6218 | break; | 6284 | break; |
| 6219 | } | 6285 | } |
| 6220 | printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); | 6286 | printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); |
| 6221 | return 0; | 6287 | return 0; |
| 6222 | } | 6288 | } \ No newline at end of file |
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h index 8343aaa01..9e62255aa 100644 --- a/src/core/arm/skyeye_common/armdefs.h +++ b/src/core/arm/skyeye_common/armdefs.h | |||
| @@ -281,6 +281,7 @@ struct ARMul_State | |||
| 281 | 281 | ||
| 282 | ARMword currentexaddr; | 282 | ARMword currentexaddr; |
| 283 | ARMword currentexval; | 283 | ARMword currentexval; |
| 284 | ARMword currentexvald; | ||
| 284 | ARMword servaddr; | 285 | ARMword servaddr; |
| 285 | 286 | ||
| 286 | unsigned NextInstr; | 287 | unsigned NextInstr; |
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index 07d0c1f44..871900497 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp | |||
| @@ -522,8 +522,7 @@ static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ic | |||
| 522 | if (tm == VFP_QNAN) | 522 | if (tm == VFP_QNAN) |
| 523 | vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; | 523 | vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; |
| 524 | goto pack_nan; | 524 | goto pack_nan; |
| 525 | } | 525 | } else if (tm & VFP_ZERO) |
| 526 | else if (tm & VFP_ZERO) | ||
| 527 | vdd.exponent = 0; | 526 | vdd.exponent = 0; |
| 528 | else | 527 | else |
| 529 | vdd.exponent = vsm.exponent + (1023 - 127); | 528 | vdd.exponent = vsm.exponent + (1023 - 127); |
| @@ -620,7 +619,7 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 620 | if (vsm.exponent >= 127 + 32) { | 619 | if (vsm.exponent >= 127 + 32) { |
| 621 | d = vsm.sign ? 0 : 0xffffffff; | 620 | d = vsm.sign ? 0 : 0xffffffff; |
| 622 | exceptions = FPSCR_IOC; | 621 | exceptions = FPSCR_IOC; |
| 623 | } else if (vsm.exponent >= 127 - 1) { | 622 | } else if (vsm.exponent >= 127) { |
| 624 | int shift = 127 + 31 - vsm.exponent; | 623 | int shift = 127 + 31 - vsm.exponent; |
| 625 | u32 rem, incr = 0; | 624 | u32 rem, incr = 0; |
| 626 | 625 | ||
| @@ -705,7 +704,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f | |||
| 705 | if (vsm.sign) | 704 | if (vsm.sign) |
| 706 | d = ~d; | 705 | d = ~d; |
| 707 | exceptions |= FPSCR_IOC; | 706 | exceptions |= FPSCR_IOC; |
| 708 | } else if (vsm.exponent >= 127 - 1) { | 707 | } else if (vsm.exponent >= 127) { |
| 709 | int shift = 127 + 31 - vsm.exponent; | 708 | int shift = 127 + 31 - vsm.exponent; |
| 710 | u32 rem, incr = 0; | 709 | u32 rem, incr = 0; |
| 711 | 710 | ||