summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/arm/interpreter/armemu.cpp164
-rw-r--r--src/core/hle/kernel/shared_memory.h14
-rw-r--r--src/core/hle/svc.cpp4
3 files changed, 115 insertions, 67 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 1a589e39c..b9ac8b9ad 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,38 @@ 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 // SSUB16
5823 return 1; 5843 if ((instr & 0xFF0) == 0xf70) {
5824 } else if ((instr & 0xFF0) == 0xf50) { //ssax 5844 state->Reg[rd_idx] = ((rn_lo - rm_lo) & 0xFFFF) | (((rn_hi - rm_hi) & 0xFFFF) << 16);
5825 u8 tar = BITS(12, 15); 5845 }
5826 u8 src1 = BITS(16, 19); 5846 // SADD16
5827 u8 src2 = BITS(0, 3); 5847 else if ((instr & 0xFF0) == 0xf10) {
5828 s16 a1 = (state->Reg[src1] & 0xFFFF); 5848 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16);
5829 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5849 }
5830 s16 b1 = (state->Reg[src2] & 0xFFFF); 5850 // SSAX
5831 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5851 else if ((instr & 0xFF0) == 0xf50) {
5832 state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); 5852 state->Reg[rd_idx] = ((rn_lo + rm_hi) & 0xFFFF) | (((rn_hi - rm_lo) & 0xFFFF) << 16);
5833 return 1; 5853 }
5834 } else if ((instr & 0xFF0) == 0xf30) { //sasx 5854 // SASX
5835 u8 tar = BITS(12, 15); 5855 else {
5836 u8 src1 = BITS(16, 19); 5856 state->Reg[rd_idx] = ((rn_lo - rm_hi) & 0xFFFF) | (((rn_hi + rm_lo) & 0xFFFF) << 16);
5837 u8 src2 = BITS(0, 3); 5857 }
5838 s16 a1 = (state->Reg[src1] & 0xFFFF);
5839 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5840 s16 b1 = (state->Reg[src2] & 0xFFFF);
5841 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5842 state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10);
5843 return 1; 5858 return 1;
5844 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5859 } else {
5860 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5861 }
5845 break; 5862 break;
5846 case 0x62: // QSUB16 and QADD16 5863 case 0x62: // QSUB16 and QADD16
5847 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { 5864 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {
@@ -5930,11 +5947,29 @@ L_stm_s_takeabort:
5930 b2 = ((u8)(from >> 8) + (u8)(to >> 8)); 5947 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
5931 b3 = ((u8)(from >> 16) + (u8)(to >> 16)); 5948 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
5932 b4 = ((u8)(from >> 24) + (u8)(to >> 24)); 5949 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5933 if (b1 & 0xffffff00) state->Cpsr |= (1 << 16); 5950
5934 if (b2 & 0xffffff00) state->Cpsr |= (1 << 17); 5951 if (b1 & 0xffffff00)
5935 if (b3 & 0xffffff00) state->Cpsr |= (1 << 18); 5952 state->Cpsr |= (1 << 16);
5936 if (b4 & 0xffffff00) state->Cpsr |= (1 << 19); 5953 else
5954 state->Cpsr &= ~(1 << 16);
5955
5956 if (b2 & 0xffffff00)
5957 state->Cpsr |= (1 << 17);
5958 else
5959 state->Cpsr &= ~(1 << 17);
5960
5961 if (b3 & 0xffffff00)
5962 state->Cpsr |= (1 << 18);
5963 else
5964 state->Cpsr &= ~(1 << 18);
5965
5966
5967 if (b4 & 0xffffff00)
5968 state->Cpsr |= (1 << 19);
5969 else
5970 state->Cpsr &= ~(1 << 19);
5937 } 5971 }
5972
5938 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); 5973 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5939 return 1; 5974 return 1;
5940 } 5975 }
@@ -6049,7 +6084,7 @@ L_stm_s_takeabort:
6049 break; 6084 break;
6050 } 6085 }
6051 6086
6052 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6087 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
6053 if (Rm & 0x80) 6088 if (Rm & 0x80)
6054 Rm |= 0xffffff00; 6089 Rm |= 0xffffff00;
6055 6090
@@ -6058,11 +6093,12 @@ L_stm_s_takeabort:
6058 state->Reg[BITS(12, 15)] = Rm; 6093 state->Reg[BITS(12, 15)] = Rm;
6059 else 6094 else
6060 /* SXTAB */ 6095 /* SXTAB */
6061 state->Reg[BITS(12, 15)] += Rm; 6096 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6062 6097
6063 return 1; 6098 return 1;
6064 } 6099 }
6065 case 0x6b: { 6100 case 0x6b:
6101 {
6066 ARMword Rm; 6102 ARMword Rm;
6067 int ror = -1; 6103 int ror = -1;
6068 6104
@@ -6080,10 +6116,10 @@ L_stm_s_takeabort:
6080 ror = 24; 6116 ror = 24;
6081 break; 6117 break;
6082 6118
6083 case 0xf3: 6119 case 0xf3: // REV
6084 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); 6120 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6085 return 1; 6121 return 1;
6086 case 0xfb: 6122 case 0xfb: // REV16
6087 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); 6123 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6088 return 1; 6124 return 1;
6089 default: 6125 default:
@@ -6093,7 +6129,7 @@ L_stm_s_takeabort:
6093 if (ror == -1) 6129 if (ror == -1)
6094 break; 6130 break;
6095 6131
6096 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6132 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
6097 if (Rm & 0x8000) 6133 if (Rm & 0x8000)
6098 Rm |= 0xffff0000; 6134 Rm |= 0xffff0000;
6099 6135
@@ -6180,7 +6216,7 @@ L_stm_s_takeabort:
6180 break; 6216 break;
6181 } 6217 }
6182 6218
6183 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6219 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF;
6184 6220
6185 if (BITS(16, 19) == 0xf) 6221 if (BITS(16, 19) == 0xf)
6186 /* UXTB */ 6222 /* UXTB */
@@ -6210,9 +6246,13 @@ L_stm_s_takeabort:
6210 ror = 24; 6246 ror = 24;
6211 break; 6247 break;
6212 6248
6213 case 0xfb: 6249 case 0xfb: // REVSH
6214 printf("Unhandled v6 insn: revsh\n"); 6250 {
6215 return 0; 6251 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6252 if (DEST & 0x8000)
6253 DEST |= 0xffff0000;
6254 return 1;
6255 }
6216 default: 6256 default:
6217 break; 6257 break;
6218 } 6258 }
@@ -6220,13 +6260,13 @@ L_stm_s_takeabort:
6220 if (ror == -1) 6260 if (ror == -1)
6221 break; 6261 break;
6222 6262
6223 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6263 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | ((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF;
6224 6264
6225 /* UXT */ 6265 /* UXT */
6226 /* state->Reg[BITS (12, 15)] = Rm; */ 6266 /* state->Reg[BITS (12, 15)] = Rm; */
6227 /* dyf add */ 6267 /* dyf add */
6228 if (BITS(16, 19) == 0xf) { 6268 if (BITS(16, 19) == 0xf) {
6229 state->Reg[BITS(12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; 6269 state->Reg[BITS(12, 15)] = Rm;
6230 } 6270 }
6231 else { 6271 else {
6232 /* UXTAH */ 6272 /* UXTAH */
@@ -6234,7 +6274,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)] 6274 // 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)); 6275 // , Rm, BITS(10, 11));
6236 // printf("icounter is %lld\n", state->NumInstrs); 6276 // printf("icounter is %lld\n", state->NumInstrs);
6237 state->Reg[BITS(12, 15)] = (state->Reg[BITS(16, 19)] >> (8 * (BITS(10, 11)))) + Rm; 6277 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6238 // printf("rd is %x\n", state->Reg[BITS (12, 15)]); 6278 // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6239 // exit(-1); 6279 // exit(-1);
6240 } 6280 }
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));