@@ -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