Skip to content

Commit 2b23e08

Browse files
committed
Fix PC-relative adds and destination PC of ALU operations
1 parent d6265a7 commit 2b23e08

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

core/arm/armcpu.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ static uint32_t arm_adds(arm_cpu_t *cpu, uint32_t x, uint32_t y) {
273273
return arm_movs(cpu, x);
274274
#else
275275
uint32_t res = x + y;
276-
flags->v = ((res ^ x) & (res ^ y)) >> 31;
277-
flags->c = res < x;
276+
cpu->v = ((res ^ x) & (res ^ y)) >> 31;
277+
cpu->c = res < x;
278278
//int64_t res = (int64_t)(int32_t)x + (int32_t)y;
279279
//cpu->v = res != (int32_t)res;
280280
//cpu->c = (uint32_t)res < x;
@@ -777,13 +777,21 @@ void arm_cpu_execute(arm_t *arm) {
777777
case 1: // Special data instructions and branch and exchange
778778
switch (opc >> 8 & 3) {
779779
case 0: // Add Registers
780-
cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] += cpu->r[opc >> 3 & 0xF];
780+
i = (opc >> 4 & 8) | (opc >> 0 & 7);
781+
cpu->r[i] += cpu->r[opc >> 3 & 0xF];
782+
if (unlikely(i == 15)) {
783+
cpu->pc = (cpu->pc | 1) + 1;
784+
}
781785
break;
782786
case 1: // Compare Registers
783787
arm_subs(cpu, cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)], cpu->r[opc >> 3 & 0xF]);
784788
break;
785789
case 2: // Move Registers
786-
cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] = cpu->r[opc >> 3 & 0xF];
790+
i = (opc >> 4 & 8) | (opc >> 0 & 7);
791+
cpu->r[i] = cpu->r[opc >> 3 & 0xF];
792+
if (unlikely(i == 15)) {
793+
cpu->pc = (cpu->pc | 1) + 1;
794+
}
787795
break;
788796
case 3: // Branch (with Link) and Exchange
789797
val = cpu->r[opc >> 3 & 0xF];
@@ -857,8 +865,8 @@ void arm_cpu_execute(arm_t *arm) {
857865
arm_mem_store_word(arm, cpu->r[opc >> 8 & 7], cpu->sp + ((opc >> 0 & 0xFF) << 2));
858866
}
859867
break;
860-
case 10: // Generate SP/PC
861-
cpu->r[opc >> 8 & 7] = cpu->r[opc >> 11 & 1 ? 13 : 15] + ((opc >> 0 & 0xFF) << 2);
868+
case 10: // Add SP/PC relative
869+
cpu->r[opc >> 8 & 7] = (opc >> 11 & 1 ? cpu->sp : cpu->pc & ~2) + ((opc >> 0 & 0xFF) << 2);
862870
break;
863871
case 11: // Miscellaneous 16-bit instructions
864872
switch (opc >> 9 & 7) {

0 commit comments

Comments
 (0)