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 {
tc.tar.gz
Description: application/tar-gz
_______________________________________________ m5-dev mailing list [email protected] http://m5sim.org/mailman/listinfo/m5-dev
