Hi,

I've found a few bugs in the M5 ARM implementation.
Here are some fixes for the latest (06/23/09) development version.

macromem-fix - added unimplemented load/store multiple instructions.

lr-fix       - the link register is incorrectly overwritten by
   non-executed branch and link operations, e.g. "blne"
   when "Z = 1".

longmul-loads - long (64bit) multiplication instructions should
   ensure that only 32 bits of the input registers are
   actually used; added some unimplemented load instructions

Also attached: 

tc.tar.gz    - a test case that fails if the above fixes are not in place.
   It prints "Tests passed" on success. I successfully ran the program on 
   a real ARM system and also on QEMU's ARM simulator - it passes in both
   cases.  
   


I may also have found a bug in src/arch/arm/linux/linux.hh;
it seems that some of the flags named TGT_O_RDONLY ... TGT_O_NOATIME
don't match the values defined in my kernel headers. This affects 
some common operations such as creating a file with fopen. However, I 
hesitate to propose a fix: perhaps I am simply using the wrong C library 
or Linux kernel.

I used an execution trace comparison with QEMU to detect the above bugs.
This requires some quite invasive modifications to QEMU, since unlike M5
it does not produce a useful execution trace "out of the box". If you 
would be interested in a patch for QEMU, please let me know.


-- 
Jack Whitham
[email protected]

diff -rU2 m5/src/arch/arm/isa/formats/macromem.isa 
m5mod/src/arch/arm/isa/formats/macromem.isa
--- m5/src/arch/arm/isa/formats/macromem.isa    2009-06-23 16:20:36.000000000 
+0100
+++ m5mod/src/arch/arm/isa/formats/macromem.isa 2009-06-23 16:18:48.000000000 
+0100
@@ -59,8 +59,7 @@
     switch (puswl)
     {
+        case 0x00: //       stmda
         case 0x01: //     L ldmda_l
-            start_addr = (ones << 2) - 4;
-            end_addr = 0;
-            break;
+        case 0x02: //    W  stmda_w
         case 0x03: //    WL ldmda_wl
             start_addr = (ones << 2) - 4;
@@ -68,33 +67,27 @@
             break;
         case 0x08: //  U    stmia_u
-            start_addr = 0;
-            end_addr = (ones << 2) - 4;
-            break;
         case 0x09: //  U  L ldmia_ul
-            start_addr = 0;
-            end_addr = (ones << 2) - 4;
-            break;
+        case 0x0a: //  U W  stmia
         case 0x0b: //  U WL ldmia
             start_addr = 0;
             end_addr = (ones << 2) - 4;
             break;
+        case 0x10: // P     stmdb
         case 0x11: // P   L ldmdb
-            start_addr = (ones << 2); // U-bit is already 0 for subtract
-            end_addr = 4; // negative 4
-            break;
         case 0x12: // P  W  stmdb
+        case 0x13: // P  WL ldmdb
             start_addr = (ones << 2); // U-bit is already 0 for subtract
             end_addr = 4; // negative 4
             break;
         case 0x18: // PU    stmib
-            start_addr = 4;
-            end_addr = (ones << 2) + 4;
-            break;
         case 0x19: // PU  L ldmib
+        case 0x1a: // PU W  stmib
+        case 0x1b: // PU WL ldmib
             start_addr = 4;
             end_addr = (ones << 2) + 4;
             break;
         default:
-            panic("Unhandled Load/Store Multiple Instruction");
+            panic("Unhandled Load/Store Multiple Instruction, "
+                "puswl = 0x%x", (unsigned) puswl);
             break;
     }
Only in m5mod/src/arch/arm/isa/formats: macromem.isa.orig
Only in m5mod/src/arch/arm/isa/formats: macromem.isa.rej
Only in m5mod/src/arch/arm/isa/formats: util.isa.orig
Only in m5/src: ftr.hh
Binary files m5/util/style.pyc and m5mod/util/style.pyc differ
diff -rU2 m5/src/arch/arm/isa/formats/branch.isa 
m5mod/src/arch/arm/isa/formats/branch.isa
--- m5/src/arch/arm/isa/formats/branch.isa      2009-06-23 16:20:36.000000000 
+0100
+++ m5mod/src/arch/arm/isa/formats/branch.isa   2009-06-23 16:19:21.000000000 
+0100
@@ -56,4 +56,5 @@
     icode += '} else {\n'
     icode += '  NPC = NPC;\n'
+    icode += '  LR = LR;\n'
     icode += '};\n'
 
@@ -90,4 +91,5 @@
     icode += '} else {\n'
     icode += '  NPC = NPC;\n'
+    icode += '  LR = LR;\n'
     icode += '};\n'
 
diff -rU2 m5/src/arch/arm/isa/decoder.isa m5mod/src/arch/arm/isa/decoder.isa
--- m5/src/arch/arm/isa/decoder.isa     2009-06-23 16:20:36.000000000 +0100
+++ m5mod/src/arch/arm/isa/decoder.isa  2009-06-23 16:16:01.000000000 +0100
@@ -376,5 +376,6 @@
                             0x8: umull_l({{
                                 uint64_t resTemp;
-                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
+                                resTemp = ((uint64_t)((uint32_t)Rm))*
+                                        ((uint64_t)((uint32_t)Rs));
                                 Rd = (uint32_t)(resTemp & 0xffffffff);
                                 Rn = (uint32_t)(resTemp >> 32);
@@ -382,5 +383,6 @@
                             0xa: umlal_lu({{
                                 uint64_t resTemp;
-                                resTemp = ((uint64_t)Rm)*((uint64_t)Rs);
+                                resTemp = ((uint64_t)((uint32_t)Rm))*
+                                        ((uint64_t)((uint32_t)Rs));
                                 resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd);
                                 Rd = (uint32_t)(resTemp & 0xffffffff);
@@ -389,5 +391,6 @@
                             0xc: smull_lu({{
                                 int64_t resTemp;
-                                resTemp = ((int64_t)Rm)*((int64_t)Rs);
+                                resTemp = ((int64_t)((int32_t)Rm))*
+                                        ((int64_t)((int32_t)Rs));
                                 Rd = (int32_t)(resTemp & 0xffffffff);
                                 Rn = (int32_t)(resTemp >> 32);
@@ -397,4 +400,7 @@
                     }
                     0x1: decode PUIWL {
+                        0x01,0x09: ArmLoadMemory::ldrh_l({{ Rd.uh = Mem.uh;
+                                                          Rn = Rn + Rm; }},
+                                                        {{ EA = Rn; }});
                         0x04,0x0c: ArmStoreMemory::strh_i({{ Mem.uh = Rd.uh;
                                                           Rn = Rn + hilo; }},
@@ -426,4 +432,7 @@
                     0x2: decode PUIWL {
                         format ArmLoadMemory {
+                            0x05,0x0d: ldrsb_il({{ Rd.sb = Mem.sb; 
+                                                    Rn = Rn + hilo; }},
+                                                {{ EA = Rn; }});
                             0x11,0x19: ldrsb_pl({{ Rd.sb = Mem.sb; }},
                                                 {{ EA = Rn + Rm; }});
@@ -440,4 +449,7 @@
                     0x3: decode PUIWL {
                         format ArmLoadMemory {
+                            0x05,0x0d: ldrsh_il({{ Rd.sh = Mem.sh; 
+                                                    Rn = Rn + hilo; }},
+                                                {{ EA = Rn; }});
                             0x11,0x19: ldrsh_pl({{ Rd.sh = Mem.sh; }},
                                                 {{ EA = Rn + Rm; }});
@@ -584,12 +596,12 @@
                                                Rn = Rn + disp; }},
                                             {{ EA = Rn; }});
-            0x01,0x09: ArmLoadMemory::ldr_l({{ Rd = Mem;
-                                               Rn = Rn + disp; }},
+            0x01,0x09: ArmLoadMemory::ldr_l({{ Rn = Rn + disp; 
+                                               Rd = Mem; }},
                                             {{ EA = Rn; }});
             0x04,0x0c: ArmStoreMemory::strb_b({{ Mem.ub = Rd.ub;
                                                  Rn = Rn + disp; }},
                                               {{ EA = Rn; }});
-            0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rd.ub = Mem.ub;
-                                                 Rn = Rn + disp; }},
+            0x05,0x0d: ArmLoadMemory::ldrb_bl({{ Rn = Rn + disp; 
+                                                 Rd.ub = Mem.ub; }},
                                               {{ EA = Rn; }});
             // Pre-indexed variants
@@ -598,12 +610,12 @@
             0x12,0x1a: ArmStoreMemory::str_pw({{ Mem = Rd;
                                                  Rn = Rn + disp; }});
-            0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rd = Mem;
-                                                 Rn = Rn + disp; }});
+            0x13,0x1b: ArmLoadMemory::ldr_pwl({{ Rn = Rn + disp; 
+                                                 Rd = Mem; }});
             0x14,0x1c: ArmStoreMemory::strb_pb({{ Mem.ub = Rd.ub; }});
             0x15,0x1d: ArmLoadMemory::ldrb_pbl({{ Rd.ub = Mem.ub; }});
             0x16,0x1e: ArmStoreMemory::strb_pbw({{ Mem.ub = Rd.ub;
                                                    Rn = Rn + disp; }});
-            0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rd.ub = Mem.ub;
-                                                   Rn = Rn + disp; }});
+            0x17,0x1f: ArmLoadMemory::ldrb_pbwl({{ Rn = Rn + disp; 
+                                                   Rd.ub = Mem.ub; }});
         }
         0x3: decode OPCODE_4 {

Attachment: tc.tar.gz
Description: application/tar-gz

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to