summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/arm/interpreter/armemu.cpp220
-rw-r--r--src/core/hle/kernel/shared_memory.h14
-rw-r--r--src/core/hle/svc.cpp4
3 files changed, 160 insertions, 78 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 1a589e39c..07d205755 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -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. */
@@ -3103,12 +3109,18 @@ mainswitch:
3103 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); 3109 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
3104 break; 3110 break;
3105 } else if ((instr & 0x70) == 0x50) { //pkhtb 3111 } else if ((instr & 0x70) == 0x50) { //pkhtb
3106 u8 idest = BITS(12, 15); 3112 const u8 rd_idx = BITS(12, 15);
3107 u8 rfis = BITS(16, 19); 3113 const u8 rn_idx = BITS(16, 19);
3108 u8 rlast = BITS(0, 3); 3114 const u8 rm_idx = BITS(0, 3);
3109 u8 ishi = BITS(7, 11); 3115 const u8 imm5 = BITS(7, 11);
3110 if (ishi == 0)ishi = 0x20; 3116
3111 state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000); 3117 ARMword val;
3118 if (imm5 >= 32)
3119 val = (state->Reg[rm_idx] >> 31);
3120 else
3121 val = (state->Reg[rm_idx] >> imm5);
3122
3123 state->Reg[rd_idx] = (val & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3112 break; 3124 break;
3113 } else if (BIT (4)) { 3125 } else if (BIT (4)) {
3114#ifdef MODE32 3126#ifdef MODE32
@@ -5677,8 +5689,24 @@ L_stm_s_takeabort:
5677 case 0x03: 5689 case 0x03:
5678 printf ("Unhandled v6 insn: ldr\n"); 5690 printf ("Unhandled v6 insn: ldr\n");
5679 break; 5691 break;
5680 case 0x04: 5692 case 0x04: // UMAAL
5681 printf ("Unhandled v6 insn: umaal\n"); 5693 {
5694 const u8 rm_idx = BITS(8, 11);
5695 const u8 rn_idx = BITS(0, 3);
5696 const u8 rd_lo_idx = BITS(12, 15);
5697 const u8 rd_hi_idx = BITS(16, 19);
5698
5699 const u32 rm_val = state->Reg[rm_idx];
5700 const u32 rn_val = state->Reg[rn_idx];
5701 const u32 rd_lo_val = state->Reg[rd_lo_idx];
5702 const u32 rd_hi_val = state->Reg[rd_hi_idx];
5703
5704 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
5705
5706 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
5707 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
5708 return 1;
5709 }
5682 break; 5710 break;
5683 case 0x06: 5711 case 0x06:
5684 printf ("Unhandled v6 insn: mls/str\n"); 5712 printf ("Unhandled v6 insn: mls/str\n");
@@ -5799,49 +5827,63 @@ L_stm_s_takeabort:
5799 case 0x3f: 5827 case 0x3f:
5800 printf ("Unhandled v6 insn: rbit\n"); 5828 printf ("Unhandled v6 insn: rbit\n");
5801 break; 5829 break;
5802 case 0x61: 5830 case 0x61: // SSUB16, SADD16, SSAX, and SASX
5803 if ((instr & 0xFF0) == 0xf70) { //ssub16 5831 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10 ||
5804 u8 tar = BITS(12, 15); 5832 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf30)
5805 u8 src1 = BITS(16, 19); 5833 {
5806 u8 src2 = BITS(0, 3);
5807 s16 a1 = (state->Reg[src1] & 0xFFFF);
5808 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5809 s16 b1 = (state->Reg[src2] & 0xFFFF);
5810 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5811 state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2) & 0xFFFF) << 0x10);
5812 return 1;
5813 } else if ((instr & 0xFF0) == 0xf10) { //sadd16
5814 const u8 rd_idx = BITS(12, 15); 5834 const u8 rd_idx = BITS(12, 15);
5815 const u8 rm_idx = BITS(0, 3); 5835 const u8 rm_idx = BITS(0, 3);
5816 const u8 rn_idx = BITS(16, 19); 5836 const u8 rn_idx = BITS(16, 19);
5817 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5818 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5819 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); 5837 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5820 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); 5838 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5839 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5840 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5821 5841
5822 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16); 5842 s32 lo_result;
5823 return 1; 5843 s32 hi_result;
5824 } else if ((instr & 0xFF0) == 0xf50) { //ssax 5844
5825 u8 tar = BITS(12, 15); 5845 // SSUB16
5826 u8 src1 = BITS(16, 19); 5846 if ((instr & 0xFF0) == 0xf70) {
5827 u8 src2 = BITS(0, 3); 5847 lo_result = (rn_lo - rm_lo);
5828 s16 a1 = (state->Reg[src1] & 0xFFFF); 5848 hi_result = (rn_hi - rm_hi);
5829 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5849 }
5830 s16 b1 = (state->Reg[src2] & 0xFFFF); 5850 // SADD16
5831 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5851 else if ((instr & 0xFF0) == 0xf10) {
5832 state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); 5852 lo_result = (rn_lo + rm_lo);
5833 return 1; 5853 hi_result = (rn_hi + rm_hi);
5834 } else if ((instr & 0xFF0) == 0xf30) { //sasx 5854 }
5835 u8 tar = BITS(12, 15); 5855 // SSAX
5836 u8 src1 = BITS(16, 19); 5856 else if ((instr & 0xFF0) == 0xf50) {
5837 u8 src2 = BITS(0, 3); 5857 lo_result = (rn_lo + rm_hi);
5838 s16 a1 = (state->Reg[src1] & 0xFFFF); 5858 hi_result = (rn_hi - rm_lo);
5839 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5859 }
5840 s16 b1 = (state->Reg[src2] & 0xFFFF); 5860 // SASX
5841 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5861 else {
5842 state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10); 5862 lo_result = (rn_lo - rm_hi);
5863 hi_result = (rn_hi + rm_lo);
5864 }
5865
5866 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5867
5868 if (lo_result >= 0) {
5869 state->Cpsr |= (1 << 16);
5870 state->Cpsr |= (1 << 17);
5871 } else {
5872 state->Cpsr &= ~(1 << 16);
5873 state->Cpsr &= ~(1 << 17);
5874 }
5875
5876 if (hi_result >= 0) {
5877 state->Cpsr |= (1 << 18);
5878 state->Cpsr |= (1 << 19);
5879 } else {
5880 state->Cpsr &= ~(1 << 18);
5881 state->Cpsr &= ~(1 << 19);
5882 }
5843 return 1; 5883 return 1;
5844 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5884 } else {
5885 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5886 }
5845 break; 5887 break;
5846 case 0x62: // QSUB16 and QADD16 5888 case 0x62: // QSUB16 and QADD16
5847 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { 5889 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {
@@ -5930,11 +5972,29 @@ L_stm_s_takeabort:
5930 b2 = ((u8)(from >> 8) + (u8)(to >> 8)); 5972 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
5931 b3 = ((u8)(from >> 16) + (u8)(to >> 16)); 5973 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
5932 b4 = ((u8)(from >> 24) + (u8)(to >> 24)); 5974 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5933 if (b1 & 0xffffff00) state->Cpsr |= (1 << 16); 5975
5934 if (b2 & 0xffffff00) state->Cpsr |= (1 << 17); 5976 if (b1 & 0xffffff00)
5935 if (b3 & 0xffffff00) state->Cpsr |= (1 << 18); 5977 state->Cpsr |= (1 << 16);
5936 if (b4 & 0xffffff00) state->Cpsr |= (1 << 19); 5978 else
5979 state->Cpsr &= ~(1 << 16);
5980
5981 if (b2 & 0xffffff00)
5982 state->Cpsr |= (1 << 17);
5983 else
5984 state->Cpsr &= ~(1 << 17);
5985
5986 if (b3 & 0xffffff00)
5987 state->Cpsr |= (1 << 18);
5988 else
5989 state->Cpsr &= ~(1 << 18);
5990
5991
5992 if (b4 & 0xffffff00)
5993 state->Cpsr |= (1 << 19);
5994 else
5995 state->Cpsr &= ~(1 << 19);
5937 } 5996 }
5997
5938 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); 5998 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5939 return 1; 5999 return 1;
5940 } 6000 }
@@ -6049,7 +6109,7 @@ L_stm_s_takeabort:
6049 break; 6109 break;
6050 } 6110 }
6051 6111
6052 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6112 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
6053 if (Rm & 0x80) 6113 if (Rm & 0x80)
6054 Rm |= 0xffffff00; 6114 Rm |= 0xffffff00;
6055 6115
@@ -6058,11 +6118,12 @@ L_stm_s_takeabort:
6058 state->Reg[BITS(12, 15)] = Rm; 6118 state->Reg[BITS(12, 15)] = Rm;
6059 else 6119 else
6060 /* SXTAB */ 6120 /* SXTAB */
6061 state->Reg[BITS(12, 15)] += Rm; 6121 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6062 6122
6063 return 1; 6123 return 1;
6064 } 6124 }
6065 case 0x6b: { 6125 case 0x6b:
6126 {
6066 ARMword Rm; 6127 ARMword Rm;
6067 int ror = -1; 6128 int ror = -1;
6068 6129
@@ -6080,10 +6141,10 @@ L_stm_s_takeabort:
6080 ror = 24; 6141 ror = 24;
6081 break; 6142 break;
6082 6143
6083 case 0xf3: 6144 case 0xf3: // REV
6084 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); 6145 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6085 return 1; 6146 return 1;
6086 case 0xfb: 6147 case 0xfb: // REV16
6087 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); 6148 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6088 return 1; 6149 return 1;
6089 default: 6150 default:
@@ -6093,7 +6154,7 @@ L_stm_s_takeabort:
6093 if (ror == -1) 6154 if (ror == -1)
6094 break; 6155 break;
6095 6156
6096 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6157 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
6097 if (Rm & 0x8000) 6158 if (Rm & 0x8000)
6098 Rm |= 0xffff0000; 6159 Rm |= 0xffff0000;
6099 6160
@@ -6156,18 +6217,27 @@ L_stm_s_takeabort:
6156 //ichfly 6217 //ichfly
6157 //USAT16 6218 //USAT16
6158 { 6219 {
6159 u8 tar = BITS(12, 15); 6220 const u8 rd_idx = BITS(12, 15);
6160 u8 src = BITS(0, 3); 6221 const u8 rn_idx = BITS(0, 3);
6161 u8 val = BITS(16, 19); 6222 const u8 num_bits = BITS(16, 19);
6162 s16 a1 = (state->Reg[src]); 6223 const s16 max = 0xFFFF >> (16 - num_bits);
6163 s16 a2 = (state->Reg[src] >> 0x10); 6224 s16 rn_lo = (state->Reg[rn_idx]);
6164 s16 max = 0xFFFF >> (16 - val); 6225 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6165 if (max < a1) a1 = max; 6226
6166 if (max < a2) a2 = max; 6227 if (max < rn_lo)
6167 u32 temp2 = ((u32)(a2)) << 0x10; 6228 rn_lo = max;
6168 state->Reg[tar] = (a1 & 0xFFFF) | (temp2); 6229 else if (rn_lo < 0)
6230 rn_lo = 0;
6231
6232 if (max < rn_hi)
6233 rn_hi = max;
6234 else if (rn_hi < 0)
6235 rn_hi = 0;
6236
6237 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6238 return 1;
6169 } 6239 }
6170 return 1; 6240
6171 default: 6241 default:
6172 break; 6242 break;
6173 } 6243 }
@@ -6180,7 +6250,7 @@ L_stm_s_takeabort:
6180 break; 6250 break;
6181 } 6251 }
6182 6252
6183 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6253 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
6184 6254
6185 if (BITS(16, 19) == 0xf) 6255 if (BITS(16, 19) == 0xf)
6186 /* UXTB */ 6256 /* UXTB */
@@ -6210,9 +6280,13 @@ L_stm_s_takeabort:
6210 ror = 24; 6280 ror = 24;
6211 break; 6281 break;
6212 6282
6213 case 0xfb: 6283 case 0xfb: // REVSH
6214 printf("Unhandled v6 insn: revsh\n"); 6284 {
6215 return 0; 6285 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6286 if (DEST & 0x8000)
6287 DEST |= 0xffff0000;
6288 return 1;
6289 }
6216 default: 6290 default:
6217 break; 6291 break;
6218 } 6292 }
@@ -6220,13 +6294,13 @@ L_stm_s_takeabort:
6220 if (ror == -1) 6294 if (ror == -1)
6221 break; 6295 break;
6222 6296
6223 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6297 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
6224 6298
6225 /* UXT */ 6299 /* UXT */
6226 /* state->Reg[BITS (12, 15)] = Rm; */ 6300 /* state->Reg[BITS (12, 15)] = Rm; */
6227 /* dyf add */ 6301 /* dyf add */
6228 if (BITS(16, 19) == 0xf) { 6302 if (BITS(16, 19) == 0xf) {
6229 state->Reg[BITS(12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; 6303 state->Reg[BITS(12, 15)] = Rm;
6230 } 6304 }
6231 else { 6305 else {
6232 /* UXTAH */ 6306 /* UXTAH */
@@ -6234,7 +6308,7 @@ L_stm_s_takeabort:
6234 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)] 6308 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6235 // , Rm, BITS(10, 11)); 6309 // , Rm, BITS(10, 11));
6236 // printf("icounter is %lld\n", state->NumInstrs); 6310 // printf("icounter is %lld\n", state->NumInstrs);
6237 state->Reg[BITS(12, 15)] = (state->Reg[BITS(16, 19)] >> (8 * (BITS(10, 11)))) + Rm; 6311 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6238 // printf("rd is %x\n", state->Reg[BITS (12, 15)]); 6312 // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6239 // exit(-1); 6313 // exit(-1);
6240 } 6314 }
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 304cf5b67..bb778ec26 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -12,11 +12,15 @@ namespace Kernel {
12 12
13/// Permissions for mapped shared memory blocks 13/// Permissions for mapped shared memory blocks
14enum class MemoryPermission : u32 { 14enum class MemoryPermission : u32 {
15 None = 0, 15 None = 0,
16 Read = (1u << 0), 16 Read = (1u << 0),
17 Write = (1u << 1), 17 Write = (1u << 1),
18 ReadWrite = (Read | Write), 18 ReadWrite = (Read | Write),
19 DontCare = (1u << 28) 19 Execute = (1u << 2),
20 ReadExecute = (Read | Execute),
21 WriteExecute = (Write | Execute),
22 ReadWriteExecute = (Read | Write | Execute),
23 DontCare = (1u << 28)
20}; 24};
21 25
22/** 26/**
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 15cc240f4..47e9bf77e 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -64,6 +64,10 @@ static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other
64 case Kernel::MemoryPermission::Read: 64 case Kernel::MemoryPermission::Read:
65 case Kernel::MemoryPermission::Write: 65 case Kernel::MemoryPermission::Write:
66 case Kernel::MemoryPermission::ReadWrite: 66 case Kernel::MemoryPermission::ReadWrite:
67 case Kernel::MemoryPermission::Execute:
68 case Kernel::MemoryPermission::ReadExecute:
69 case Kernel::MemoryPermission::WriteExecute:
70 case Kernel::MemoryPermission::ReadWriteExecute:
67 case Kernel::MemoryPermission::DontCare: 71 case Kernel::MemoryPermission::DontCare:
68 Kernel::MapSharedMemory(handle, addr, permissions_type, 72 Kernel::MapSharedMemory(handle, addr, permissions_type,
69 static_cast<Kernel::MemoryPermission>(other_permissions)); 73 static_cast<Kernel::MemoryPermission>(other_permissions));