diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 276 |
1 files changed, 234 insertions, 42 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index cdcf47ee1..73223874e 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -63,13 +63,6 @@ static unsigned MultiplyAdd64 (ARMul_State *, ARMword, int, int); | |||
| 63 | static void Handle_Load_Double (ARMul_State *, ARMword); | 63 | static void Handle_Load_Double (ARMul_State *, ARMword); |
| 64 | static void Handle_Store_Double (ARMul_State *, ARMword); | 64 | static void Handle_Store_Double (ARMul_State *, ARMword); |
| 65 | 65 | ||
| 66 | void | ||
| 67 | XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far); | ||
| 68 | int | ||
| 69 | XScale_debug_moe (ARMul_State * state, int moe); | ||
| 70 | unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg, | ||
| 71 | unsigned cpnum); | ||
| 72 | |||
| 73 | static int | 66 | static int |
| 74 | handle_v6_insn (ARMul_State * state, ARMword instr); | 67 | handle_v6_insn (ARMul_State * state, ARMword instr); |
| 75 | 68 | ||
| @@ -376,7 +369,7 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 376 | #endif | 369 | #endif |
| 377 | { | 370 | { |
| 378 | /* The PC pipeline value depends on whether ARM | 371 | /* The PC pipeline value depends on whether ARM |
| 379 | or Thumb instructions are being | 372 | or Thumb instructions are being |
| 380 | d. */ | 373 | d. */ |
| 381 | ARMword isize; | 374 | ARMword isize; |
| 382 | ARMword instr; /* The current instruction. */ | 375 | ARMword instr; /* The current instruction. */ |
| @@ -538,6 +531,7 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 538 | state->AbortAddr = 1; | 531 | state->AbortAddr = 1; |
| 539 | 532 | ||
| 540 | instr = ARMul_LoadInstrN (state, pc, isize); | 533 | instr = ARMul_LoadInstrN (state, pc, isize); |
| 534 | |||
| 541 | //chy 2006-04-12, for ICE debug | 535 | //chy 2006-04-12, for ICE debug |
| 542 | have_bp=ARMul_ICE_debug(state,instr,pc); | 536 | have_bp=ARMul_ICE_debug(state,instr,pc); |
| 543 | #if 0 | 537 | #if 0 |
| @@ -562,6 +556,7 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 562 | } | 556 | } |
| 563 | printf("\n"); | 557 | printf("\n"); |
| 564 | #endif | 558 | #endif |
| 559 | |||
| 565 | instr = ARMul_LoadInstrN (state, pc, isize); | 560 | instr = ARMul_LoadInstrN (state, pc, isize); |
| 566 | state->last_instr = state->CurrInstr; | 561 | state->last_instr = state->CurrInstr; |
| 567 | state->CurrInstr = instr; | 562 | state->CurrInstr = instr; |
| @@ -952,9 +947,8 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 952 | case t_decoded: | 947 | case t_decoded: |
| 953 | /* ARM instruction available. */ | 948 | /* ARM instruction available. */ |
| 954 | //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); | 949 | //printf("t decode %04lx -> %08lx\n", instr & 0xffff, armOp); |
| 955 | 950 | ||
| 956 | if (armOp == 0xDEADC0DE) | 951 | if (armOp == 0xDEADC0DE) { |
| 957 | { | ||
| 958 | DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); | 952 | DEBUG("Failed to decode thumb opcode %04X at %08X\n", instr, pc); |
| 959 | } | 953 | } |
| 960 | 954 | ||
| @@ -967,7 +961,6 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 967 | } | 961 | } |
| 968 | } | 962 | } |
| 969 | #endif | 963 | #endif |
| 970 | |||
| 971 | /* Check the condition codes. */ | 964 | /* Check the condition codes. */ |
| 972 | if ((temp = TOPBITS (28)) == AL) { | 965 | if ((temp = TOPBITS (28)) == AL) { |
| 973 | /* Vile deed in the need for speed. */ | 966 | /* Vile deed in the need for speed. */ |
| @@ -1124,6 +1117,7 @@ ARMul_Emulate26 (ARMul_State * state) | |||
| 1124 | 1117 | ||
| 1125 | //chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it... | 1118 | //chy 2003-08-24 now #if 0 .... #endif process cp14, cp15.reg14, I disable it... |
| 1126 | 1119 | ||
| 1120 | |||
| 1127 | /* Actual execution of instructions begins here. */ | 1121 | /* Actual execution of instructions begins here. */ |
| 1128 | /* If the condition codes don't match, stop here. */ | 1122 | /* If the condition codes don't match, stop here. */ |
| 1129 | if (temp) { | 1123 | if (temp) { |
| @@ -2308,12 +2302,9 @@ mainswitch: | |||
| 2308 | if (state->Aborted) { | 2302 | if (state->Aborted) { |
| 2309 | TAKEABORT; | 2303 | TAKEABORT; |
| 2310 | } | 2304 | } |
| 2311 | if (enter) | 2305 | if (enter) { |
| 2312 | { | ||
| 2313 | state->Reg[DESTReg] = 0; | 2306 | state->Reg[DESTReg] = 0; |
| 2314 | } | 2307 | } else { |
| 2315 | else | ||
| 2316 | { | ||
| 2317 | state->Reg[DESTReg] = 1; | 2308 | state->Reg[DESTReg] = 1; |
| 2318 | } | 2309 | } |
| 2319 | break; | 2310 | break; |
| @@ -3063,7 +3054,27 @@ mainswitch: | |||
| 3063 | break; | 3054 | break; |
| 3064 | 3055 | ||
| 3065 | case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ | 3056 | case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */ |
| 3066 | if (BIT (4)) { | 3057 | //ichfly PKHBT PKHTB todo check this |
| 3058 | if ((instr & 0x70) == 0x10) //pkhbt | ||
| 3059 | { | ||
| 3060 | u8 idest = BITS(12, 15); | ||
| 3061 | u8 rfis = BITS(16, 19); | ||
| 3062 | u8 rlast = BITS(0, 3); | ||
| 3063 | u8 ishi = BITS(7,11); | ||
| 3064 | state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); | ||
| 3065 | break; | ||
| 3066 | } | ||
| 3067 | else if ((instr & 0x70) == 0x50)//pkhtb | ||
| 3068 | { | ||
| 3069 | u8 idest = BITS(12, 15); | ||
| 3070 | u8 rfis = BITS(16, 19); | ||
| 3071 | u8 rlast = BITS(0, 3); | ||
| 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; | ||
| 3076 | } | ||
| 3077 | else if (BIT (4)) { | ||
| 3067 | #ifdef MODE32 | 3078 | #ifdef MODE32 |
| 3068 | if (state->is_v6 | 3079 | if (state->is_v6 |
| 3069 | && handle_v6_insn (state, instr)) | 3080 | && handle_v6_insn (state, instr)) |
| @@ -3675,7 +3686,13 @@ mainswitch: | |||
| 3675 | 3686 | ||
| 3676 | /* Co-Processor Data Transfers. */ | 3687 | /* Co-Processor Data Transfers. */ |
| 3677 | case 0xc4: | 3688 | case 0xc4: |
| 3678 | if (state->is_v5) { | 3689 | 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)]; | ||
| 3692 | state->ExtReg[(BITS(0, 3) << 1) + 1] = state->Reg[BITS(16, 20)]; | ||
| 3693 | break; | ||
| 3694 | } | ||
| 3695 | else if (state->is_v5) { | ||
| 3679 | /* Reading from R15 is UNPREDICTABLE. */ | 3696 | /* Reading from R15 is UNPREDICTABLE. */ |
| 3680 | if (BITS (12, 15) == 15 || BITS (16, 19) == 15) | 3697 | if (BITS (12, 15) == 15 || BITS (16, 19) == 15) |
| 3681 | ARMul_UndefInstr (state, instr); | 3698 | ARMul_UndefInstr (state, instr); |
| @@ -3695,13 +3712,21 @@ mainswitch: | |||
| 3695 | break; | 3712 | break; |
| 3696 | 3713 | ||
| 3697 | case 0xc5: | 3714 | case 0xc5: |
| 3698 | if (state->is_v5) { | 3715 | 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]; | ||
| 3718 | state->Reg[BITS(16, 19)] = state->ExtReg[(BITS(0, 3) << 1) + 1]; | ||
| 3719 | break; | ||
| 3720 | } | ||
| 3721 | else if (state->is_v5) { | ||
| 3699 | /* Writes to R15 are UNPREDICATABLE. */ | 3722 | /* Writes to R15 are UNPREDICATABLE. */ |
| 3700 | if (DESTReg == 15 || LHSReg == 15) | 3723 | if (DESTReg == 15 || LHSReg == 15) |
| 3701 | ARMul_UndefInstr (state, instr); | 3724 | ARMul_UndefInstr (state, instr); |
| 3702 | /* Is access to the coprocessor allowed ? */ | 3725 | /* Is access to the coprocessor allowed ? */ |
| 3703 | else if (!CP_ACCESS_ALLOWED(state, CPNum)) | 3726 | else if (!CP_ACCESS_ALLOWED(state, CPNum)) |
| 3704 | ARMul_UndefInstr (state, instr); | 3727 | { |
| 3728 | ARMul_UndefInstr(state, instr); | ||
| 3729 | } | ||
| 3705 | else { | 3730 | else { |
| 3706 | /* MRRC, ARMv5TE and up */ | 3731 | /* MRRC, ARMv5TE and up */ |
| 3707 | ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); | 3732 | ARMul_MRRC (state, instr, &DEST, &(state->Reg[LHSReg])); |
| @@ -4059,9 +4084,11 @@ TEST_EMULATE: | |||
| 4059 | // continue; | 4084 | // continue; |
| 4060 | else if (state->Emulate != RUN) | 4085 | else if (state->Emulate != RUN) |
| 4061 | break; | 4086 | break; |
| 4062 | } | 4087 | |
| 4063 | while (state->NumInstrsToExecute--); | 4088 | } |
| 4064 | 4089 | ||
| 4090 | while (state->NumInstrsToExecute); | ||
| 4091 | exit: | ||
| 4065 | state->decoded = decoded; | 4092 | state->decoded = decoded; |
| 4066 | state->loaded = loaded; | 4093 | state->loaded = loaded; |
| 4067 | state->pc = pc; | 4094 | state->pc = pc; |
| @@ -5686,12 +5713,98 @@ L_stm_s_takeabort: | |||
| 5686 | case 0x3f: | 5713 | case 0x3f: |
| 5687 | printf ("Unhandled v6 insn: rbit\n"); | 5714 | printf ("Unhandled v6 insn: rbit\n"); |
| 5688 | break; | 5715 | break; |
| 5716 | #endif | ||
| 5689 | case 0x61: | 5717 | case 0x61: |
| 5690 | printf ("Unhandled v6 insn: sadd/ssub\n"); | 5718 | if ((instr & 0xFF0) == 0xf70)//ssub16 |
| 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 | { | ||
| 5732 | u8 tar = BITS(12, 15); | ||
| 5733 | u8 src1 = BITS(16, 19); | ||
| 5734 | u8 src2 = BITS(0, 3); | ||
| 5735 | s16 a1 = (state->Reg[src1] & 0xFFFF); | ||
| 5736 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | ||
| 5737 | s16 b1 = (state->Reg[src2] & 0xFFFF); | ||
| 5738 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | ||
| 5739 | state->Reg[tar] = (a1 + a2)&0xFFFF | (((b1 + b2)&0xFFFF)<< 0x10); | ||
| 5740 | return 1; | ||
| 5741 | } | ||
| 5742 | else if ((instr & 0xFF0) == 0xf50)//ssax | ||
| 5743 | { | ||
| 5744 | u8 tar = BITS(12, 15); | ||
| 5745 | u8 src1 = BITS(16, 19); | ||
| 5746 | u8 src2 = BITS(0, 3); | ||
| 5747 | s16 a1 = (state->Reg[src1] & 0xFFFF); | ||
| 5748 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | ||
| 5749 | s16 b1 = (state->Reg[src2] & 0xFFFF); | ||
| 5750 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | ||
| 5751 | state->Reg[tar] = (a1 - b2) & 0xFFFF | (((a2 + b1) & 0xFFFF) << 0x10); | ||
| 5752 | return 1; | ||
| 5753 | } | ||
| 5754 | else if ((instr & 0xFF0) == 0xf30)//sasx | ||
| 5755 | { | ||
| 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 | } | ||
| 5766 | else printf ("Unhandled v6 insn: sadd/ssub\n"); | ||
| 5691 | break; | 5767 | break; |
| 5692 | case 0x62: | 5768 | case 0x62: |
| 5693 | printf ("Unhandled v6 insn: qadd/qsub\n"); | 5769 | if ((instr & 0xFF0) == 0xf70)//QSUB16 |
| 5770 | { | ||
| 5771 | u8 tar = BITS(12, 15); | ||
| 5772 | u8 src1 = BITS(16, 19); | ||
| 5773 | u8 src2 = BITS(0, 3); | ||
| 5774 | s16 a1 = (state->Reg[src1] & 0xFFFF); | ||
| 5775 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | ||
| 5776 | s16 b1 = (state->Reg[src2] & 0xFFFF); | ||
| 5777 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | ||
| 5778 | s32 res1 = (a1 - b1); | ||
| 5779 | s32 res2 = (a2 - b2); | ||
| 5780 | if (res1 > 0x7FFF) res1 = 0x7FFF; | ||
| 5781 | if (res2 > 0x7FFF) res2 = 0x7FFF; | ||
| 5782 | if (res1 < 0x7FFF) res1 = -0x8000; | ||
| 5783 | if (res2 < 0x7FFF) res2 = -0x8000; | ||
| 5784 | state->Reg[tar] = (res1 & 0xFFFF) | ((res2 & 0xFFFF) << 0x10); | ||
| 5785 | return 1; | ||
| 5786 | } | ||
| 5787 | else if ((instr & 0xFF0) == 0xf10)//QADD16 | ||
| 5788 | { | ||
| 5789 | u8 tar = BITS(12, 15); | ||
| 5790 | u8 src1 = BITS(16, 19); | ||
| 5791 | u8 src2 = BITS(0, 3); | ||
| 5792 | s16 a1 = (state->Reg[src1] & 0xFFFF); | ||
| 5793 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | ||
| 5794 | s16 b1 = (state->Reg[src2] & 0xFFFF); | ||
| 5795 | s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); | ||
| 5796 | s32 res1 = (a1 + b1); | ||
| 5797 | s32 res2 = (a2 + b2); | ||
| 5798 | if (res1 > 0x7FFF) res1 = 0x7FFF; | ||
| 5799 | if (res2 > 0x7FFF) res2 = 0x7FFF; | ||
| 5800 | if (res1 < 0x7FFF) res1 = -0x8000; | ||
| 5801 | if (res2 < 0x7FFF) res2 = -0x8000; | ||
| 5802 | state->Reg[tar] = ((res1) & 0xFFFF) | (((res2) & 0xFFFF) << 0x10); | ||
| 5803 | return 1; | ||
| 5804 | } | ||
| 5805 | else printf ("Unhandled v6 insn: qadd/qsub\n"); | ||
| 5694 | break; | 5806 | break; |
| 5807 | #if 0 | ||
| 5695 | case 0x63: | 5808 | case 0x63: |
| 5696 | printf ("Unhandled v6 insn: shadd/shsub\n"); | 5809 | printf ("Unhandled v6 insn: shadd/shsub\n"); |
| 5697 | break; | 5810 | break; |
| @@ -5709,10 +5822,65 @@ L_stm_s_takeabort: | |||
| 5709 | break; | 5822 | break; |
| 5710 | #endif | 5823 | #endif |
| 5711 | case 0x6c: | 5824 | case 0x6c: |
| 5712 | printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); | 5825 | if ((instr & 0xf03f0) == 0xf0070) //uxtb16 |
| 5826 | { | ||
| 5827 | u8 src1 = BITS(0, 3); | ||
| 5828 | u8 tar = BITS(12, 15); | ||
| 5829 | u32 base = state->Reg[src1]; | ||
| 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"); | ||
| 5713 | break; | 5837 | break; |
| 5714 | case 0x70: | 5838 | case 0x70: |
| 5715 | printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); | 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 | |||
| 5852 | } | ||
| 5853 | else if ((instr & 0xf0d0) == 0xf050)//smusd | ||
| 5854 | { | ||
| 5855 | u8 tar = BITS(16, 19); | ||
| 5856 | u8 src1 = BITS(0, 3); | ||
| 5857 | u8 src2 = BITS(8, 11); | ||
| 5858 | u8 swap = BIT(5); | ||
| 5859 | s16 a1 = (state->Reg[src1] & 0xFFFF); | ||
| 5860 | s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); | ||
| 5861 | s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); | ||
| 5862 | s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); | ||
| 5863 | state->Reg[tar] = a1*a2 - b1*b2; | ||
| 5864 | return 1; | ||
| 5865 | } | ||
| 5866 | else if ((instr & 0xd0) == 0x10)//smlad | ||
| 5867 | { | ||
| 5868 | u8 tar = BITS(16, 19); | ||
| 5869 | u8 src1 = BITS(0, 3); | ||
| 5870 | u8 src2 = BITS(8, 11); | ||
| 5871 | u8 src3 = BITS(12, 15); | ||
| 5872 | u8 swap = BIT(5); | ||
| 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; | ||
| 5882 | } | ||
| 5883 | else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); | ||
| 5716 | break; | 5884 | break; |
| 5717 | case 0x74: | 5885 | case 0x74: |
| 5718 | printf ("Unhandled v6 insn: smlald/smlsld\n"); | 5886 | printf ("Unhandled v6 insn: smlald/smlsld\n"); |
| @@ -5750,13 +5918,10 @@ L_stm_s_takeabort: | |||
| 5750 | if (state->Aborted) { | 5918 | if (state->Aborted) { |
| 5751 | TAKEABORT; | 5919 | TAKEABORT; |
| 5752 | } | 5920 | } |
| 5753 | 5921 | ||
| 5754 | if (enter) | 5922 | if (enter) { |
| 5755 | { | ||
| 5756 | state->Reg[DESTReg] = 0; | 5923 | state->Reg[DESTReg] = 0; |
| 5757 | } | 5924 | } else { |
| 5758 | else | ||
| 5759 | { | ||
| 5760 | state->Reg[DESTReg] = 1; | 5925 | state->Reg[DESTReg] = 1; |
| 5761 | } | 5926 | } |
| 5762 | 5927 | ||
| @@ -5795,12 +5960,9 @@ L_stm_s_takeabort: | |||
| 5795 | } | 5960 | } |
| 5796 | 5961 | ||
| 5797 | 5962 | ||
| 5798 | if (enter) | 5963 | if (enter) { |
| 5799 | { | ||
| 5800 | state->Reg[DESTReg] = 0; | 5964 | state->Reg[DESTReg] = 0; |
| 5801 | } | 5965 | } else { |
| 5802 | else | ||
| 5803 | { | ||
| 5804 | state->Reg[DESTReg] = 1; | 5966 | state->Reg[DESTReg] = 1; |
| 5805 | } | 5967 | } |
| 5806 | 5968 | ||
| @@ -5853,8 +6015,25 @@ L_stm_s_takeabort: | |||
| 5853 | 6015 | ||
| 5854 | case 0x01: | 6016 | case 0x01: |
| 5855 | case 0xf3: | 6017 | case 0xf3: |
| 5856 | printf ("Unhandled v6 insn: ssat\n"); | 6018 | //ichfly |
| 5857 | return 0; | 6019 | //SSAT16 |
| 6020 | { | ||
| 6021 | u8 tar = BITS(12,15); | ||
| 6022 | u8 src = BITS(0, 3); | ||
| 6023 | u8 val = BITS(16, 19) + 1; | ||
| 6024 | s16 a1 = (state->Reg[src]); | ||
| 6025 | s16 a2 = (state->Reg[src] >> 0x10); | ||
| 6026 | s16 min = (s16)(0x8000) >> (16 - val); | ||
| 6027 | s16 max = 0x7FFF >> (16 - val); | ||
| 6028 | if (min > a1) a1 = min; | ||
| 6029 | if (max < a1) a1 = max; | ||
| 6030 | if (min > a2) a2 = min; | ||
| 6031 | if (max < a2) a2 = max; | ||
| 6032 | u32 temp2 = ((u32)(a2)) << 0x10; | ||
| 6033 | state->Reg[tar] = (a1&0xFFFF) | (temp2); | ||
| 6034 | } | ||
| 6035 | |||
| 6036 | return 1; | ||
| 5858 | default: | 6037 | default: |
| 5859 | break; | 6038 | break; |
| 5860 | } | 6039 | } |
| @@ -5944,8 +6123,21 @@ L_stm_s_takeabort: | |||
| 5944 | 6123 | ||
| 5945 | case 0x01: | 6124 | case 0x01: |
| 5946 | case 0xf3: | 6125 | case 0xf3: |
| 5947 | printf ("Unhandled v6 insn: usat\n"); | 6126 | //ichfly |
| 5948 | return 0; | 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; | ||
| 5949 | default: | 6141 | default: |
| 5950 | break; | 6142 | break; |
| 5951 | } | 6143 | } |