summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/interpreter/armemu.cpp276
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);
63static void Handle_Load_Double (ARMul_State *, ARMword); 63static void Handle_Load_Double (ARMul_State *, ARMword);
64static void Handle_Store_Double (ARMul_State *, ARMword); 64static void Handle_Store_Double (ARMul_State *, ARMword);
65 65
66void
67XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword _far);
68int
69XScale_debug_moe (ARMul_State * state, int moe);
70unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
71 unsigned cpnum);
72
73static int 66static int
74handle_v6_insn (ARMul_State * state, ARMword instr); 67handle_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);
4091exit:
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 }