Author: wmb Date: Wed Aug 31 03:12:52 2011 New Revision: 2487 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2487
Log: ARM simulator - implemented smull and umull instructions. There is still a problem lurking, as "m*" fails on certain numbers when arm4? is false. An example failure is "false to arm4? decimal 1,000,000,000 -5 m* d.". The carry out into the high word doesn't happen.
Modified: cpu/arm/armsim.c
Modified: cpu/arm/armsim.c ============================================================================== --- cpu/arm/armsim.c Mon Aug 29 03:46:46 2011 (r2486) +++ cpu/arm/armsim.c Wed Aug 31 03:12:52 2011 (r2487) @@ -447,6 +447,18 @@ } switch (BXTYPE) { // P=0, U=1, bit22=0, W=0 - post-index, subtract offset, register, no writeback + case 0x9: INSTR("umull"); + { unsigned long long result; + result = (unsigned long long)RM * (unsigned long long)RS; + RN = (u32)((result >> 32) & 0xffffffffLL); + RD = (u32)(result & 0xffffffffLL); + if (S) { + N = (result < 0); + Z = (result == 0); + } + } + break; + case 0xb: if (L) { INSTR("ldrh"); @@ -487,7 +499,8 @@ case 0xf: UNIMP("ldrsh"); break; // UNPREDICTABLE default: UNIMP("BXTYPE"); break; } break; -case 0x06: if (OP1 == 0 || OP2 == 0) { +case 0x06: + if (OP1 == 0 || OP2 == 0) { INSTR("sbc"); SHFT(res); // printf("sbc RN %x res %x ~res %x C %x -- ", RN, res, ~(res), C); // ADC(RD, RN, ~(res), C); @@ -502,7 +515,19 @@ case 0x3: case 0x5: case 0x7: INSTR("sbc"); SHFT(res); SBB(RD, res, RN, C); break; - case 0x9: UNIMP("smull"); break; + case 0x9: INSTR("smull"); + { long long result, a, b; + a = (int)RM; + b = (int)RS; + result = a * b; + RN = (u32)((result >> 32) & 0xffffffffLL); + RD = (u32)(result & 0xffffffffLL); + if (S) { + N = (result < 0); + Z = (result == 0); + } + } + break; // P=0, U=1, bit22=1, W=0 - post-index, subtract offset, immediate, no writeback case 0xb: if (L) {
openfirmware@openfirmware.info