[openfirmware] [commit] r2487 - cpu/arm

repository service svn at openfirmware.info
Wed Aug 31 03:12:52 CEST 2011


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) {



More information about the openfirmware mailing list