aboutsummaryrefslogtreecommitdiff
path: root/sim/erc32/exec.c
diff options
context:
space:
mode:
authorJiri Gaisler <jiri@gaisler.se>2015-04-03 22:35:48 +0200
committerMike Frysinger <vapier@gentoo.org>2015-04-19 02:29:44 -0400
commitd3e9b40afb8e7bd09522044951cdce4710676c3e (patch)
tree23020a66ff49d500c422b506c5891c998089e64b /sim/erc32/exec.c
parent09b29ece9abb652983d4718aac0ff666d62d6790 (diff)
downloadgdb-d3e9b40afb8e7bd09522044951cdce4710676c3e.zip
gdb-d3e9b40afb8e7bd09522044951cdce4710676c3e.tar.gz
gdb-d3e9b40afb8e7bd09522044951cdce4710676c3e.tar.bz2
sim/erc32: Switched emulated memory to host endian order.
Change data ordering in emulated memory from target order (big endian) to host order. Improves performance and simplifies most memory operations. Requires some byte twisting during stores on little endian hosts (intel). Also removed support for little-endian binaries.
Diffstat (limited to 'sim/erc32/exec.c')
-rw-r--r--sim/erc32/exec.c58
1 files changed, 49 insertions, 9 deletions
diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
index e6ce6c5..d31032b 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -370,6 +370,36 @@ div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned)
}
+static int
+extract_short (uint32 data, uint32 address)
+{
+ return ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
+}
+
+static int
+extract_short_signed (uint32 data, uint32 address)
+{
+ uint32 tmp = ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
+ if (tmp & 0x8000)
+ tmp |= 0xffff0000;
+ return tmp;
+}
+
+static int
+extract_byte (uint32 data, uint32 address)
+{
+ return ((data >> ((3 - (address & 3)) * 8)) & 0xff);
+}
+
+static int
+extract_byte_signed (uint32 data, uint32 address)
+{
+ uint32 tmp = ((data >> ((3 - (address & 3)) * 8)) & 0xff);
+ if (tmp & 0x80)
+ tmp |= 0xffffff00;
+ return tmp;
+}
+
int
dispatch_instruction(sregs)
struct pstate *sregs;
@@ -1077,7 +1107,8 @@ dispatch_instruction(sregs)
sregs->trap = TRAP_PRIVI;
break;
}
- sregs->psr = (rs1 ^ operand2) & 0x00f03fff;
+ sregs->psr = (sregs->psr & 0xff000000) |
+ (rs1 ^ operand2) & 0x00f03fff;
break;
case WRWIM:
if (!(sregs->psr & PSR_S)) {
@@ -1213,8 +1244,10 @@ dispatch_instruction(sregs)
else
rdd = &(sregs->g[rd]);
}
- mexc = memory_read(asi, address, ddata, 3, &ws);
- sregs->hold += ws * 2;
+ mexc = memory_read (asi, address, ddata, 2, &ws);
+ sregs->hold += ws;
+ mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
+ sregs->hold += ws;
sregs->icnt = T_LDD;
if (mexc) {
sregs->trap = TRAP_DEXC;
@@ -1252,6 +1285,7 @@ dispatch_instruction(sregs)
sregs->trap = TRAP_DEXC;
break;
}
+ data = extract_byte (data, address);
*rdd = data;
data = 0x0ff;
mexc = memory_write(asi, address, &data, 0, &ws);
@@ -1274,8 +1308,10 @@ dispatch_instruction(sregs)
sregs->trap = TRAP_DEXC;
break;
}
- if ((op3 == LDSB) && (data & 0x80))
- data |= 0xffffff00;
+ if (op3 == LDSB)
+ data = extract_byte_signed (data, address);
+ else
+ data = extract_byte (data, address);
*rdd = data;
break;
case LDSHA:
@@ -1293,8 +1329,10 @@ dispatch_instruction(sregs)
sregs->trap = TRAP_DEXC;
break;
}
- if ((op3 == LDSH) && (data & 0x8000))
- data |= 0xffff0000;
+ if (op3 == LDSH)
+ data = extract_short_signed (data, address);
+ else
+ data = extract_short (data, address);
*rdd = data;
break;
case LDF:
@@ -1337,8 +1375,10 @@ dispatch_instruction(sregs)
((sregs->frs2 >> 1) == (rd >> 1)))
sregs->fhold += (sregs->ftime - ebase.simtime);
}
- mexc = memory_read(asi, address, ddata, 3, &ws);
- sregs->hold += ws * 2;
+ mexc = memory_read (asi, address, ddata, 2, &ws);
+ sregs->hold += ws;
+ mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
+ sregs->hold += ws;
sregs->icnt = T_LDD;
if (mexc) {
sregs->trap = TRAP_DEXC;