summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp1412
1 files changed, 903 insertions, 509 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 73223874e..b9c2aa6c2 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -949,7 +949,7 @@ ARMul_Emulate26 (ARMul_State * state)
949 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); 949 //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp);
950 950
951 if (armOp == 0xDEADC0DE) { 951 if (armOp == 0xDEADC0DE) {
952 DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); 952 LOG_ERROR(Core_ARM11, "Failed to decode thumb opcode %04X at %08X", instr, pc);
953 } 953 }
954 954
955 instr = armOp; 955 instr = armOp;
@@ -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);
@@ -1356,7 +1356,13 @@ mainswitch:
1356 } 1356 }
1357 break; 1357 break;
1358 1358
1359 case 0x04: /* SUB reg */ 1359 case 0x04: /* SUB reg */
1360 // Signifies UMAAL
1361 if (state->is_v6 && BITS(4, 7) == 0x09) {
1362 if (handle_v6_insn(state, instr))
1363 break;
1364 }
1365
1360#ifdef MODET 1366#ifdef MODET
1361 if (BITS (4, 7) == 0xB) { 1367 if (BITS (4, 7) == 0xB) {
1362 /* STRH immediate offset, no write-back, down, post indexed. */ 1368 /* STRH immediate offset, no write-back, down, post indexed. */
@@ -1664,7 +1670,7 @@ mainswitch:
1664 op1 *= op2; 1670 op1 *= op2;
1665 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn); 1671 //printf("SMLA_INST:BB,op1=0x%x, op2=0x%x. Rn=0x%x\n", op1, op2, Rn);
1666 if (AddOverflow(op1, Rn, op1 + Rn)) 1672 if (AddOverflow(op1, Rn, op1 + Rn))
1667 SETS; 1673 SETQ;
1668 state->Reg[BITS (16, 19)] = op1 + Rn; 1674 state->Reg[BITS (16, 19)] = op1 + Rn;
1669 break; 1675 break;
1670 } 1676 }
@@ -1676,7 +1682,7 @@ mainswitch:
1676 ARMword result = op1 + op2; 1682 ARMword result = op1 + op2;
1677 if (AddOverflow(op1, op2, result)) { 1683 if (AddOverflow(op1, op2, result)) {
1678 result = POS (result) ? 0x80000000 : 0x7fffffff; 1684 result = POS (result) ? 0x80000000 : 0x7fffffff;
1679 SETS; 1685 SETQ;
1680 } 1686 }
1681 state->Reg[BITS (12, 15)] = result; 1687 state->Reg[BITS (12, 15)] = result;
1682 break; 1688 break;
@@ -1718,7 +1724,7 @@ mainswitch:
1718 TAKEABORT; 1724 TAKEABORT;
1719 } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */ 1725 } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */
1720 UNDEF_MRSPC; 1726 UNDEF_MRSPC;
1721 DEST = ECC | EINT | EMODE; 1727 DEST = ARMul_GetCPSR(state);
1722 } else { 1728 } else {
1723 UNDEF_Test; 1729 UNDEF_Test;
1724 } 1730 }
@@ -1737,7 +1743,7 @@ mainswitch:
1737 //chy 2006-02-15 if in user mode, can not set cpsr 0:23 1743 //chy 2006-02-15 if in user mode, can not set cpsr 0:23
1738 //from p165 of ARMARM book 1744 //from p165 of ARMARM book
1739 state->Cpsr = GETSPSR (state->Bank); 1745 state->Cpsr = GETSPSR (state->Bank);
1740 //ARMul_CPSRAltered (state); 1746 ARMul_CPSRAltered (state);
1741#else 1747#else
1742 rhs = DPRegRHS; 1748 rhs = DPRegRHS;
1743 temp = LHS & rhs; 1749 temp = LHS & rhs;
@@ -1789,7 +1795,7 @@ mainswitch:
1789 ARMword Rn = state->Reg[BITS(12, 15)]; 1795 ARMword Rn = state->Reg[BITS(12, 15)];
1790 1796
1791 if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn))) 1797 if (AddOverflow((ARMword)result, Rn, (ARMword)(result + Rn)))
1792 SETS; 1798 SETQ;
1793 result += Rn; 1799 result += Rn;
1794 } 1800 }
1795 state->Reg[BITS (16, 19)] = (ARMword)result; 1801 state->Reg[BITS (16, 19)] = (ARMword)result;
@@ -1805,7 +1811,7 @@ mainswitch:
1805 if (SubOverflow 1811 if (SubOverflow
1806 (op1, op2, result)) { 1812 (op1, op2, result)) {
1807 result = POS (result) ? 0x80000000 : 0x7fffffff; 1813 result = POS (result) ? 0x80000000 : 0x7fffffff;
1808 SETS; 1814 SETQ;
1809 } 1815 }
1810 1816
1811 state->Reg[BITS (12, 15)] = result; 1817 state->Reg[BITS (12, 15)] = result;
@@ -1877,7 +1883,7 @@ mainswitch:
1877 /* TEQP reg */ 1883 /* TEQP reg */
1878#ifdef MODE32 1884#ifdef MODE32
1879 state->Cpsr = GETSPSR (state->Bank); 1885 state->Cpsr = GETSPSR (state->Bank);
1880 //ARMul_CPSRAltered (state); 1886 ARMul_CPSRAltered (state);
1881#else 1887#else
1882 rhs = DPRegRHS; 1888 rhs = DPRegRHS;
1883 temp = LHS ^ rhs; 1889 temp = LHS ^ rhs;
@@ -1928,13 +1934,13 @@ mainswitch:
1928 1934
1929 if (AddOverflow 1935 if (AddOverflow
1930 (op2, op2, op2d)) { 1936 (op2, op2, op2d)) {
1931 SETS; 1937 SETQ;
1932 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 1938 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1933 } 1939 }
1934 1940
1935 result = op1 + op2d; 1941 result = op1 + op2d;
1936 if (AddOverflow(op1, op2d, result)) { 1942 if (AddOverflow(op1, op2d, result)) {
1937 SETS; 1943 SETQ;
1938 result = POS (result) ? 0x80000000 : 0x7fffffff; 1944 result = POS (result) ? 0x80000000 : 0x7fffffff;
1939 } 1945 }
1940 1946
@@ -1993,7 +1999,7 @@ mainswitch:
1993 /* CMPP reg. */ 1999 /* CMPP reg. */
1994#ifdef MODE32 2000#ifdef MODE32
1995 state->Cpsr = GETSPSR (state->Bank); 2001 state->Cpsr = GETSPSR (state->Bank);
1996 //ARMul_CPSRAltered (state); 2002 ARMul_CPSRAltered (state);
1997#else 2003#else
1998 rhs = DPRegRHS; 2004 rhs = DPRegRHS;
1999 temp = LHS - rhs; 2005 temp = LHS - rhs;
@@ -2047,13 +2053,13 @@ mainswitch:
2047 ARMword result; 2053 ARMword result;
2048 2054
2049 if (AddOverflow(op2, op2, op2d)) { 2055 if (AddOverflow(op2, op2, op2d)) {
2050 SETS; 2056 SETQ;
2051 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; 2057 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
2052 } 2058 }
2053 2059
2054 result = op1 - op2d; 2060 result = op1 - op2d;
2055 if (SubOverflow(op1, op2d, result)) { 2061 if (SubOverflow(op1, op2d, result)) {
2056 SETS; 2062 SETQ;
2057 result = POS (result) ? 0x80000000 : 0x7fffffff; 2063 result = POS (result) ? 0x80000000 : 0x7fffffff;
2058 } 2064 }
2059 2065
@@ -2112,7 +2118,7 @@ mainswitch:
2112 if (DESTReg == 15) { 2118 if (DESTReg == 15) {
2113#ifdef MODE32 2119#ifdef MODE32
2114 state->Cpsr = GETSPSR (state->Bank); 2120 state->Cpsr = GETSPSR (state->Bank);
2115 //ARMul_CPSRAltered (state); 2121 ARMul_CPSRAltered (state);
2116#else 2122#else
2117 rhs = DPRegRHS; 2123 rhs = DPRegRHS;
2118 temp = LHS + rhs; 2124 temp = LHS + rhs;
@@ -2200,17 +2206,57 @@ mainswitch:
2200 Handle_Store_Double (state, instr); 2206 Handle_Store_Double (state, instr);
2201 break; 2207 break;
2202 } 2208 }
2209 if (BITS(4, 11) == 0xF9) { //strexd
2210 u32 l = LHSReg;
2211
2212 bool enter = false;
2213
2214 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&&
2215 state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4))
2216 enter = true;
2217
2218
2219 //todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html
2220
2221
2222 if (enter) {
2223 ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]);
2224 ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]);
2225 state->Reg[DESTReg] = 0;
2226 } else {
2227 state->Reg[DESTReg] = 1;
2228 }
2229
2230 break;
2231 }
2203#endif 2232#endif
2204 dest = DPRegRHS; 2233 dest = DPRegRHS;
2205 WRITEDEST (dest); 2234 WRITEDEST (dest);
2206 break; 2235 break;
2207 2236
2208 case 0x1b: /* MOVS reg */ 2237 case 0x1B: /* MOVS reg */
2209#ifdef MODET 2238#ifdef MODET
2239 /* ldrexd ichfly */
2240 if (BITS(0, 11) == 0xF9F) { //strexd
2241 lhs = LHS;
2242
2243 state->currentexaddr = lhs;
2244 state->currentexval = (u32)ARMul_ReadWord(state, lhs);
2245 state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4);
2246
2247 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs);
2248 state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4);
2249 break;
2250 }
2251
2210 if ((BITS (4, 11) & 0xF9) == 0x9) 2252 if ((BITS (4, 11) & 0xF9) == 0x9)
2211 /* LDR register offset, write-back, up, pre indexed. */ 2253 /* LDR register offset, write-back, up, pre indexed. */
2212 LHPREUPWB (); 2254 LHPREUPWB ();
2213 /* Continue with remaining instruction decoding. */ 2255 /* Continue with remaining instruction decoding. */
2256
2257
2258
2259
2214#endif 2260#endif
2215 dest = DPSRegRHS; 2261 dest = DPSRegRHS;
2216 WRITESDEST (dest); 2262 WRITESDEST (dest);
@@ -2297,12 +2343,12 @@ mainswitch:
2297 if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true; 2343 if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
2298 2344
2299 2345
2300 ARMul_StoreHalfWord(state, lhs, RHS);
2301 //StoreWord(state, lhs, RHS) 2346 //StoreWord(state, lhs, RHS)
2302 if (state->Aborted) { 2347 if (state->Aborted) {
2303 TAKEABORT; 2348 TAKEABORT;
2304 } 2349 }
2305 if (enter) { 2350 if (enter) {
2351 ARMul_StoreHalfWord(state, lhs, RHS);
2306 state->Reg[DESTReg] = 0; 2352 state->Reg[DESTReg] = 0;
2307 } else { 2353 } else {
2308 state->Reg[DESTReg] = 1; 2354 state->Reg[DESTReg] = 1;
@@ -2520,7 +2566,7 @@ mainswitch:
2520 /* TSTP immed. */ 2566 /* TSTP immed. */
2521#ifdef MODE32 2567#ifdef MODE32
2522 state->Cpsr = GETSPSR (state->Bank); 2568 state->Cpsr = GETSPSR (state->Bank);
2523 //ARMul_CPSRAltered (state); 2569 ARMul_CPSRAltered (state);
2524#else 2570#else
2525 temp = LHS & DPImmRHS; 2571 temp = LHS & DPImmRHS;
2526 SETR15PSR (temp); 2572 SETR15PSR (temp);
@@ -2547,7 +2593,7 @@ mainswitch:
2547 /* TEQP immed. */ 2593 /* TEQP immed. */
2548#ifdef MODE32 2594#ifdef MODE32
2549 state->Cpsr = GETSPSR (state->Bank); 2595 state->Cpsr = GETSPSR (state->Bank);
2550 //ARMul_CPSRAltered (state); 2596 ARMul_CPSRAltered (state);
2551#else 2597#else
2552 temp = LHS ^ DPImmRHS; 2598 temp = LHS ^ DPImmRHS;
2553 SETR15PSR (temp); 2599 SETR15PSR (temp);
@@ -2568,7 +2614,7 @@ mainswitch:
2568 /* CMPP immed. */ 2614 /* CMPP immed. */
2569#ifdef MODE32 2615#ifdef MODE32
2570 state->Cpsr = GETSPSR (state->Bank); 2616 state->Cpsr = GETSPSR (state->Bank);
2571 //ARMul_CPSRAltered (state); 2617 ARMul_CPSRAltered (state);
2572#else 2618#else
2573 temp = LHS - DPImmRHS; 2619 temp = LHS - DPImmRHS;
2574 SETR15PSR (temp); 2620 SETR15PSR (temp);
@@ -2604,7 +2650,7 @@ mainswitch:
2604 /* CMNP immed. */ 2650 /* CMNP immed. */
2605#ifdef MODE32 2651#ifdef MODE32
2606 state->Cpsr = GETSPSR (state->Bank); 2652 state->Cpsr = GETSPSR (state->Bank);
2607 //ARMul_CPSRAltered (state); 2653 ARMul_CPSRAltered (state);
2608#else 2654#else
2609 temp = LHS + DPImmRHS; 2655 temp = LHS + DPImmRHS;
2610 SETR15PSR (temp); 2656 SETR15PSR (temp);
@@ -3054,27 +3100,21 @@ mainswitch:
3054 break; 3100 break;
3055 3101
3056 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ 3102 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
3057 //ichfly PKHBT PKHTB todo check this 3103 if ((instr & 0x70) == 0x10) { //pkhbt
3058 if ((instr & 0x70) == 0x10) //pkhbt
3059 {
3060 u8 idest = BITS(12, 15); 3104 u8 idest = BITS(12, 15);
3061 u8 rfis = BITS(16, 19); 3105 u8 rfis = BITS(16, 19);
3062 u8 rlast = BITS(0, 3); 3106 u8 rlast = BITS(0, 3);
3063 u8 ishi = BITS(7,11); 3107 u8 ishi = BITS(7,11);
3064 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); 3108 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
3065 break; 3109 break;
3066 } 3110 } else if ((instr & 0x70) == 0x50) { //pkhtb
3067 else if ((instr & 0x70) == 0x50)//pkhtb 3111 u8 rd_idx = BITS(12, 15);
3068 { 3112 u8 rn_idx = BITS(16, 19);
3069 u8 idest = BITS(12, 15); 3113 u8 rm_idx = BITS(0, 3);
3070 u8 rfis = BITS(16, 19); 3114 u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
3071 u8 rlast = BITS(0, 3); 3115 state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3072 u8 ishi = BITS(7, 11);
3073 if (ishi == 0)ishi = 0x20;
3074 state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000);
3075 break; 3116 break;
3076 } 3117 } else if (BIT (4)) {
3077 else if (BIT (4)) {
3078#ifdef MODE32 3118#ifdef MODE32
3079 if (state->is_v6 3119 if (state->is_v6
3080 && handle_v6_insn (state, instr)) 3120 && handle_v6_insn (state, instr))
@@ -3437,7 +3477,7 @@ mainswitch:
3437 3477
3438 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */ 3478 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
3439 if (BIT (4)) { 3479 if (BIT (4)) {
3440 DEBUG("got unhandled special breakpoint\n"); 3480 LOG_DEBUG(Core_ARM11, "got unhandled special breakpoint");
3441 return 1; 3481 return 1;
3442 } 3482 }
3443 UNDEF_LSRBaseEQOffWb; 3483 UNDEF_LSRBaseEQOffWb;
@@ -3686,13 +3726,11 @@ mainswitch:
3686 3726
3687 /* Co-Processor Data Transfers. */ 3727 /* Co-Processor Data Transfers. */
3688 case 0xc4: 3728 case 0xc4:
3689 if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0 3729 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)]; 3730 state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
3692 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; 3731 state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
3693 break; 3732 break;
3694 } 3733 } else if (state->is_v5) {
3695 else if (state->is_v5) {
3696 /* Reading from R15 is UNPREDICTABLE. */ 3734 /* Reading from R15 is UNPREDICTABLE. */
3697 if (BITS (12, 15) == 15 || BITS (16, 19) == 15) 3735 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3698 ARMul_UndefInstr (state, instr); 3736 ARMul_UndefInstr (state, instr);
@@ -3712,22 +3750,18 @@ mainswitch:
3712 break; 3750 break;
3713 3751
3714 case 0xc5: 3752 case 0xc5:
3715 if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0 3753 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]; 3754 state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
3718 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; 3755 state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
3719 break; 3756 break;
3720 } 3757 } else if (state->is_v5) {
3721 else if (state->is_v5) {
3722 /* Writes to R15 are UNPREDICATABLE. */ 3758 /* Writes to R15 are UNPREDICATABLE. */
3723 if (DESTReg == 15 || LHSReg == 15) 3759 if (DESTReg == 15 || LHSReg == 15)
3724 ARMul_UndefInstr (state, instr); 3760 ARMul_UndefInstr (state, instr);
3725 /* Is access to the coprocessor allowed ? */ 3761 /* Is access to the coprocessor allowed ? */
3726 else if (!CP_ACCESS_ALLOWED(state, CPNum)) 3762 else if (!CP_ACCESS_ALLOWED(state, CPNum)) {
3727 {
3728 ARMul_UndefInstr(state, instr); 3763 ARMul_UndefInstr(state, instr);
3729 } 3764 } else {
3730 else {
3731 /* MRRC, ARMv5TE and up */ 3765 /* MRRC, ARMv5TE and up */
3732 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); 3766 ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
3733 break; 3767 break;
@@ -4565,7 +4599,7 @@ out:
4565#ifdef MODE32 4599#ifdef MODE32
4566 if (state->Bank > 0) { 4600 if (state->Bank > 0) {
4567 state->Cpsr = state->Spsr[state->Bank]; 4601 state->Cpsr = state->Spsr[state->Bank];
4568 //ARMul_CPSRAltered (state); 4602 ARMul_CPSRAltered (state);
4569 } 4603 }
4570#ifdef MODET 4604#ifdef MODET
4571 if (TFLAG) 4605 if (TFLAG)
@@ -5256,7 +5290,7 @@ L_ldm_s_makeabort:
5256 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode 5290 //chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
5257 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) { 5291 if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
5258 state->Cpsr = GETSPSR (state->Bank); 5292 state->Cpsr = GETSPSR (state->Bank);
5259 //ARMul_CPSRAltered (state); 5293 ARMul_CPSRAltered (state);
5260 } 5294 }
5261 5295
5262 WriteR15 (state, PC); 5296 WriteR15 (state, PC);
@@ -5639,37 +5673,29 @@ L_stm_s_takeabort:
5639 /* Attempt to emulate an ARMv6 instruction. 5673 /* Attempt to emulate an ARMv6 instruction.
5640 Returns non-zero upon success. */ 5674 Returns non-zero upon success. */
5641 5675
5642 static int 5676 static int handle_v6_insn(ARMul_State* state, ARMword instr) {
5643 handle_v6_insn (ARMul_State * state, ARMword instr) { 5677 switch (BITS(20, 27)) {
5644 switch (BITS (20, 27)) {
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
5654 u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub));
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: 5678 case 0x03:
5669 printf ("Unhandled v6 insn: ldr\n"); 5679 printf ("Unhandled v6 insn: ldr\n");
5670 break; 5680 break;
5671 case 0x04: 5681 case 0x04: // UMAAL
5672 printf ("Unhandled v6 insn: umaal\n"); 5682 {
5683 const u8 rm_idx = BITS(8, 11);
5684 const u8 rn_idx = BITS(0, 3);
5685 const u8 rd_lo_idx = BITS(12, 15);
5686 const u8 rd_hi_idx = BITS(16, 19);
5687
5688 const u32 rm_val = state->Reg[rm_idx];
5689 const u32 rn_val = state->Reg[rn_idx];
5690 const u32 rd_lo_val = state->Reg[rd_lo_idx];
5691 const u32 rd_hi_val = state->Reg[rd_hi_idx];
5692
5693 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
5694
5695 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
5696 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
5697 return 1;
5698 }
5673 break; 5699 break;
5674 case 0x06: 5700 case 0x06:
5675 printf ("Unhandled v6 insn: mls/str\n"); 5701 printf ("Unhandled v6 insn: mls/str\n");
@@ -5678,9 +5704,43 @@ L_stm_s_takeabort:
5678 printf ("Unhandled v6 insn: smi\n"); 5704 printf ("Unhandled v6 insn: smi\n");
5679 break; 5705 break;
5680 case 0x18: 5706 case 0x18:
5707 if (BITS(4, 7) == 0x9) {
5708 /* strex */
5709 u32 l = LHSReg;
5710 u32 r = RHSReg;
5711 u32 lhs = LHS;
5712
5713 bool enter = false;
5714
5715 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
5716 //StoreWord(state, lhs, RHS)
5717 if (state->Aborted) {
5718 TAKEABORT;
5719 }
5720
5721 if (enter) {
5722 ARMul_StoreWordS(state, lhs, RHS);
5723 state->Reg[DESTReg] = 0;
5724 }
5725 else {
5726 state->Reg[DESTReg] = 1;
5727 }
5728
5729 return 1;
5730 }
5681 printf ("Unhandled v6 insn: strex\n"); 5731 printf ("Unhandled v6 insn: strex\n");
5682 break; 5732 break;
5683 case 0x19: 5733 case 0x19:
5734 /* ldrex */
5735 if (BITS(4, 7) == 0x9) {
5736 u32 lhs = LHS;
5737
5738 state->currentexaddr = lhs;
5739 state->currentexval = ARMul_ReadWord(state, lhs);
5740
5741 LoadWord(state, instr, lhs);
5742 return 1;
5743 }
5684 printf ("Unhandled v6 insn: ldrex\n"); 5744 printf ("Unhandled v6 insn: ldrex\n");
5685 break; 5745 break;
5686 case 0x1a: 5746 case 0x1a:
@@ -5690,9 +5750,52 @@ L_stm_s_takeabort:
5690 printf ("Unhandled v6 insn: ldrexd\n"); 5750 printf ("Unhandled v6 insn: ldrexd\n");
5691 break; 5751 break;
5692 case 0x1c: 5752 case 0x1c:
5753 if (BITS(4, 7) == 0x9) {
5754 /* strexb */
5755 u32 lhs = LHS;
5756
5757 bool enter = false;
5758
5759 if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
5760
5761 BUSUSEDINCPCN;
5762 if (state->Aborted) {
5763 TAKEABORT;
5764 }
5765
5766
5767 if (enter) {
5768 ARMul_StoreByte(state, lhs, RHS);
5769 state->Reg[DESTReg] = 0;
5770 }
5771 else {
5772 state->Reg[DESTReg] = 1;
5773 }
5774
5775 //printf("In %s, strexb not implemented\n", __FUNCTION__);
5776 UNDEF_LSRBPC;
5777 /* WRITESDEST (dest); */
5778 return 1;
5779 }
5693 printf ("Unhandled v6 insn: strexb\n"); 5780 printf ("Unhandled v6 insn: strexb\n");
5694 break; 5781 break;
5695 case 0x1d: 5782 case 0x1d:
5783 if ((BITS(4, 7)) == 0x9) {
5784 /* ldrexb */
5785 u32 lhs = LHS;
5786 LoadByte(state, instr, lhs, LUNSIGNED);
5787
5788 state->currentexaddr = lhs;
5789 state->currentexval = (u32)ARMul_ReadByte(state, lhs);
5790
5791 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
5792 //printf("ldrexb\n");
5793 //printf("instr is %x rm is %d\n", instr, BITS(16, 19));
5794 //exit(-1);
5795
5796 //printf("In %s, ldrexb not implemented\n", __FUNCTION__);
5797 return 1;
5798 }
5696 printf ("Unhandled v6 insn: ldrexb\n"); 5799 printf ("Unhandled v6 insn: ldrexb\n");
5697 break; 5800 break;
5698 case 0x1e: 5801 case 0x1e:
@@ -5713,510 +5816,801 @@ L_stm_s_takeabort:
5713 case 0x3f: 5816 case 0x3f:
5714 printf ("Unhandled v6 insn: rbit\n"); 5817 printf ("Unhandled v6 insn: rbit\n");
5715 break; 5818 break;
5716#endif 5819 case 0x61: // SADD16, SASX, SSAX, and SSUB16
5717 case 0x61: 5820 if ((instr & 0xFF0) == 0xf10 || (instr & 0xFF0) == 0xf30 ||
5718 if ((instr & 0xFF0) == 0xf70)//ssub16 5821 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf70)
5719 {
5720 u8 tar = BITS(12, 15);
5721 u8 src1 = BITS(16, 19);
5722 u8 src2 = BITS(0, 3);
5723 s16 a1 = (state->Reg[src1] & 0xFFFF);
5724 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5725 s16 b1 = (state->Reg[src2] & 0xFFFF);
5726 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5727 state->Reg[tar] = (a1 - a2)&0xFFFF | (((b1 - b2)&0xFFFF)<< 0x10);
5728 return 1;
5729 }
5730 else if ((instr & 0xFF0) == 0xf10)//sadd16
5731 { 5822 {
5732 u8 tar = BITS(12, 15); 5823 const u8 rd_idx = BITS(12, 15);
5733 u8 src1 = BITS(16, 19); 5824 const u8 rm_idx = BITS(0, 3);
5734 u8 src2 = BITS(0, 3); 5825 const u8 rn_idx = BITS(16, 19);
5735 s16 a1 = (state->Reg[src1] & 0xFFFF); 5826 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5736 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5827 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5737 s16 b1 = (state->Reg[src2] & 0xFFFF); 5828 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5738 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5829 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5739 state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10); 5830
5831 s32 lo_result;
5832 s32 hi_result;
5833
5834 // SADD16
5835 if ((instr & 0xFF0) == 0xf10) {
5836 lo_result = (rn_lo + rm_lo);
5837 hi_result = (rn_hi + rm_hi);
5838 }
5839 // SASX
5840 else if ((instr & 0xFF0) == 0xf30) {
5841 lo_result = (rn_lo - rm_hi);
5842 hi_result = (rn_hi + rm_lo);
5843 }
5844 // SSAX
5845 else if ((instr & 0xFF0) == 0xf50) {
5846 lo_result = (rn_lo + rm_hi);
5847 hi_result = (rn_hi - rm_lo);
5848 }
5849 // SSUB16
5850 else {
5851 lo_result = (rn_lo - rm_lo);
5852 hi_result = (rn_hi - rm_hi);
5853 }
5854
5855 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5856
5857 if (lo_result >= 0) {
5858 state->GEFlag |= (1 << 16);
5859 state->GEFlag |= (1 << 17);
5860 } else {
5861 state->GEFlag &= ~(1 << 16);
5862 state->GEFlag &= ~(1 << 17);
5863 }
5864
5865 if (hi_result >= 0) {
5866 state->GEFlag |= (1 << 18);
5867 state->GEFlag |= (1 << 19);
5868 } else {
5869 state->GEFlag &= ~(1 << 18);
5870 state->GEFlag &= ~(1 << 19);
5871 }
5872
5740 return 1; 5873 return 1;
5741 } 5874 }
5742 else if ((instr & 0xFF0) == 0xf50)//ssax 5875 // SADD8/SSUB8
5876 else if ((instr & 0xFF0) == 0xf90 || (instr & 0xFF0) == 0xff0)
5743 { 5877 {
5744 u8 tar = BITS(12, 15); 5878 const u8 rd_idx = BITS(12, 15);
5745 u8 src1 = BITS(16, 19); 5879 const u8 rm_idx = BITS(0, 3);
5746 u8 src2 = BITS(0, 3); 5880 const u8 rn_idx = BITS(16, 19);
5747 s16 a1 = (state->Reg[src1] & 0xFFFF); 5881 const u32 rm_val = state->Reg[rm_idx];
5748 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5882 const u32 rn_val = state->Reg[rn_idx];
5749 s16 b1 = (state->Reg[src2] & 0xFFFF); 5883
5750 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5884 u8 lo_val1;
5751 state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); 5885 u8 lo_val2;
5886 u8 hi_val1;
5887 u8 hi_val2;
5888
5889 // SADD8
5890 if ((instr & 0xFF0) == 0xf90) {
5891 lo_val1 = (u8)((rn_val & 0xFF) + (rm_val & 0xFF));
5892 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF));
5893 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF));
5894 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF));
5895
5896 if (lo_val1 & 0x80)
5897 state->GEFlag |= (1 << 16);
5898 else
5899 state->GEFlag &= ~(1 << 16);
5900
5901 if (lo_val2 & 0x80)
5902 state->GEFlag |= (1 << 17);
5903 else
5904 state->GEFlag &= ~(1 << 17);
5905
5906 if (hi_val1 & 0x80)
5907 state->GEFlag |= (1 << 18);
5908 else
5909 state->GEFlag &= ~(1 << 18);
5910
5911 if (hi_val2 & 0x80)
5912 state->GEFlag |= (1 << 19);
5913 else
5914 state->GEFlag &= ~(1 << 19);
5915 }
5916 // SSUB8
5917 else {
5918 lo_val1 = (u8)((rn_val & 0xFF) - (rm_val & 0xFF));
5919 lo_val2 = (u8)(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF));
5920 hi_val1 = (u8)(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF));
5921 hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
5922
5923 if (!(lo_val1 & 0x80))
5924 state->GEFlag |= (1 << 16);
5925 else
5926 state->GEFlag &= ~(1 << 16);
5927
5928 if (!(lo_val2 & 0x80))
5929 state->GEFlag |= (1 << 17);
5930 else
5931 state->GEFlag &= ~(1 << 17);
5932
5933 if (!(hi_val1 & 0x80))
5934 state->GEFlag |= (1 << 18);
5935 else
5936 state->GEFlag &= ~(1 << 18);
5937
5938 if (!(hi_val2 & 0x80))
5939 state->GEFlag |= (1 << 19);
5940 else
5941 state->GEFlag &= ~(1 << 19);
5942 }
5943
5944 state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24);
5752 return 1; 5945 return 1;
5753 } 5946 }
5754 else if ((instr & 0xFF0) == 0xf30)//sasx 5947 else {
5755 { 5948 printf("Unhandled v6 insn: %08x", instr);
5756 u8 tar = BITS(12, 15);
5757 u8 src1 = BITS(16, 19);
5758 u8 src2 = BITS(0, 3);
5759 s16 a1 = (state->Reg[src1] & 0xFFFF);
5760 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5761 s16 b1 = (state->Reg[src2] & 0xFFFF);
5762 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5763 state->Reg[tar] = (a2 - b1) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10);
5764 return 1;
5765 } 5949 }
5766 else printf ("Unhandled v6 insn: sadd/ssub\n");
5767 break; 5950 break;
5768 case 0x62: 5951 case 0x62: // QADD16, QASX, QSAX, QSUB16, QADD8, and QSUB8
5769 if ((instr & 0xFF0) == 0xf70)//QSUB16
5770 { 5952 {
5771 u8 tar = BITS(12, 15); 5953 const u8 op2 = BITS(5, 7);
5772 u8 src1 = BITS(16, 19); 5954
5773 u8 src2 = BITS(0, 3); 5955 const u8 rd_idx = BITS(12, 15);
5774 s16 a1 = (state->Reg[src1] & 0xFFFF); 5956 const u8 rn_idx = BITS(16, 19);
5775 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5957 const u8 rm_idx = BITS(0, 3);
5776 s16 b1 = (state->Reg[src2] & 0xFFFF); 5958 const u16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5777 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5959 const u16 rm_hi = ((state->Reg[rm_idx] >> 0x10) & 0xFFFF);
5778 s32 res1 = (a1 - b1); 5960 const u16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5779 s32 res2 = (a2 - b2); 5961 const u16 rn_hi = ((state->Reg[rn_idx] >> 0x10) & 0xFFFF);
5780 if (res1 > 0x7FFF) res1 = 0x7FFF; 5962
5781 if (res2 > 0x7FFF) res2 = 0x7FFF; 5963 u16 lo_result = 0;
5782 if (res1 < 0x7FFF) res1 = -0x8000; 5964 u16 hi_result = 0;
5783 if (res2 < 0x7FFF) res2 = -0x8000; 5965
5784 state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); 5966 // QADD16
5785 return 1; 5967 if (op2 == 0x00) {
5786 } 5968 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo);
5787 else if ((instr & 0xFF0) == 0xf10)//QADD16 5969 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi);
5788 { 5970 }
5789 u8 tar = BITS(12, 15); 5971 // QASX
5790 u8 src1 = BITS(16, 19); 5972 else if (op2 == 0x01) {
5791 u8 src2 = BITS(0, 3); 5973 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi);
5792 s16 a1 = (state->Reg[src1] & 0xFFFF); 5974 hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo);
5793 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5975 }
5794 s16 b1 = (state->Reg[src2] & 0xFFFF); 5976 // QSAX
5795 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5977 else if (op2 == 0x02) {
5796 s32 res1 = (a1 + b1); 5978 lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi);
5797 s32 res2 = (a2 + b2); 5979 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo);
5798 if (res1 > 0x7FFF) res1 = 0x7FFF; 5980 }
5799 if (res2 > 0x7FFF) res2 = 0x7FFF; 5981 // QSUB16
5800 if (res1 < 0x7FFF) res1 = -0x8000; 5982 else if (op2 == 0x03) {
5801 if (res2 < 0x7FFF) res2 = -0x8000; 5983 lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo);
5802 state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); 5984 hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi);
5985 }
5986 // QADD8
5987 else if (op2 == 0x04) {
5988 lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) |
5989 ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8;
5990 hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) |
5991 ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8;
5992 }
5993 // QSUB8
5994 else if (op2 == 0x07) {
5995 lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) |
5996 ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8;
5997 hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) |
5998 ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8;
5999 }
6000
6001 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5803 return 1; 6002 return 1;
5804 } 6003 }
5805 else printf ("Unhandled v6 insn: qadd/qsub\n");
5806 break; 6004 break;
5807#if 0
5808 case 0x63: 6005 case 0x63:
5809 printf ("Unhandled v6 insn: shadd/shsub\n"); 6006 printf ("Unhandled v6 insn: shadd/shsub\n");
5810 break; 6007 break;
5811 case 0x65: 6008 case 0x65:
5812 printf ("Unhandled v6 insn: uadd/usub\n"); 6009 {
5813 break; 6010 u32 rd = (instr >> 12) & 0xF;
5814 case 0x66: 6011 u32 rn = (instr >> 16) & 0xF;
5815 printf ("Unhandled v6 insn: uqadd/uqsub\n"); 6012 u32 rm = (instr >> 0) & 0xF;
5816 break; 6013 u32 from = state->Reg[rn];
5817 case 0x67: 6014 u32 to = state->Reg[rm];
5818 printf ("Unhandled v6 insn: uhadd/uhsub\n"); 6015
5819 break; 6016 if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16
5820 case 0x68: 6017 u32 h1, h2;
5821 printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); 6018 state->Cpsr &= 0xfff0ffff;
5822 break; 6019 if ((instr & 0x0F0) == 0x070) { // USUB16
5823#endif 6020 h1 = ((u16)from - (u16)to);
5824 case 0x6c: 6021 h2 = ((u16)(from >> 16) - (u16)(to >> 16));
5825 if ((instr & 0xf03f0) == 0xf0070) //uxtb16 6022
5826 { 6023 if (!(h1 & 0xffff0000))
5827 u8 src1 = BITS(0, 3); 6024 state->GEFlag |= (3 << 16);
5828 u8 tar = BITS(12, 15); 6025 else
5829 u32 base = state->Reg[src1]; 6026 state->GEFlag &= ~(3 << 16);
5830 u32 shamt = BITS(9,10)* 8;
5831 u32 in = ((base << (32 - shamt)) | (base >> shamt));
5832 state->Reg[tar] = in & 0x00FF00FF;
5833 return 1;
5834 }
5835 else
5836 printf ("Unhandled v6 insn: uxtb16/uxtab16\n");
5837 break;
5838 case 0x70:
5839 if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly
5840 {
5841 u8 tar = BITS(16, 19);
5842 u8 src1 = BITS(0, 3);
5843 u8 src2 = BITS(8, 11);
5844 u8 swap = BIT(5);
5845 s16 a1 = (state->Reg[src1] & 0xFFFF);
5846 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5847 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5848 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5849 state->Reg[tar] = a1*a2 + b1*b2;
5850 return 1;
5851 6027
5852 } 6028 if (!(h2 & 0xffff0000))
5853 else if ((instr & 0xf0d0) == 0xf050)//smusd 6029 state->GEFlag |= (3 << 18);
5854 { 6030 else
5855 u8 tar = BITS(16, 19); 6031 state->GEFlag &= ~(3 << 18);
5856 u8 src1 = BITS(0, 3); 6032 }
5857 u8 src2 = BITS(8, 11); 6033 else { // UADD16
5858 u8 swap = BIT(5); 6034 h1 = ((u16)from + (u16)to);
5859 s16 a1 = (state->Reg[src1] & 0xFFFF); 6035 h2 = ((u16)(from >> 16) + (u16)(to >> 16));
5860 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 6036
5861 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); 6037 if (h1 & 0xffff0000)
5862 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); 6038 state->GEFlag |= (3 << 16);
5863 state->Reg[tar] = a1*a2 - b1*b2; 6039 else
5864 return 1; 6040 state->GEFlag &= ~(3 << 16);
5865 } 6041
5866 else if ((instr & 0xd0) == 0x10)//smlad 6042 if (h2 & 0xffff0000)
5867 { 6043 state->GEFlag |= (3 << 18);
5868 u8 tar = BITS(16, 19); 6044 else
5869 u8 src1 = BITS(0, 3); 6045 state->GEFlag &= ~(3 << 18);
5870 u8 src2 = BITS(8, 11); 6046 }
5871 u8 src3 = BITS(12, 15); 6047
5872 u8 swap = BIT(5); 6048 state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
5873
5874 u32 a3 = state->Reg[src3];
5875
5876 s16 a1 = (state->Reg[src1] & 0xFFFF);
5877 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5878 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
5879 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
5880 state->Reg[tar] = a1*a2 + b1*b2 + a3;
5881 return 1; 6049 return 1;
5882 } 6050 }
5883 else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); 6051 else
5884 break; 6052 if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8
5885 case 0x74: 6053 u32 b1, b2, b3, b4;
5886 printf ("Unhandled v6 insn: smlald/smlsld\n"); 6054 state->Cpsr &= 0xfff0ffff;
5887 break; 6055 if ((instr & 0x0F0) == 0x0F0) { // USUB8
5888 case 0x75: 6056 b1 = ((u8)from - (u8)to);
5889 printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); 6057 b2 = ((u8)(from >> 8) - (u8)(to >> 8));
5890 break; 6058 b3 = ((u8)(from >> 16) - (u8)(to >> 16));
5891 case 0x78: 6059 b4 = ((u8)(from >> 24) - (u8)(to >> 24));
5892 printf ("Unhandled v6 insn: usad/usada8\n"); 6060
5893 break; 6061 if (!(b1 & 0xffffff00))
5894#if 0 6062 state->GEFlag |= (1 << 16);
5895 case 0x7a: 6063 else
5896 printf ("Unhandled v6 insn: usbfx\n"); 6064 state->GEFlag &= ~(1 << 16);
5897 break;
5898 case 0x7c:
5899 printf ("Unhandled v6 insn: bfc/bfi\n");
5900 break;
5901#endif
5902 6065
6066 if (!(b2 & 0xffffff00))
6067 state->GEFlag |= (1 << 17);
6068 else
6069 state->GEFlag &= ~(1 << 17);
5903 6070
5904 /* add new instr for arm v6. */ 6071 if (!(b3 & 0xffffff00))
5905 ARMword lhs, temp; 6072 state->GEFlag |= (1 << 18);
5906 case 0x18: { /* ORR reg */ 6073 else
5907 /* dyf add armv6 instr strex 2010.9.17 */ 6074 state->GEFlag &= ~(1 << 18);
5908 if (BITS (4, 7) == 0x9) {
5909 u32 l = LHSReg;
5910 u32 r = RHSReg;
5911 lhs = LHS;
5912 6075
5913 bool enter = false; 6076 if (!(b4 & 0xffffff00))
6077 state->GEFlag |= (1 << 19);
6078 else
6079 state->GEFlag &= ~(1 << 19);
6080 }
6081 else { // UADD8
6082 b1 = ((u8)from + (u8)to);
6083 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
6084 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
6085 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5914 6086
5915 if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true; 6087 if (b1 & 0xffffff00)
5916 ARMul_StoreWordS(state, lhs, RHS); 6088 state->GEFlag |= (1 << 16);
5917 //StoreWord(state, lhs, RHS) 6089 else
5918 if (state->Aborted) { 6090 state->GEFlag &= ~(1 << 16);
5919 TAKEABORT;
5920 }
5921 6091
5922 if (enter) { 6092 if (b2 & 0xffffff00)
5923 state->Reg[DESTReg] = 0; 6093 state->GEFlag |= (1 << 17);
5924 } else { 6094 else
5925 state->Reg[DESTReg] = 1; 6095 state->GEFlag &= ~(1 << 17);
5926 }
5927 6096
5928 return 1; 6097 if (b3 & 0xffffff00)
5929 } 6098 state->GEFlag |= (1 << 18);
5930 break; 6099 else
5931 } 6100 state->GEFlag &= ~(1 << 18);
5932 6101
5933 case 0x19: { /* orrs reg */ 6102 if (b4 & 0xffffff00)
5934 /* dyf add armv6 instr ldrex */ 6103 state->GEFlag |= (1 << 19);
5935 if (BITS (4, 7) == 0x9) { 6104 else
5936 lhs = LHS; 6105 state->GEFlag &= ~(1 << 19);
6106 }
5937 6107
5938 state->currentexaddr = lhs; 6108 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5939 state->currentexval = ARMul_ReadWord(state, lhs); 6109 return 1;
6110 }
6111 }
6112 printf("Unhandled v6 insn: uasx/usax\n");
6113 break;
6114 case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
6115 {
6116 const u8 rd_idx = BITS(12, 15);
6117 const u8 rm_idx = BITS(0, 3);
6118 const u8 rn_idx = BITS(16, 19);
6119 const u8 op2 = BITS(5, 7);
6120 const u32 rm_val = state->Reg[rm_idx];
6121 const u32 rn_val = state->Reg[rn_idx];
6122
6123 u16 lo_val = 0;
6124 u16 hi_val = 0;
6125
6126 // UQADD16
6127 if (op2 == 0x00) {
6128 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6129 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6130 }
6131 // UQASX
6132 else if (op2 == 0x01) {
6133 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6134 hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6135 }
6136 // UQSAX
6137 else if (op2 == 0x02) {
6138 lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6139 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
6140 }
6141 // UQSUB16
6142 else if (op2 == 0x03) {
6143 lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
6144 hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
6145 }
6146 // UQADD8
6147 else if (op2 == 0x04) {
6148 lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
6149 ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
6150 hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
6151 ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
6152 }
6153 // UQSUB8
6154 else {
6155 lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
6156 ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
6157 hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
6158 ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
6159 }
5940 6160
5941 LoadWord (state, instr, lhs); 6161 state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
5942 return 1; 6162 return 1;
5943 } 6163 }
5944 break; 6164 break;
5945 } 6165 case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
6166 {
6167 const u8 op2 = BITS(5, 7);
5946 6168
5947 case 0x1c: { /* BIC reg */ 6169 const u8 rm_idx = BITS(0, 3);
5948 /* dyf add for STREXB */ 6170 const u8 rn_idx = BITS(16, 19);
5949 if (BITS (4, 7) == 0x9) { 6171 const u8 rd_idx = BITS(12, 15);
5950 lhs = LHS;
5951 6172
5952 bool enter = false; 6173 const u32 rm_val = state->Reg[rm_idx];
6174 const u32 rn_val = state->Reg[rn_idx];
5953 6175
5954 if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true; 6176 if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
6177 {
6178 u32 lo_val = 0;
6179 u32 hi_val = 0;
5955 6180
5956 ARMul_StoreByte (state, lhs, RHS); 6181 // UHADD16
5957 BUSUSEDINCPCN; 6182 if (op2 == 0x00) {
5958 if (state->Aborted) { 6183 lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
5959 TAKEABORT; 6184 hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
5960 } 6185 }
6186 // UHASX
6187 else if (op2 == 0x01) {
6188 lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6189 hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
6190 }
6191 // UHSAX
6192 else if (op2 == 0x02) {
6193 lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
6194 hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
6195 }
6196 // UHSUB16
6197 else if (op2 == 0x03) {
6198 lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
6199 hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
6200 }
5961 6201
6202 lo_val >>= 1;
6203 hi_val >>= 1;
5962 6204
5963 if (enter) { 6205 state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
5964 state->Reg[DESTReg] = 0; 6206 return 1;
5965 } else { 6207 }
5966 state->Reg[DESTReg] = 1; 6208 else if (op2 == 0x04 || op2 == 0x07) {
6209 u32 sum1;
6210 u32 sum2;
6211 u32 sum3;
6212 u32 sum4;
6213
6214 // UHADD8
6215 if (op2 == 0x04) {
6216 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
6217 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
6218 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
6219 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
6220 }
6221 // UHSUB8
6222 else {
6223 sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
6224 sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
6225 sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
6226 sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
6227 }
6228
6229 sum1 >>= 1;
6230 sum2 >>= 1;
6231 sum3 >>= 1;
6232 sum4 >>= 1;
6233
6234 state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
6235 return 1;
5967 } 6236 }
5968
5969 //printf("In %s, strexb not implemented\n", __FUNCTION__);
5970 UNDEF_LSRBPC;
5971 /* WRITESDEST (dest); */
5972 return 1;
5973 } 6237 }
5974 break; 6238 break;
6239 case 0x68:
6240 {
6241 u32 rd = (instr >> 12) & 0xF;
6242 u32 rn = (instr >> 16) & 0xF;
6243 u32 rm = (instr >> 0) & 0xF;
6244 u32 from = state->Reg[rn];
6245 u32 to = state->Reg[rm];
6246 u32 cpsr = ARMul_GetCPSR(state);
6247 if ((instr & 0xFF0) == 0xFB0) { // SEL
6248 u32 result;
6249 if (cpsr & (1 << 16))
6250 result = from & 0xff;
6251 else
6252 result = to & 0xff;
6253 if (cpsr & (1 << 17))
6254 result |= from & 0x0000ff00;
6255 else
6256 result |= to & 0x0000ff00;
6257 if (cpsr & (1 << 18))
6258 result |= from & 0x00ff0000;
6259 else
6260 result |= to & 0x00ff0000;
6261 if (cpsr & (1 << 19))
6262 result |= from & 0xff000000;
6263 else
6264 result |= to & 0xff000000;
6265 state->Reg[rd] = result;
6266 return 1;
6267 }
5975 } 6268 }
6269 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
6270 break;
6271
6272 case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
6273 {
6274 const u8 op2 = BITS(5, 7);
6275
6276 // SSAT16
6277 if (op2 == 0x01) {
6278 const u8 rd_idx = BITS(12, 15);
6279 const u8 rn_idx = BITS(0, 3);
6280 const u8 num_bits = BITS(16, 19) + 1;
6281 const s16 min = -(0x8000 >> (16 - num_bits));
6282 const s16 max = (0x7FFF >> (16 - num_bits));
6283 s16 rn_lo = (state->Reg[rn_idx]);
6284 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6285
6286 if (rn_lo > max) {
6287 rn_lo = max;
6288 SETQ;
6289 } else if (rn_lo < min) {
6290 rn_lo = min;
6291 SETQ;
6292 }
6293
6294 if (rn_hi > max) {
6295 rn_hi = max;
6296 SETQ;
6297 } else if (rn_hi < min) {
6298 rn_hi = min;
6299 SETQ;
6300 }
6301
6302 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6303 return 1;
6304 }
6305 else if (op2 == 0x03) {
6306 const u8 rotation = BITS(10, 11) * 8;
6307 u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
6308 if (rm & 0x80)
6309 rm |= 0xffffff00;
6310
6311 // SXTB, otherwise SXTAB
6312 if (BITS(16, 19) == 0xf)
6313 state->Reg[BITS(12, 15)] = rm;
6314 else
6315 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6316
6317 return 1;
6318 }
6319 else {
6320 printf("Unimplemented op: SSAT");
6321 }
6322 }
6323 break;
6324
6325 case 0x6b: // REV, REV16, SXTH, and SXTAH
6326 {
6327 const u8 op2 = BITS(5, 7);
6328
6329 // REV
6330 if (op2 == 0x01) {
6331 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6332 return 1;
6333 }
6334 // REV16
6335 else if (op2 == 0x05) {
6336 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6337 return 1;
6338 }
6339 else if (op2 == 0x03) {
6340 const u8 rotate = BITS(10, 11) * 8;
6341
6342 u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6343 if (rm & 0x8000)
6344 rm |= 0xffff0000;
6345
6346 // SXTH, otherwise SXTAH
6347 if (BITS(16, 19) == 15)
6348 state->Reg[BITS(12, 15)] = rm;
6349 else
6350 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6351
6352 return 1;
6353 }
6354 }
6355 break;
6356
6357 case 0x6c: // UXTB16 and UXTAB16
6358 {
6359 const u8 rm_idx = BITS(0, 3);
6360 const u8 rn_idx = BITS(16, 19);
6361 const u8 rd_idx = BITS(12, 15);
6362 const u32 rm_val = state->Reg[rm_idx];
6363 const u32 rn_val = state->Reg[rn_idx];
6364 const u32 rotation = BITS(10, 11) * 8;
6365 const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
6366
6367 // UXTB16
6368 if ((instr & 0xf03f0) == 0xf0070) {
6369 state->Reg[rd_idx] = rotated_rm & 0x00FF00FF;
6370 }
6371 else { // UXTAB16
6372 const u8 lo_rotated = (rotated_rm & 0xFF);
6373 const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
6374
6375 const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
6376 const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
6377
6378 state->Reg[rd_idx] = ((hi_result << 16) | (lo_result & 0xFFFF));
6379 }
6380
6381 return 1;
6382 }
6383 break;
6384 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
6385 {
6386 const u8 op2 = BITS(5, 7);
6387
6388 // USAT16
6389 if (op2 == 0x01) {
6390 const u8 rd_idx = BITS(12, 15);
6391 const u8 rn_idx = BITS(0, 3);
6392 const u8 num_bits = BITS(16, 19);
6393 const s16 max = 0xFFFF >> (16 - num_bits);
6394 s16 rn_lo = (state->Reg[rn_idx]);
6395 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6396
6397 if (max < rn_lo) {
6398 rn_lo = max;
6399 SETQ;
6400 } else if (rn_lo < 0) {
6401 rn_lo = 0;
6402 SETQ;
6403 }
6404
6405 if (max < rn_hi) {
6406 rn_hi = max;
6407 SETQ;
6408 } else if (rn_hi < 0) {
6409 rn_hi = 0;
6410 SETQ;
6411 }
6412
6413 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6414 return 1;
6415 }
6416 else if (op2 == 0x03) {
6417 const u8 rotate = BITS(10, 11) * 8;
6418 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
6419
6420 if (BITS(16, 19) == 0xf)
6421 /* UXTB */
6422 state->Reg[BITS(12, 15)] = rm;
6423 else
6424 /* UXTAB */
6425 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6426
6427 return 1;
6428 }
6429 else {
6430 printf("Unimplemented op: USAT");
6431 }
6432 }
6433 break;
6434
6435 case 0x6f: // UXTH, UXTAH, and REVSH.
6436 {
6437 const u8 op2 = BITS(5, 7);
6438
6439 // REVSH
6440 if (op2 == 0x05) {
6441 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6442 if (DEST & 0x8000)
6443 DEST |= 0xffff0000;
6444 return 1;
6445 }
6446 // UXTH and UXTAH
6447 else if (op2 == 0x03) {
6448 const u8 rotate = BITS(10, 11) * 8;
6449 const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6450
6451 // UXTH
6452 if (BITS(16, 19) == 0xf) {
6453 state->Reg[BITS(12, 15)] = rm;
6454 }
6455 // UXTAH
6456 else {
6457 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6458 }
6459
6460 return 1;
6461 }
6462 }
6463 case 0x70:
6464 // ichfly
6465 // SMUAD, SMUSD, SMLAD, and SMLSD
6466 if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 ||
6467 (instr & 0xd0) == 0x10 || (instr & 0xd0) == 0x50)
6468 {
6469 const u8 rd_idx = BITS(16, 19);
6470 const u8 rn_idx = BITS(0, 3);
6471 const u8 rm_idx = BITS(8, 11);
6472 const u8 ra_idx = BITS(12, 15);
6473 const bool do_swap = (BIT(5) == 1);
5976 6474
5977 case 0x1d: { /* BICS reg */ 6475 u32 rm_val = state->Reg[rm_idx];
5978 if ((BITS (4, 7)) == 0x9) { 6476 const u32 rn_val = state->Reg[rn_idx];
5979 /* ldrexb */
5980 temp = LHS;
5981 LoadByte (state, instr, temp, LUNSIGNED);
5982 6477
5983 state->currentexaddr = temp; 6478 if (do_swap)
5984 state->currentexval = (u32)ARMul_ReadByte(state, temp); 6479 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
5985 6480
5986 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); 6481 const s16 rm_lo = (rm_val & 0xFFFF);
5987 //printf("ldrexb\n"); 6482 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
5988 //printf("instr is %x rm is %d\n", instr, BITS(16, 19)); 6483 const s16 rn_lo = (rn_val & 0xFFFF);
5989 //exit(-1); 6484 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
5990 6485
5991 //printf("In %s, ldrexb not implemented\n", __FUNCTION__); 6486 const u32 product1 = (rn_lo * rm_lo);
5992 return 1; 6487 const u32 product2 = (rn_hi * rm_hi);
5993 }
5994 break;
5995 }
5996 /* add end */
5997 6488
5998 case 0x6a: { 6489 // SMUAD and SMLAD
5999 ARMword Rm; 6490 if (BIT(6) == 0) {
6000 int ror = -1; 6491 state->Reg[rd_idx] = product1 + product2;
6001 6492
6002 switch (BITS (4, 11)) { 6493 if (BITS(12, 15) != 15) {
6003 case 0x07: 6494 state->Reg[rd_idx] += state->Reg[ra_idx];
6004 ror = 0; 6495 ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]);
6005 break; 6496 }
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 6497
6016 case 0x01: 6498 ARMul_AddOverflowQ(state, product1, product2);
6017 case 0xf3: 6499 }
6018 //ichfly 6500 // SMUSD and SMLSD
6019 //SSAT16 6501 else {
6020 { 6502 state->Reg[rd_idx] = product1 - product2;
6021 u8 tar = BITS(12,15); 6503
6022 u8 src = BITS(0, 3); 6504 if (BITS(12, 15) != 15)
6023 u8 val = BITS(16, 19) + 1; 6505 state->Reg[rd_idx] += state->Reg[ra_idx];
6024 s16 a1 = (state->Reg[src]); 6506 }
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 6507
6036 return 1; 6508 return 1;
6037 default:
6038 break;
6039 } 6509 }
6040 6510 break;
6041 if (ror == -1) { 6511 case 0x74: // SMLALD and SMLSLD
6042 if (BITS (4, 6) == 0x7) { 6512 {
6043 printf ("Unhandled v6 insn: ssat\n"); 6513 const u8 rm_idx = BITS(8, 11);
6044 return 0; 6514 const u8 rn_idx = BITS(0, 3);
6515 const u8 rdlo_idx = BITS(12, 15);
6516 const u8 rdhi_idx = BITS(16, 19);
6517 const bool do_swap = (BIT(5) == 1);
6518
6519 const u32 rdlo_val = state->Reg[rdlo_idx];
6520 const u32 rdhi_val = state->Reg[rdhi_idx];
6521 const u32 rn_val = state->Reg[rn_idx];
6522 u32 rm_val = state->Reg[rm_idx];
6523
6524 if (do_swap)
6525 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
6526
6527 const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
6528 const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
6529 s64 result;
6530
6531 // SMLALD
6532 if (BIT(6) == 0) {
6533 result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
6534 }
6535 // SMLSLD
6536 else {
6537 result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
6045 } 6538 }
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 6539
6080 case 0xf3: 6540 state->Reg[rdlo_idx] = (result & 0xFFFFFFFF);
6081 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); 6541 state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF);
6082 return 1; 6542 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 } 6543 }
6544 break;
6545 case 0x75: // SMMLA, SMMUL, and SMMLS
6546 {
6547 const u8 rm_idx = BITS(8, 11);
6548 const u8 rn_idx = BITS(0, 3);
6549 const u8 ra_idx = BITS(12, 15);
6550 const u8 rd_idx = BITS(16, 19);
6551 const bool do_round = (BIT(5) == 1);
6089 6552
6090 if (ror == -1) 6553 const u32 rm_val = state->Reg[rm_idx];
6091 break; 6554 const u32 rn_val = state->Reg[rn_idx];
6092 6555
6093 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF); 6556 // Assume SMMUL by default.
6094 if (Rm & 0x8000) 6557 s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
6095 Rm |= 0xffff0000;
6096 6558
6097 if (BITS (16, 19) == 0xf) 6559 if (ra_idx != 15) {
6098 /* SXTH */ 6560 const u32 ra_val = state->Reg[ra_idx];
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 6561
6106 case 0x6e: { 6562 // SMMLA, otherwise SMMLS
6107 ARMword Rm; 6563 if (BIT(6) == 0)
6108 int ror = -1; 6564 result += ((s64)ra_val << 32);
6565 else
6566 result = ((s64)ra_val << 32) - result;
6567 }
6109 6568
6110 switch (BITS (4, 11)) { 6569 if (do_round)
6111 case 0x07: 6570 result += 0x80000000;
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 6571
6124 case 0x01: 6572 state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
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; 6573 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 } 6574 }
6575 break;
6576 case 0x78:
6577 if (BITS(20, 24) == 0x18)
6578 {
6579 const u8 rm_idx = BITS(8, 11);
6580 const u8 rn_idx = BITS(0, 3);
6581 const u8 rd_idx = BITS(16, 19);
6152 6582
6153 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF); 6583 const u32 rm_val = state->Reg[rm_idx];
6154 6584 const u32 rn_val = state->Reg[rn_idx];
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 6585
6164 case 0x6f: { 6586 const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
6165 ARMword Rm; 6587 const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
6166 int ror = -1; 6588 const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
6589 const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
6167 6590
6168 switch (BITS (4, 11)) { 6591 u32 finalDif = (diff1 + diff2 + diff3 + diff4);
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 6592
6182 case 0xfb: 6593 // Op is USADA8 if true.
6183 printf ("Unhandled v6 insn: revsh\n"); 6594 const u8 ra_idx = BITS(12, 15);
6184 return 0; 6595 if (ra_idx != 15)
6185 default: 6596 finalDif += state->Reg[ra_idx];
6186 break;
6187 }
6188 6597
6189 if (ror == -1) 6598 state->Reg[rd_idx] = finalDif;
6190 break; 6599 return 1;
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 } 6600 }
6209 } 6601 break;
6210 return 1; 6602 case 0x7a:
6211 6603 printf ("Unhandled v6 insn: usbfx\n");
6212#if 0 6604 break;
6605 case 0x7c:
6606 printf ("Unhandled v6 insn: bfc/bfi\n");
6607 break;
6213 case 0x84: 6608 case 0x84:
6214 printf ("Unhandled v6 insn: srs\n"); 6609 printf ("Unhandled v6 insn: srs\n");
6215 break; 6610 break;
6216#endif
6217 default: 6611 default:
6218 break; 6612 break;
6219 } 6613 }
6220 printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27)); 6614 printf("Unhandled v6 insn: UNKNOWN: %08x %08X\n", instr, BITS(20, 27));
6221 return 0; 6615 return 0;
6222 } 6616 } \ No newline at end of file