From d3e9b40afb8e7bd09522044951cdce4710676c3e Mon Sep 17 00:00:00 2001 From: Jiri Gaisler Date: Fri, 3 Apr 2015 22:35:48 +0200 Subject: 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. --- sim/erc32/exec.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 9 deletions(-) (limited to 'sim/erc32/exec.c') 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; -- cgit v1.1