Merge pull request #273 from bunnei/more-skyeye-fixes
ARM: Pull some SkyEye fixes from 3dmoo.
This commit is contained in:
commit
2cac148ff3
3 changed files with 485 additions and 419 deletions
|
@ -1166,7 +1166,7 @@ mainswitch:
|
||||||
else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
|
else if ((((int)BITS(21, 27)) == 0x3e) && ((int)BITS(4, 6) == 0x1)) {
|
||||||
//(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
|
//(ARMword)(instr<<(31-(n))) >> ((31-(n))+(m))
|
||||||
unsigned msb ,tmp_rn, tmp_rd, dst;
|
unsigned msb ,tmp_rn, tmp_rd, dst;
|
||||||
msb = tmp_rd = tmp_rn = dst = 0;
|
tmp_rd = tmp_rn = dst = 0;
|
||||||
Rd = BITS(12, 15);
|
Rd = BITS(12, 15);
|
||||||
Rn = BITS(0, 3);
|
Rn = BITS(0, 3);
|
||||||
lsb = BITS(7, 11);
|
lsb = BITS(7, 11);
|
||||||
|
@ -1737,7 +1737,7 @@ mainswitch:
|
||||||
//chy 2006-02-15 if in user mode, can not set cpsr 0:23
|
//chy 2006-02-15 if in user mode, can not set cpsr 0:23
|
||||||
//from p165 of ARMARM book
|
//from p165 of ARMARM book
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
rhs = DPRegRHS;
|
rhs = DPRegRHS;
|
||||||
temp = LHS & rhs;
|
temp = LHS & rhs;
|
||||||
|
@ -1877,7 +1877,7 @@ mainswitch:
|
||||||
/* TEQP reg */
|
/* TEQP reg */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
rhs = DPRegRHS;
|
rhs = DPRegRHS;
|
||||||
temp = LHS ^ rhs;
|
temp = LHS ^ rhs;
|
||||||
|
@ -1993,7 +1993,7 @@ mainswitch:
|
||||||
/* CMPP reg. */
|
/* CMPP reg. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
rhs = DPRegRHS;
|
rhs = DPRegRHS;
|
||||||
temp = LHS - rhs;
|
temp = LHS - rhs;
|
||||||
|
@ -2112,7 +2112,7 @@ mainswitch:
|
||||||
if (DESTReg == 15) {
|
if (DESTReg == 15) {
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
rhs = DPRegRHS;
|
rhs = DPRegRHS;
|
||||||
temp = LHS + rhs;
|
temp = LHS + rhs;
|
||||||
|
@ -2200,17 +2200,57 @@ mainswitch:
|
||||||
Handle_Store_Double (state, instr);
|
Handle_Store_Double (state, instr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (BITS(4, 11) == 0xF9) { //strexd
|
||||||
|
u32 l = LHSReg;
|
||||||
|
|
||||||
|
bool enter = false;
|
||||||
|
|
||||||
|
if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr)&&
|
||||||
|
state->currentexvald == (u32)ARMul_ReadWord(state, state->currentexaddr + 4))
|
||||||
|
enter = true;
|
||||||
|
|
||||||
|
|
||||||
|
//todo bug this and STREXD and LDREXD http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360e/CHDGJGGC.html
|
||||||
|
|
||||||
|
|
||||||
|
if (enter) {
|
||||||
|
ARMul_StoreWordN(state, LHS, state->Reg[RHSReg]);
|
||||||
|
ARMul_StoreWordN(state,LHS + 4 , state->Reg[RHSReg + 1]);
|
||||||
|
state->Reg[DESTReg] = 0;
|
||||||
|
} else {
|
||||||
|
state->Reg[DESTReg] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
dest = DPRegRHS;
|
dest = DPRegRHS;
|
||||||
WRITEDEST (dest);
|
WRITEDEST (dest);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1b: /* MOVS reg */
|
case 0x1B: /* MOVS reg */
|
||||||
#ifdef MODET
|
#ifdef MODET
|
||||||
|
/* ldrexd ichfly */
|
||||||
|
if (BITS(0, 11) == 0xF9F) { //strexd
|
||||||
|
lhs = LHS;
|
||||||
|
|
||||||
|
state->currentexaddr = lhs;
|
||||||
|
state->currentexval = (u32)ARMul_ReadWord(state, lhs);
|
||||||
|
state->currentexvald = (u32)ARMul_ReadWord(state, lhs + 4);
|
||||||
|
|
||||||
|
state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs);
|
||||||
|
state->Reg[DESTReg] = ARMul_LoadWordN(state, lhs + 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((BITS (4, 11) & 0xF9) == 0x9)
|
if ((BITS (4, 11) & 0xF9) == 0x9)
|
||||||
/* LDR register offset, write-back, up, pre indexed. */
|
/* LDR register offset, write-back, up, pre indexed. */
|
||||||
LHPREUPWB ();
|
LHPREUPWB ();
|
||||||
/* Continue with remaining instruction decoding. */
|
/* Continue with remaining instruction decoding. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
dest = DPSRegRHS;
|
dest = DPSRegRHS;
|
||||||
WRITESDEST (dest);
|
WRITESDEST (dest);
|
||||||
|
@ -2297,12 +2337,12 @@ mainswitch:
|
||||||
if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
|
if (state->currentexval == (u32)ARMul_LoadHalfWord(state, state->currentexaddr))enter = true;
|
||||||
|
|
||||||
|
|
||||||
ARMul_StoreHalfWord(state, lhs, RHS);
|
|
||||||
//StoreWord(state, lhs, RHS)
|
//StoreWord(state, lhs, RHS)
|
||||||
if (state->Aborted) {
|
if (state->Aborted) {
|
||||||
TAKEABORT;
|
TAKEABORT;
|
||||||
}
|
}
|
||||||
if (enter) {
|
if (enter) {
|
||||||
|
ARMul_StoreHalfWord(state, lhs, RHS);
|
||||||
state->Reg[DESTReg] = 0;
|
state->Reg[DESTReg] = 0;
|
||||||
} else {
|
} else {
|
||||||
state->Reg[DESTReg] = 1;
|
state->Reg[DESTReg] = 1;
|
||||||
|
@ -2520,7 +2560,7 @@ mainswitch:
|
||||||
/* TSTP immed. */
|
/* TSTP immed. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
temp = LHS & DPImmRHS;
|
temp = LHS & DPImmRHS;
|
||||||
SETR15PSR (temp);
|
SETR15PSR (temp);
|
||||||
|
@ -2547,7 +2587,7 @@ mainswitch:
|
||||||
/* TEQP immed. */
|
/* TEQP immed. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
temp = LHS ^ DPImmRHS;
|
temp = LHS ^ DPImmRHS;
|
||||||
SETR15PSR (temp);
|
SETR15PSR (temp);
|
||||||
|
@ -2568,7 +2608,7 @@ mainswitch:
|
||||||
/* CMPP immed. */
|
/* CMPP immed. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
temp = LHS - DPImmRHS;
|
temp = LHS - DPImmRHS;
|
||||||
SETR15PSR (temp);
|
SETR15PSR (temp);
|
||||||
|
@ -2604,7 +2644,7 @@ mainswitch:
|
||||||
/* CMNP immed. */
|
/* CMNP immed. */
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
#else
|
#else
|
||||||
temp = LHS + DPImmRHS;
|
temp = LHS + DPImmRHS;
|
||||||
SETR15PSR (temp);
|
SETR15PSR (temp);
|
||||||
|
@ -3055,17 +3095,14 @@ mainswitch:
|
||||||
|
|
||||||
case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
|
case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
|
||||||
//ichfly PKHBT PKHTB todo check this
|
//ichfly PKHBT PKHTB todo check this
|
||||||
if ((instr & 0x70) == 0x10) //pkhbt
|
if ((instr & 0x70) == 0x10) { //pkhbt
|
||||||
{
|
|
||||||
u8 idest = BITS(12, 15);
|
u8 idest = BITS(12, 15);
|
||||||
u8 rfis = BITS(16, 19);
|
u8 rfis = BITS(16, 19);
|
||||||
u8 rlast = BITS(0, 3);
|
u8 rlast = BITS(0, 3);
|
||||||
u8 ishi = BITS(7,11);
|
u8 ishi = BITS(7,11);
|
||||||
state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
|
state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
|
||||||
break;
|
break;
|
||||||
}
|
} else if ((instr & 0x70) == 0x50) { //pkhtb
|
||||||
else if ((instr & 0x70) == 0x50)//pkhtb
|
|
||||||
{
|
|
||||||
u8 idest = BITS(12, 15);
|
u8 idest = BITS(12, 15);
|
||||||
u8 rfis = BITS(16, 19);
|
u8 rfis = BITS(16, 19);
|
||||||
u8 rlast = BITS(0, 3);
|
u8 rlast = BITS(0, 3);
|
||||||
|
@ -3073,8 +3110,7 @@ mainswitch:
|
||||||
if (ishi == 0)ishi = 0x20;
|
if (ishi == 0)ishi = 0x20;
|
||||||
state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000);
|
state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000);
|
||||||
break;
|
break;
|
||||||
}
|
} else if (BIT (4)) {
|
||||||
else if (BIT (4)) {
|
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
if (state->is_v6
|
if (state->is_v6
|
||||||
&& handle_v6_insn (state, instr))
|
&& handle_v6_insn (state, instr))
|
||||||
|
@ -3686,13 +3722,11 @@ mainswitch:
|
||||||
|
|
||||||
/* Co-Processor Data Transfers. */
|
/* Co-Processor Data Transfers. */
|
||||||
case 0xc4:
|
case 0xc4:
|
||||||
if ((instr & 0x0FF00FF0) == 0xC400B10) //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
|
if ((instr & 0x0FF00FF0) == 0xC400B10) { //vmov BIT(0-3), BIT(12-15), BIT(16-20), vmov d0, r0, r0
|
||||||
{
|
|
||||||
state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
|
state->ExtReg[BITS(0, 3) << 1] = state->Reg[BITS(12, 15)];
|
||||||
state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
|
state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)];
|
||||||
break;
|
break;
|
||||||
}
|
} else if (state->is_v5) {
|
||||||
else if (state->is_v5) {
|
|
||||||
/* Reading from R15 is UNPREDICTABLE. */
|
/* Reading from R15 is UNPREDICTABLE. */
|
||||||
if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
|
if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
|
||||||
ARMul_UndefInstr (state, instr);
|
ARMul_UndefInstr (state, instr);
|
||||||
|
@ -3712,22 +3746,18 @@ mainswitch:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc5:
|
case 0xc5:
|
||||||
if ((instr & 0x00000FF0) == 0xB10) //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
|
if ((instr & 0x00000FF0) == 0xB10) { //vmov BIT(12-15), BIT(16-20), BIT(0-3) vmov r0, r0, d0
|
||||||
{
|
|
||||||
state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
|
state->Reg[BITS(12, 15)] = state->ExtReg[BITS(0, 3) << 1];
|
||||||
state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
|
state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1];
|
||||||
break;
|
break;
|
||||||
}
|
} else if (state->is_v5) {
|
||||||
else if (state->is_v5) {
|
|
||||||
/* Writes to R15 are UNPREDICATABLE. */
|
/* Writes to R15 are UNPREDICATABLE. */
|
||||||
if (DESTReg == 15 || LHSReg == 15)
|
if (DESTReg == 15 || LHSReg == 15)
|
||||||
ARMul_UndefInstr (state, instr);
|
ARMul_UndefInstr (state, instr);
|
||||||
/* Is access to the coprocessor allowed ? */
|
/* Is access to the coprocessor allowed ? */
|
||||||
else if (!CP_ACCESS_ALLOWED(state, CPNum))
|
else if (!CP_ACCESS_ALLOWED(state, CPNum)) {
|
||||||
{
|
|
||||||
ARMul_UndefInstr(state, instr);
|
ARMul_UndefInstr(state, instr);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* MRRC, ARMv5TE and up */
|
/* MRRC, ARMv5TE and up */
|
||||||
ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
|
ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg]));
|
||||||
break;
|
break;
|
||||||
|
@ -4565,7 +4595,7 @@ out:
|
||||||
#ifdef MODE32
|
#ifdef MODE32
|
||||||
if (state->Bank > 0) {
|
if (state->Bank > 0) {
|
||||||
state->Cpsr = state->Spsr[state->Bank];
|
state->Cpsr = state->Spsr[state->Bank];
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
}
|
}
|
||||||
#ifdef MODET
|
#ifdef MODET
|
||||||
if (TFLAG)
|
if (TFLAG)
|
||||||
|
@ -5256,7 +5286,7 @@ L_ldm_s_makeabort:
|
||||||
//chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
|
//chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
|
||||||
if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
|
if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
|
||||||
state->Cpsr = GETSPSR (state->Bank);
|
state->Cpsr = GETSPSR (state->Bank);
|
||||||
//ARMul_CPSRAltered (state);
|
ARMul_CPSRAltered (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteR15 (state, PC);
|
WriteR15 (state, PC);
|
||||||
|
@ -5641,30 +5671,9 @@ L_stm_s_takeabort:
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handle_v6_insn (ARMul_State * state, ARMword instr) {
|
handle_v6_insn (ARMul_State * state, ARMword instr) {
|
||||||
switch (BITS (20, 27)) {
|
ARMword lhs, temp;
|
||||||
//ichfly
|
|
||||||
case 0x66: //UQSUB8
|
|
||||||
if ((instr & 0x0FF00FF0) == 0x06600FF0) {
|
|
||||||
u32 rd = (instr >> 12) & 0xF;
|
|
||||||
u32 rm = (instr >> 16) & 0xF;
|
|
||||||
u32 rn = (instr >> 0) & 0xF;
|
|
||||||
u32 subfrom = state->Reg[rm];
|
|
||||||
u32 tosub = state->Reg[rn];
|
|
||||||
|
|
||||||
u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub));
|
switch (BITS (20, 27)) {
|
||||||
if (b1 > (u8)(subfrom)) b1 = 0;
|
|
||||||
u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8));
|
|
||||||
if (b2 > (u8)(subfrom >> 8)) b2 = 0;
|
|
||||||
u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16));
|
|
||||||
if (b3 > (u8)(subfrom >> 16)) b3 = 0;
|
|
||||||
u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24));
|
|
||||||
if (b4 > (u8)(subfrom >> 24)) b4 = 0;
|
|
||||||
state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24);
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
printf("UQSUB8 decoding fail %08X",instr);
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
case 0x03:
|
case 0x03:
|
||||||
printf ("Unhandled v6 insn: ldr\n");
|
printf ("Unhandled v6 insn: ldr\n");
|
||||||
break;
|
break;
|
||||||
|
@ -5678,9 +5687,43 @@ L_stm_s_takeabort:
|
||||||
printf ("Unhandled v6 insn: smi\n");
|
printf ("Unhandled v6 insn: smi\n");
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case 0x18:
|
||||||
|
if (BITS(4, 7) == 0x9) {
|
||||||
|
/* strex */
|
||||||
|
u32 l = LHSReg;
|
||||||
|
u32 r = RHSReg;
|
||||||
|
lhs = LHS;
|
||||||
|
|
||||||
|
bool enter = false;
|
||||||
|
|
||||||
|
if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
|
||||||
|
//StoreWord(state, lhs, RHS)
|
||||||
|
if (state->Aborted) {
|
||||||
|
TAKEABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enter) {
|
||||||
|
ARMul_StoreWordS(state, lhs, RHS);
|
||||||
|
state->Reg[DESTReg] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state->Reg[DESTReg] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
printf ("Unhandled v6 insn: strex\n");
|
printf ("Unhandled v6 insn: strex\n");
|
||||||
break;
|
break;
|
||||||
case 0x19:
|
case 0x19:
|
||||||
|
/* ldrex */
|
||||||
|
if (BITS(4, 7) == 0x9) {
|
||||||
|
lhs = LHS;
|
||||||
|
|
||||||
|
state->currentexaddr = lhs;
|
||||||
|
state->currentexval = ARMul_ReadWord(state, lhs);
|
||||||
|
|
||||||
|
LoadWord(state, instr, lhs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
printf ("Unhandled v6 insn: ldrex\n");
|
printf ("Unhandled v6 insn: ldrex\n");
|
||||||
break;
|
break;
|
||||||
case 0x1a:
|
case 0x1a:
|
||||||
|
@ -5690,9 +5733,52 @@ L_stm_s_takeabort:
|
||||||
printf ("Unhandled v6 insn: ldrexd\n");
|
printf ("Unhandled v6 insn: ldrexd\n");
|
||||||
break;
|
break;
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
|
if (BITS(4, 7) == 0x9) {
|
||||||
|
/* strexb */
|
||||||
|
lhs = LHS;
|
||||||
|
|
||||||
|
bool enter = false;
|
||||||
|
|
||||||
|
if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
|
||||||
|
|
||||||
|
BUSUSEDINCPCN;
|
||||||
|
if (state->Aborted) {
|
||||||
|
TAKEABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (enter) {
|
||||||
|
ARMul_StoreByte(state, lhs, RHS);
|
||||||
|
state->Reg[DESTReg] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state->Reg[DESTReg] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("In %s, strexb not implemented\n", __FUNCTION__);
|
||||||
|
UNDEF_LSRBPC;
|
||||||
|
/* WRITESDEST (dest); */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
printf ("Unhandled v6 insn: strexb\n");
|
printf ("Unhandled v6 insn: strexb\n");
|
||||||
break;
|
break;
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
|
if ((BITS(4, 7)) == 0x9) {
|
||||||
|
/* ldrexb */
|
||||||
|
temp = LHS;
|
||||||
|
LoadByte(state, instr, temp, LUNSIGNED);
|
||||||
|
|
||||||
|
state->currentexaddr = temp;
|
||||||
|
state->currentexval = (u32)ARMul_ReadByte(state, temp);
|
||||||
|
|
||||||
|
//state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
|
||||||
|
//printf("ldrexb\n");
|
||||||
|
//printf("instr is %x rm is %d\n", instr, BITS(16, 19));
|
||||||
|
//exit(-1);
|
||||||
|
|
||||||
|
//printf("In %s, ldrexb not implemented\n", __FUNCTION__);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
printf ("Unhandled v6 insn: ldrexb\n");
|
printf ("Unhandled v6 insn: ldrexb\n");
|
||||||
break;
|
break;
|
||||||
case 0x1e:
|
case 0x1e:
|
||||||
|
@ -5713,10 +5799,8 @@ L_stm_s_takeabort:
|
||||||
case 0x3f:
|
case 0x3f:
|
||||||
printf ("Unhandled v6 insn: rbit\n");
|
printf ("Unhandled v6 insn: rbit\n");
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case 0x61:
|
case 0x61:
|
||||||
if ((instr & 0xFF0) == 0xf70)//ssub16
|
if ((instr & 0xFF0) == 0xf70) { //ssub16
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5724,11 +5808,9 @@ L_stm_s_takeabort:
|
||||||
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
||||||
s16 b1 = (state->Reg[src2] & 0xFFFF);
|
s16 b1 = (state->Reg[src2] & 0xFFFF);
|
||||||
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2)&0xFFFF)<< 0x10);
|
state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2) & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ((instr & 0xFF0) == 0xf10) { //sadd16
|
||||||
else if ((instr & 0xFF0) == 0xf10)//sadd16
|
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5736,11 +5818,9 @@ L_stm_s_takeabort:
|
||||||
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
||||||
s16 b1 = (state->Reg[src2] & 0xFFFF);
|
s16 b1 = (state->Reg[src2] & 0xFFFF);
|
||||||
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
state->Reg[tar] = ((a1 + a2) & 0xFFFF) | (((b1 + b2)&0xFFFF)<< 0x10);
|
state->Reg[tar] = ((a1 + a2) & 0xFFFF) | (((b1 + b2) & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ((instr & 0xFF0) == 0xf50) { //ssax
|
||||||
else if ((instr & 0xFF0) == 0xf50)//ssax
|
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5750,9 +5830,7 @@ L_stm_s_takeabort:
|
||||||
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10);
|
state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ((instr & 0xFF0) == 0xf30) { //sasx
|
||||||
else if ((instr & 0xFF0) == 0xf30)//sasx
|
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5762,12 +5840,10 @@ L_stm_s_takeabort:
|
||||||
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10);
|
state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n");
|
||||||
else printf ("Unhandled v6 insn: sadd/ssub\n");
|
|
||||||
break;
|
break;
|
||||||
case 0x62:
|
case 0x62:
|
||||||
if ((instr & 0xFF0) == 0xf70)//QSUB16
|
if ((instr & 0xFF0) == 0xf70) { //QSUB16
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5783,9 +5859,7 @@ L_stm_s_takeabort:
|
||||||
if (res2 < 0x7FFF) res2 = -0x8000;
|
if (res2 < 0x7FFF) res2 = -0x8000;
|
||||||
state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10);
|
state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ((instr & 0xFF0) == 0xf10) { //QADD16
|
||||||
else if ((instr & 0xFF0) == 0xf10)//QADD16
|
|
||||||
{
|
|
||||||
u8 tar = BITS(12, 15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src1 = BITS(16, 19);
|
u8 src1 = BITS(16, 19);
|
||||||
u8 src2 = BITS(0, 3);
|
u8 src2 = BITS(0, 3);
|
||||||
|
@ -5801,205 +5875,129 @@ L_stm_s_takeabort:
|
||||||
if (res2 < 0x7FFF) res2 = -0x8000;
|
if (res2 < 0x7FFF) res2 = -0x8000;
|
||||||
state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10);
|
state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else printf ("Unhandled v6 insn: qadd16/qsub16\n");
|
||||||
else printf ("Unhandled v6 insn: qadd/qsub\n");
|
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case 0x63:
|
case 0x63:
|
||||||
printf ("Unhandled v6 insn: shadd/shsub\n");
|
printf ("Unhandled v6 insn: shadd/shsub\n");
|
||||||
break;
|
break;
|
||||||
case 0x65:
|
case 0x65:
|
||||||
printf ("Unhandled v6 insn: uadd/usub\n");
|
{
|
||||||
|
u32 rd = (instr >> 12) & 0xF;
|
||||||
|
u32 rn = (instr >> 16) & 0xF;
|
||||||
|
u32 rm = (instr >> 0) & 0xF;
|
||||||
|
u32 from = state->Reg[rn];
|
||||||
|
u32 to = state->Reg[rm];
|
||||||
|
|
||||||
|
if ((instr & 0xFF0) == 0xF10 || (instr & 0xFF0) == 0xF70) { // UADD16/USUB16
|
||||||
|
u32 h1, h2;
|
||||||
|
state->Cpsr &= 0xfff0ffff;
|
||||||
|
if ((instr & 0x0F0) == 0x070) { // USUB16
|
||||||
|
h1 = ((u16)from - (u16)to);
|
||||||
|
h2 = ((u16)(from >> 16) - (u16)(to >> 16));
|
||||||
|
if (!(h1 & 0xffff0000)) state->Cpsr |= (3 << 16);
|
||||||
|
if (!(h2 & 0xffff0000)) state->Cpsr |= (3 << 18);
|
||||||
|
}
|
||||||
|
else { // UADD16
|
||||||
|
h1 = ((u16)from + (u16)to);
|
||||||
|
h2 = ((u16)(from >> 16) + (u16)(to >> 16));
|
||||||
|
if (h1 & 0xffff0000) state->Cpsr |= (3 << 16);
|
||||||
|
if (h2 & 0xffff0000) state->Cpsr |= (3 << 18);
|
||||||
|
}
|
||||||
|
state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if ((instr & 0xFF0) == 0xF90 || (instr & 0xFF0) == 0xFF0) { // UADD8/USUB8
|
||||||
|
u32 b1, b2, b3, b4;
|
||||||
|
state->Cpsr &= 0xfff0ffff;
|
||||||
|
if ((instr & 0x0F0) == 0x0F0) { // USUB8
|
||||||
|
b1 = ((u8)from - (u8)to);
|
||||||
|
b2 = ((u8)(from >> 8) - (u8)(to >> 8));
|
||||||
|
b3 = ((u8)(from >> 16) - (u8)(to >> 16));
|
||||||
|
b4 = ((u8)(from >> 24) - (u8)(to >> 24));
|
||||||
|
if (!(b1 & 0xffffff00)) state->Cpsr |= (1 << 16);
|
||||||
|
if (!(b2 & 0xffffff00)) state->Cpsr |= (1 << 17);
|
||||||
|
if (!(b3 & 0xffffff00)) state->Cpsr |= (1 << 18);
|
||||||
|
if (!(b4 & 0xffffff00)) state->Cpsr |= (1 << 19);
|
||||||
|
}
|
||||||
|
else { // UADD8
|
||||||
|
b1 = ((u8)from + (u8)to);
|
||||||
|
b2 = ((u8)(from >> 8) + (u8)(to >> 8));
|
||||||
|
b3 = ((u8)(from >> 16) + (u8)(to >> 16));
|
||||||
|
b4 = ((u8)(from >> 24) + (u8)(to >> 24));
|
||||||
|
if (b1 & 0xffffff00) state->Cpsr |= (1 << 16);
|
||||||
|
if (b2 & 0xffffff00) state->Cpsr |= (1 << 17);
|
||||||
|
if (b3 & 0xffffff00) state->Cpsr |= (1 << 18);
|
||||||
|
if (b4 & 0xffffff00) state->Cpsr |= (1 << 19);
|
||||||
|
}
|
||||||
|
state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Unhandled v6 insn: uasx/usax\n");
|
||||||
break;
|
break;
|
||||||
case 0x66:
|
case 0x66:
|
||||||
printf ("Unhandled v6 insn: uqadd/uqsub\n");
|
if ((instr & 0x0FF00FF0) == 0x06600FF0) { //uqsub8
|
||||||
|
u32 rd = (instr >> 12) & 0xF;
|
||||||
|
u32 rm = (instr >> 16) & 0xF;
|
||||||
|
u32 rn = (instr >> 0) & 0xF;
|
||||||
|
u32 subfrom = state->Reg[rm];
|
||||||
|
u32 tosub = state->Reg[rn];
|
||||||
|
|
||||||
|
u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub));
|
||||||
|
if (b1 > (u8)(subfrom)) b1 = 0;
|
||||||
|
u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8));
|
||||||
|
if (b2 > (u8)(subfrom >> 8)) b2 = 0;
|
||||||
|
u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16));
|
||||||
|
if (b3 > (u8)(subfrom >> 16)) b3 = 0;
|
||||||
|
u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24));
|
||||||
|
if (b4 > (u8)(subfrom >> 24)) b4 = 0;
|
||||||
|
state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
printf ("Unhandled v6 insn: uqsub16\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x67:
|
case 0x67:
|
||||||
printf ("Unhandled v6 insn: uhadd/uhsub\n");
|
printf ("Unhandled v6 insn: uhadd/uhsub\n");
|
||||||
break;
|
break;
|
||||||
case 0x68:
|
case 0x68:
|
||||||
printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 0x6c:
|
|
||||||
if ((instr & 0xf03f0) == 0xf0070) //uxtb16
|
|
||||||
{
|
{
|
||||||
u8 src1 = BITS(0, 3);
|
u32 rd = (instr >> 12) & 0xF;
|
||||||
u8 tar = BITS(12, 15);
|
u32 rn = (instr >> 16) & 0xF;
|
||||||
u32 base = state->Reg[src1];
|
u32 rm = (instr >> 0) & 0xF;
|
||||||
u32 shamt = BITS(9,10)* 8;
|
u32 from = state->Reg[rn];
|
||||||
u32 in = ((base << (32 - shamt)) | (base >> shamt));
|
u32 to = state->Reg[rm];
|
||||||
state->Reg[tar] = in & 0x00FF00FF;
|
u32 cpsr = state->Cpsr;
|
||||||
return 1;
|
if ((instr & 0xFF0) == 0xFB0) { // SEL
|
||||||
}
|
u32 result;
|
||||||
|
if (cpsr & (1 << 16))
|
||||||
|
result = from & 0xff;
|
||||||
else
|
else
|
||||||
printf ("Unhandled v6 insn: uxtb16/uxtab16\n");
|
result = to & 0xff;
|
||||||
break;
|
if (cpsr & (1 << 17))
|
||||||
case 0x70:
|
result |= from & 0x0000ff00;
|
||||||
if ((instr & 0xf0d0) == 0xf010)//smuad //ichfly
|
else
|
||||||
{
|
result |= to & 0x0000ff00;
|
||||||
u8 tar = BITS(16, 19);
|
if (cpsr & (1 << 18))
|
||||||
u8 src1 = BITS(0, 3);
|
result |= from & 0x00ff0000;
|
||||||
u8 src2 = BITS(8, 11);
|
else
|
||||||
u8 swap = BIT(5);
|
result |= to & 0x00ff0000;
|
||||||
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
if (cpsr & (1 << 19))
|
||||||
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
result |= from & 0xff000000;
|
||||||
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
else
|
||||||
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
result |= to & 0xff000000;
|
||||||
state->Reg[tar] = a1*a2 + b1*b2;
|
state->Reg[rd] = result;
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if ((instr & 0xf0d0) == 0xf050)//smusd
|
|
||||||
{
|
|
||||||
u8 tar = BITS(16, 19);
|
|
||||||
u8 src1 = BITS(0, 3);
|
|
||||||
u8 src2 = BITS(8, 11);
|
|
||||||
u8 swap = BIT(5);
|
|
||||||
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
|
||||||
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
|
||||||
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
|
||||||
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
|
||||||
state->Reg[tar] = a1*a2 - b1*b2;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if ((instr & 0xd0) == 0x10)//smlad
|
|
||||||
{
|
|
||||||
u8 tar = BITS(16, 19);
|
|
||||||
u8 src1 = BITS(0, 3);
|
|
||||||
u8 src2 = BITS(8, 11);
|
|
||||||
u8 src3 = BITS(12, 15);
|
|
||||||
u8 swap = BIT(5);
|
|
||||||
|
|
||||||
u32 a3 = state->Reg[src3];
|
|
||||||
|
|
||||||
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
|
||||||
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
|
||||||
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
|
||||||
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
|
||||||
state->Reg[tar] = a1*a2 + b1*b2 + a3;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n");
|
printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
|
||||||
break;
|
break;
|
||||||
case 0x74:
|
|
||||||
printf ("Unhandled v6 insn: smlald/smlsld\n");
|
|
||||||
break;
|
|
||||||
case 0x75:
|
|
||||||
printf ("Unhandled v6 insn: smmla/smmls/smmul\n");
|
|
||||||
break;
|
|
||||||
case 0x78:
|
|
||||||
printf ("Unhandled v6 insn: usad/usada8\n");
|
|
||||||
break;
|
|
||||||
#if 0
|
|
||||||
case 0x7a:
|
|
||||||
printf ("Unhandled v6 insn: usbfx\n");
|
|
||||||
break;
|
|
||||||
case 0x7c:
|
|
||||||
printf ("Unhandled v6 insn: bfc/bfi\n");
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* add new instr for arm v6. */
|
|
||||||
ARMword lhs, temp;
|
|
||||||
case 0x18: { /* ORR reg */
|
|
||||||
/* dyf add armv6 instr strex 2010.9.17 */
|
|
||||||
if (BITS (4, 7) == 0x9) {
|
|
||||||
u32 l = LHSReg;
|
|
||||||
u32 r = RHSReg;
|
|
||||||
lhs = LHS;
|
|
||||||
|
|
||||||
bool enter = false;
|
|
||||||
|
|
||||||
if (state->currentexval == (u32)ARMul_ReadWord(state, state->currentexaddr))enter = true;
|
|
||||||
ARMul_StoreWordS(state, lhs, RHS);
|
|
||||||
//StoreWord(state, lhs, RHS)
|
|
||||||
if (state->Aborted) {
|
|
||||||
TAKEABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enter) {
|
|
||||||
state->Reg[DESTReg] = 0;
|
|
||||||
} else {
|
|
||||||
state->Reg[DESTReg] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x19: { /* orrs reg */
|
|
||||||
/* dyf add armv6 instr ldrex */
|
|
||||||
if (BITS (4, 7) == 0x9) {
|
|
||||||
lhs = LHS;
|
|
||||||
|
|
||||||
state->currentexaddr = lhs;
|
|
||||||
state->currentexval = ARMul_ReadWord(state, lhs);
|
|
||||||
|
|
||||||
LoadWord (state, instr, lhs);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x1c: { /* BIC reg */
|
|
||||||
/* dyf add for STREXB */
|
|
||||||
if (BITS (4, 7) == 0x9) {
|
|
||||||
lhs = LHS;
|
|
||||||
|
|
||||||
bool enter = false;
|
|
||||||
|
|
||||||
if (state->currentexval == (u32)ARMul_ReadByte(state, state->currentexaddr))enter = true;
|
|
||||||
|
|
||||||
ARMul_StoreByte (state, lhs, RHS);
|
|
||||||
BUSUSEDINCPCN;
|
|
||||||
if (state->Aborted) {
|
|
||||||
TAKEABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (enter) {
|
|
||||||
state->Reg[DESTReg] = 0;
|
|
||||||
} else {
|
|
||||||
state->Reg[DESTReg] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("In %s, strexb not implemented\n", __FUNCTION__);
|
|
||||||
UNDEF_LSRBPC;
|
|
||||||
/* WRITESDEST (dest); */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x1d: { /* BICS reg */
|
|
||||||
if ((BITS (4, 7)) == 0x9) {
|
|
||||||
/* ldrexb */
|
|
||||||
temp = LHS;
|
|
||||||
LoadByte (state, instr, temp, LUNSIGNED);
|
|
||||||
|
|
||||||
state->currentexaddr = temp;
|
|
||||||
state->currentexval = (u32)ARMul_ReadByte(state, temp);
|
|
||||||
|
|
||||||
//state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
|
|
||||||
//printf("ldrexb\n");
|
|
||||||
//printf("instr is %x rm is %d\n", instr, BITS(16, 19));
|
|
||||||
//exit(-1);
|
|
||||||
|
|
||||||
//printf("In %s, ldrexb not implemented\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* add end */
|
|
||||||
|
|
||||||
case 0x6a: {
|
case 0x6a: {
|
||||||
ARMword Rm;
|
ARMword Rm;
|
||||||
int ror = -1;
|
int ror = -1;
|
||||||
|
|
||||||
switch (BITS (4, 11)) {
|
switch (BITS(4, 11)) {
|
||||||
case 0x07:
|
case 0x07:
|
||||||
ror = 0;
|
ror = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -6018,19 +6016,19 @@ L_stm_s_takeabort:
|
||||||
//ichfly
|
//ichfly
|
||||||
//SSAT16
|
//SSAT16
|
||||||
{
|
{
|
||||||
u8 tar = BITS(12,15);
|
u8 tar = BITS(12, 15);
|
||||||
u8 src = BITS(0, 3);
|
u8 src = BITS(0, 3);
|
||||||
u8 val = BITS(16, 19) + 1;
|
u8 val = BITS(16, 19) + 1;
|
||||||
s16 a1 = (state->Reg[src]);
|
s16 a1 = (state->Reg[src]);
|
||||||
s16 a2 = (state->Reg[src] >> 0x10);
|
s16 a2 = (state->Reg[src] >> 0x10);
|
||||||
s16 min = (s16)(0x8000) >> (16 - val);
|
s16 min = (s16)(0x8000 >> (16 - val));
|
||||||
s16 max = 0x7FFF >> (16 - val);
|
s16 max = 0x7FFF >> (16 - val);
|
||||||
if (min > a1) a1 = min;
|
if (min > a1) a1 = min;
|
||||||
if (max < a1) a1 = max;
|
if (max < a1) a1 = max;
|
||||||
if (min > a2) a2 = min;
|
if (min > a2) a2 = min;
|
||||||
if (max < a2) a2 = max;
|
if (max < a2) a2 = max;
|
||||||
u32 temp2 = ((u32)(a2)) << 0x10;
|
u32 temp2 = ((u32)(a2)) << 0x10;
|
||||||
state->Reg[tar] = (a1&0xFFFF) | (temp2);
|
state->Reg[tar] = (a1 & 0xFFFF) | (temp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -6039,31 +6037,31 @@ L_stm_s_takeabort:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ror == -1) {
|
if (ror == -1) {
|
||||||
if (BITS (4, 6) == 0x7) {
|
if (BITS(4, 6) == 0x7) {
|
||||||
printf ("Unhandled v6 insn: ssat\n");
|
printf("Unhandled v6 insn: ssat\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
|
Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF);
|
||||||
if (Rm & 0x80)
|
if (Rm & 0x80)
|
||||||
Rm |= 0xffffff00;
|
Rm |= 0xffffff00;
|
||||||
|
|
||||||
if (BITS (16, 19) == 0xf)
|
if (BITS(16, 19) == 0xf)
|
||||||
/* SXTB */
|
/* SXTB */
|
||||||
state->Reg[BITS (12, 15)] = Rm;
|
state->Reg[BITS(12, 15)] = Rm;
|
||||||
else
|
else
|
||||||
/* SXTAB */
|
/* SXTAB */
|
||||||
state->Reg[BITS (12, 15)] += Rm;
|
state->Reg[BITS(12, 15)] += Rm;
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case 0x6b: {
|
case 0x6b: {
|
||||||
ARMword Rm;
|
ARMword Rm;
|
||||||
int ror = -1;
|
int ror = -1;
|
||||||
|
|
||||||
switch (BITS (4, 11)) {
|
switch (BITS(4, 11)) {
|
||||||
case 0x07:
|
case 0x07:
|
||||||
ror = 0;
|
ror = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -6090,24 +6088,36 @@ L_stm_s_takeabort:
|
||||||
if (ror == -1)
|
if (ror == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
|
Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF);
|
||||||
if (Rm & 0x8000)
|
if (Rm & 0x8000)
|
||||||
Rm |= 0xffff0000;
|
Rm |= 0xffff0000;
|
||||||
|
|
||||||
if (BITS (16, 19) == 0xf)
|
if (BITS(16, 19) == 0xf)
|
||||||
/* SXTH */
|
/* SXTH */
|
||||||
state->Reg[BITS (12, 15)] = Rm;
|
state->Reg[BITS(12, 15)] = Rm;
|
||||||
else
|
else
|
||||||
/* SXTAH */
|
/* SXTAH */
|
||||||
state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
|
state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case 0x6c:
|
||||||
|
if ((instr & 0xf03f0) == 0xf0070) { //uxtb16
|
||||||
|
u8 src1 = BITS(0, 3);
|
||||||
|
u8 tar = BITS(12, 15);
|
||||||
|
u32 base = state->Reg[src1];
|
||||||
|
u32 shamt = BITS(9,10)* 8;
|
||||||
|
u32 in = ((base << (32 - shamt)) | (base >> shamt));
|
||||||
|
state->Reg[tar] = in & 0x00FF00FF;
|
||||||
|
return 1;
|
||||||
|
} else
|
||||||
|
printf ("Unhandled v6 insn: uxtab16\n");
|
||||||
|
break;
|
||||||
case 0x6e: {
|
case 0x6e: {
|
||||||
ARMword Rm;
|
ARMword Rm;
|
||||||
int ror = -1;
|
int ror = -1;
|
||||||
|
|
||||||
switch (BITS (4, 11)) {
|
switch (BITS(4, 11)) {
|
||||||
case 0x07:
|
case 0x07:
|
||||||
ror = 0;
|
ror = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -6143,29 +6153,30 @@ L_stm_s_takeabort:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ror == -1) {
|
if (ror == -1) {
|
||||||
if (BITS (4, 6) == 0x7) {
|
if (BITS(4, 6) == 0x7) {
|
||||||
printf ("Unhandled v6 insn: usat\n");
|
printf("Unhandled v6 insn: usat\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
|
Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF);
|
||||||
|
|
||||||
if (BITS (16, 19) == 0xf)
|
if (BITS(16, 19) == 0xf)
|
||||||
/* UXTB */
|
/* UXTB */
|
||||||
state->Reg[BITS (12, 15)] = Rm;
|
state->Reg[BITS(12, 15)] = Rm;
|
||||||
else
|
else
|
||||||
/* UXTAB */
|
/* UXTAB */
|
||||||
state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
|
state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x6f: {
|
case 0x6f: {
|
||||||
ARMword Rm;
|
ARMword Rm;
|
||||||
int ror = -1;
|
int ror = -1;
|
||||||
|
|
||||||
switch (BITS (4, 11)) {
|
switch (BITS(4, 11)) {
|
||||||
case 0x07:
|
case 0x07:
|
||||||
ror = 0;
|
ror = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -6180,7 +6191,7 @@ L_stm_s_takeabort:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
printf ("Unhandled v6 insn: revsh\n");
|
printf("Unhandled v6 insn: revsh\n");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -6189,31 +6200,86 @@ L_stm_s_takeabort:
|
||||||
if (ror == -1)
|
if (ror == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
|
Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF);
|
||||||
|
|
||||||
/* UXT */
|
/* UXT */
|
||||||
/* state->Reg[BITS (12, 15)] = Rm; */
|
/* state->Reg[BITS (12, 15)] = Rm; */
|
||||||
/* dyf add */
|
/* dyf add */
|
||||||
if (BITS (16, 19) == 0xf) {
|
if (BITS(16, 19) == 0xf) {
|
||||||
state->Reg[BITS (12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF;
|
state->Reg[BITS(12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
/* UXTAH */
|
/* UXTAH */
|
||||||
/* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
|
/* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
|
||||||
// printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
|
// printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
|
||||||
// , Rm, BITS(10, 11));
|
// , Rm, BITS(10, 11));
|
||||||
// printf("icounter is %lld\n", state->NumInstrs);
|
// printf("icounter is %lld\n", state->NumInstrs);
|
||||||
state->Reg[BITS (12, 15)] = (state->Reg[BITS (16, 19)] >> (8 * (BITS(10, 11)))) + Rm;
|
state->Reg[BITS(12, 15)] = (state->Reg[BITS(16, 19)] >> (8 * (BITS(10, 11)))) + Rm;
|
||||||
// printf("rd is %x\n", state->Reg[BITS (12, 15)]);
|
// printf("rd is %x\n", state->Reg[BITS (12, 15)]);
|
||||||
// exit(-1);
|
// exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
case 0x70:
|
||||||
|
if ((instr & 0xf0d0) == 0xf010) { //smuad //ichfly
|
||||||
|
u8 tar = BITS(16, 19);
|
||||||
|
u8 src1 = BITS(0, 3);
|
||||||
|
u8 src2 = BITS(8, 11);
|
||||||
|
u8 swap = BIT(5);
|
||||||
|
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
||||||
|
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
||||||
|
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
||||||
|
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
|
state->Reg[tar] = a1*a2 + b1*b2;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
#if 0
|
} else if ((instr & 0xf0d0) == 0xf050) { //smusd
|
||||||
|
u8 tar = BITS(16, 19);
|
||||||
|
u8 src1 = BITS(0, 3);
|
||||||
|
u8 src2 = BITS(8, 11);
|
||||||
|
u8 swap = BIT(5);
|
||||||
|
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
||||||
|
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
||||||
|
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
||||||
|
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
|
state->Reg[tar] = a1*a2 - b1*b2;
|
||||||
|
return 1;
|
||||||
|
} else if ((instr & 0xd0) == 0x10) { //smlad
|
||||||
|
u8 tar = BITS(16, 19);
|
||||||
|
u8 src1 = BITS(0, 3);
|
||||||
|
u8 src2 = BITS(8, 11);
|
||||||
|
u8 src3 = BITS(12, 15);
|
||||||
|
u8 swap = BIT(5);
|
||||||
|
|
||||||
|
u32 a3 = state->Reg[src3];
|
||||||
|
|
||||||
|
s16 a1 = (state->Reg[src1] & 0xFFFF);
|
||||||
|
s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
|
||||||
|
s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
|
||||||
|
s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
|
||||||
|
state->Reg[tar] = a1*a2 + b1*b2 + a3;
|
||||||
|
return 1;
|
||||||
|
} else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n");
|
||||||
|
break;
|
||||||
|
case 0x74:
|
||||||
|
printf ("Unhandled v6 insn: smlald/smlsld\n");
|
||||||
|
break;
|
||||||
|
case 0x75:
|
||||||
|
printf ("Unhandled v6 insn: smmla/smmls/smmul\n");
|
||||||
|
break;
|
||||||
|
case 0x78:
|
||||||
|
printf ("Unhandled v6 insn: usad/usada8\n");
|
||||||
|
break;
|
||||||
|
case 0x7a:
|
||||||
|
printf ("Unhandled v6 insn: usbfx\n");
|
||||||
|
break;
|
||||||
|
case 0x7c:
|
||||||
|
printf ("Unhandled v6 insn: bfc/bfi\n");
|
||||||
|
break;
|
||||||
case 0x84:
|
case 0x84:
|
||||||
printf ("Unhandled v6 insn: srs\n");
|
printf ("Unhandled v6 insn: srs\n");
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,6 +281,7 @@ struct ARMul_State
|
||||||
|
|
||||||
ARMword currentexaddr;
|
ARMword currentexaddr;
|
||||||
ARMword currentexval;
|
ARMword currentexval;
|
||||||
|
ARMword currentexvald;
|
||||||
ARMword servaddr;
|
ARMword servaddr;
|
||||||
|
|
||||||
unsigned NextInstr;
|
unsigned NextInstr;
|
||||||
|
|
|
@ -522,8 +522,7 @@ static s64 vfp_single_to_doubleintern(ARMul_State* state, s32 m, u32 fpscr) //ic
|
||||||
if (tm == VFP_QNAN)
|
if (tm == VFP_QNAN)
|
||||||
vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
|
vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
|
||||||
goto pack_nan;
|
goto pack_nan;
|
||||||
}
|
} else if (tm & VFP_ZERO)
|
||||||
else if (tm & VFP_ZERO)
|
|
||||||
vdd.exponent = 0;
|
vdd.exponent = 0;
|
||||||
else
|
else
|
||||||
vdd.exponent = vsm.exponent + (1023 - 127);
|
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
|
||||||
if (vsm.exponent >= 127 + 32) {
|
if (vsm.exponent >= 127 + 32) {
|
||||||
d = vsm.sign ? 0 : 0xffffffff;
|
d = vsm.sign ? 0 : 0xffffffff;
|
||||||
exceptions = FPSCR_IOC;
|
exceptions = FPSCR_IOC;
|
||||||
} else if (vsm.exponent >= 127 - 1) {
|
} else if (vsm.exponent >= 127) {
|
||||||
int shift = 127 + 31 - vsm.exponent;
|
int shift = 127 + 31 - vsm.exponent;
|
||||||
u32 rem, incr = 0;
|
u32 rem, incr = 0;
|
||||||
|
|
||||||
|
@ -705,7 +704,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f
|
||||||
if (vsm.sign)
|
if (vsm.sign)
|
||||||
d = ~d;
|
d = ~d;
|
||||||
exceptions |= FPSCR_IOC;
|
exceptions |= FPSCR_IOC;
|
||||||
} else if (vsm.exponent >= 127 - 1) {
|
} else if (vsm.exponent >= 127) {
|
||||||
int shift = 127 + 31 - vsm.exponent;
|
int shift = 127 + 31 - vsm.exponent;
|
||||||
u32 rem, incr = 0;
|
u32 rem, incr = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue