summaryrefslogtreecommitdiff
path: root/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
diff options
context:
space:
mode:
Diffstat (limited to 'tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch')
-rw-r--r--tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch564
1 files changed, 564 insertions, 0 deletions
diff --git a/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
new file mode 100644
index 0000000..04f5e90
--- /dev/null
+++ b/tools/4.11/gdb/sparc/7.9/0010-sim-erc32-Switched-emulated-memory-to-host-endian-or.patch
@@ -0,0 +1,564 @@
+From 335799e56181cd0d1ff8128b20b01835e344ee43 Mon Sep 17 00:00:00 2001
+From: Jiri Gaisler <jiri@gaisler.se>
+Date: Sat, 30 Aug 2014 23:39:33 +0200
+Subject: [PATCH 10/23] 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).
+
+ * erc32.c (fetch_bytes) Remove. (store_bytes) Remove byte twisting.
+ (memory_read) Access memory directly. (extract_short,
+ extract_short_signed, extract_byte, extract_byte_signed) New
+ function for for sub-word LD instructions.
+
+ * func.c (disp_ctrl, dis_mem) Ajust print-out to new data endian.
+
+ * interf.c (sim_open) Convert endian when gdb writes to memory.
+---
+ sim/erc32/erc32.c | 167 ++++++++++++-----------------------------------------
+ sim/erc32/exec.c | 58 ++++++++++++++++---
+ sim/erc32/func.c | 33 +++++++----
+ sim/erc32/interf.c | 29 ++++++++++
+ sim/erc32/sis.c | 4 ++
+ 5 files changed, 142 insertions(+), 149 deletions(-)
+
+diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
+index 0f3e870..7c80e13 100644
+--- a/sim/erc32/erc32.c
++++ b/sim/erc32/erc32.c
+@@ -297,11 +297,8 @@ static void gpt_reload_set (uint32 val);
+ static void timer_ctrl (uint32 val);
+ static unsigned char *
+ get_mem_ptr (uint32 addr, uint32 size);
+-
+-static void fetch_bytes (int asi, unsigned char *mem,
+- uint32 *data, int sz);
+-
+-static void store_bytes (unsigned char *mem, uint32 *data, int sz);
++static void store_bytes (unsigned char *mem, uint32 waddr,
++ uint32 *data, int sz, int32 *ws);
+
+ extern int ext_irl;
+
+@@ -1525,123 +1522,44 @@ timer_ctrl(val)
+ gpt_start();
+ }
+
+-
+-/* Retrieve data from target memory. MEM points to location from which
+- to read the data; DATA points to words where retrieved data will be
+- stored in host byte order. SZ contains log(2) of the number of bytes
+- to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word),
+- or 3 (two words). */
++/* Store data in host byte order. MEM points to the beginning of the
++ emulated memory; WADDR contains the index the emulated memory,
++ DATA points to words in host byte order to be stored. SZ contains log(2)
++ of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
++ 2 (one word), or 3 (two words); WS should return the number of wait-states. */
+
+ static void
+-fetch_bytes (asi, mem, data, sz)
+- int asi;
++store_bytes (mem, waddr, data, sz, ws)
+ unsigned char *mem;
++ uint32 waddr;
+ uint32 *data;
+- int sz;
++ int32 sz;
++ int32 *ws;
+ {
+- if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
+- || asi == 8 || asi == 9) {
+- switch (sz) {
+- case 3:
+- data[1] = (((uint32) mem[7]) & 0xff) |
+- ((((uint32) mem[6]) & 0xff) << 8) |
+- ((((uint32) mem[5]) & 0xff) << 16) |
+- ((((uint32) mem[4]) & 0xff) << 24);
+- /* Fall through to 2 */
+- case 2:
+- data[0] = (((uint32) mem[3]) & 0xff) |
+- ((((uint32) mem[2]) & 0xff) << 8) |
+- ((((uint32) mem[1]) & 0xff) << 16) |
+- ((((uint32) mem[0]) & 0xff) << 24);
+- break;
+- case 1:
+- data[0] = (((uint32) mem[1]) & 0xff) |
+- ((((uint32) mem[0]) & 0xff) << 8);
+- break;
++ switch (sz) {
+ case 0:
+- data[0] = mem[0] & 0xff;
+- break;
+-
+- }
+- } else {
+- switch (sz) {
+- case 3:
+- data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
+- ((((uint32) mem[6]) & 0xff) << 16) |
+- ((((uint32) mem[5]) & 0xff) << 8) |
+- (((uint32) mem[4]) & 0xff);
+- /* Fall through to 4 */
+- case 2:
+- data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
+- ((((uint32) mem[2]) & 0xff) << 16) |
+- ((((uint32) mem[1]) & 0xff) << 8) |
+- (((uint32) mem[0]) & 0xff);
++#ifdef HOST_LITTLE_ENDIAN
++ waddr ^= 3;
++#endif
++ mem[waddr] = *data & 0x0ff;
++ *ws = mem_ramw_ws + 3;
+ break;
+ case 1:
+- data[0] = ((((uint32) mem[1]) & 0xff) << 8) |
+- (((uint32) mem[0]) & 0xff);
+- break;
+- case 0:
+- data[0] = mem[0] & 0xff;
++#ifdef HOST_LITTLE_ENDIAN
++ waddr ^= 2;
++#endif
++ *((unsigned short *) &(mem[waddr])) = *data & 0x0ffff;
++ *ws = mem_ramw_ws + 3;
+ break;
+- }
+- }
+-}
+-
+-
+-/* Store data in target byte order. MEM points to location to store data;
+- DATA points to words in host byte order to be stored. SZ contains log(2)
+- of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
+- 2 (one word), or 3 (two words). */
+-
+-static void
+-store_bytes (mem, data, sz)
+- unsigned char *mem;
+- uint32 *data;
+- int sz;
+-{
+- if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
+- switch (sz) {
+- case 3:
+- mem[7] = (data[1] >> 24) & 0xff;
+- mem[6] = (data[1] >> 16) & 0xff;
+- mem[5] = (data[1] >> 8) & 0xff;
+- mem[4] = data[1] & 0xff;
+- /* Fall through to 2 */
+ case 2:
+- mem[3] = (data[0] >> 24) & 0xff;
+- mem[2] = (data[0] >> 16) & 0xff;
+- /* Fall through to 1 */
+- case 1:
+- mem[1] = (data[0] >> 8) & 0xff;
+- /* Fall through to 0 */
+- case 0:
+- mem[0] = data[0] & 0xff;
++ *((uint32 *) &(mem[waddr])) = *data;
++ *ws = mem_ramw_ws;
+ break;
+- }
+- } else {
+- switch (sz) {
+ case 3:
+- mem[7] = data[1] & 0xff;
+- mem[6] = (data[1] >> 8) & 0xff;
+- mem[5] = (data[1] >> 16) & 0xff;
+- mem[4] = (data[1] >> 24) & 0xff;
+- /* Fall through to 2 */
+- case 2:
+- mem[3] = data[0] & 0xff;
+- mem[2] = (data[0] >> 8) & 0xff;
+- mem[1] = (data[0] >> 16) & 0xff;
+- mem[0] = (data[0] >> 24) & 0xff;
+- break;
+- case 1:
+- mem[1] = data[0] & 0xff;
+- mem[0] = (data[0] >> 8) & 0xff;
+- break;
+- case 0:
+- mem[0] = data[0] & 0xff;
++ *((uint32 *) &(mem[waddr])) = data[0];
++ *((uint32 *) &(mem[waddr + 4])) = data[1];
++ *ws = 2 * mem_ramw_ws + STD_WS;
+ break;
+-
+- }
+ }
+ }
+
+@@ -1671,7 +1589,7 @@ memory_read(asi, addr, data, sz, ws)
+ #endif
+
+ if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
+- fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
++ *data = *((uint32 *) & (ramb[addr & mem_rammask & ~3]));
+ *ws = mem_ramr_ws;
+ return (0);
+ } else if ((addr >= MEC_START) && (addr < MEC_END)) {
+@@ -1689,7 +1607,7 @@ memory_read(asi, addr, data, sz, ws)
+ } else if (era) {
+ if ((addr < 0x100000) ||
+ ((addr>= 0x80000000) && (addr < 0x80100000))) {
+- fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
++ *data = *((uint32 *) & (romb[addr & ROM_MASK & ~3]));
+ *ws = 4;
+ return (0);
+ } else if ((addr >= 0x10000000) &&
+@@ -1700,13 +1618,13 @@ memory_read(asi, addr, data, sz, ws)
+ }
+
+ } else if (addr < mem_romsz) {
+- fetch_bytes (asi, &romb[addr], data, sz);
++ *data = *((uint32 *) & (romb[addr & ~3]));
+ *ws = mem_romr_ws;
+ return (0);
+
+ #else
+ } else if (addr < mem_romsz) {
+- fetch_bytes (asi, &romb[addr], data, sz);
++ *data = *((uint32 *) & (romb[addr & ~3]));
+ *ws = mem_romr_ws;
+ return (0);
+ #endif
+@@ -1769,21 +1687,10 @@ memory_write(asi, addr, data, sz, ws)
+ }
+ }
+
+- store_bytes (&ramb[addr & mem_rammask], data, sz);
+-
+- switch (sz) {
+- case 0:
+- case 1:
+- *ws = mem_ramw_ws + 3;
+- break;
+- case 2:
+- *ws = mem_ramw_ws;
+- break;
+- case 3:
+- *ws = 2 * mem_ramw_ws + STD_WS;
+- break;
+- }
++ waddr = addr & mem_rammask;
++ store_bytes (ramb, waddr, data, sz, ws);
+ return (0);
++
+ } else if ((addr >= MEC_START) && (addr < MEC_END)) {
+ if ((sz != 2) || (asi != 0xb)) {
+ set_sfsr(MEC_ACC, addr, asi, 0);
+@@ -1806,7 +1713,7 @@ memory_write(asi, addr, data, sz, ws)
+ ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
+ addr &= ROM_MASK;
+ *ws = sz == 3 ? 8 : 4;
+- store_bytes (&romb[addr], data, sz);
++ store_bytes (romb, addr, data, sz, ws);
+ return (0);
+ } else if ((addr >= 0x10000000) &&
+ (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
+@@ -1822,7 +1729,7 @@ memory_write(asi, addr, data, sz, ws)
+ *ws = mem_romw_ws + 1;
+ if (sz == 3)
+ *ws += mem_romw_ws + STD_WS;
+- store_bytes (&romb[addr], data, sz);
++ store_bytes (romb, addr, data, sz, ws);
+ return (0);
+
+ #else
+@@ -1833,7 +1740,7 @@ memory_write(asi, addr, data, sz, ws)
+ *ws = mem_romw_ws + 1;
+ if (sz == 3)
+ *ws += mem_romw_ws + STD_WS;
+- store_bytes (&romb[addr], data, sz);
++ store_bytes (romb, addr, data, sz, ws);
+ return (0);
+
+ #endif
+diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
+index 07f3586..e80e02a 100644
+--- a/sim/erc32/exec.c
++++ b/sim/erc32/exec.c
+@@ -371,6 +371,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;
++ 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;
++ tmp = ((data>>((3 - (address & 3))*8)) & 0xff);
++ if (tmp & 0x80) tmp |= 0xffffff00;
++ return(tmp);
++}
++
+ int
+ dispatch_instruction(sregs)
+ struct pstate *sregs;
+@@ -1078,7 +1108,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)) {
+@@ -1214,8 +1245,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;
+@@ -1253,6 +1286,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);
+@@ -1275,8 +1309,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:
+@@ -1294,8 +1330,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:
+@@ -1338,8 +1376,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;
+diff --git a/sim/erc32/func.c b/sim/erc32/func.c
+index a715f0f..bcccf6d 100644
+--- a/sim/erc32/func.c
++++ b/sim/erc32/func.c
+@@ -785,15 +785,15 @@ disp_ctrl(sregs)
+ struct pstate *sregs;
+ {
+
+- unsigned char i[4];
++ uint32 i;
+
+ printf("\n psr: %08X wim: %08X tbr: %08X y: %08X\n",
+ sregs->psr, sregs->wim, sregs->tbr, sregs->y);
+- sis_memory_read(sregs->pc, i, 4);
+- printf("\n pc: %08X = %02X%02X%02X%02X ", sregs->pc,i[0],i[1],i[2],i[3]);
++ sis_memory_read(sregs->pc, (char *) &i, 4);
++ printf("\n pc: %08X = %08X ", sregs->pc, i);
+ print_insn_sparc_sis(sregs->pc, &dinfo);
+- sis_memory_read(sregs->npc, i, 4);
+- printf("\n npc: %08X = %02X%02X%02X%02X ",sregs->npc,i[0],i[1],i[2],i[3]);
++ sis_memory_read(sregs->npc, (char *) &i, 4);
++ printf("\n npc: %08X = %08X ", sregs->npc, i);
+ print_insn_sparc_sis(sregs->npc, &dinfo);
+ if (sregs->err_mode)
+ printf("\n IU in error mode");
+@@ -808,21 +808,28 @@ disp_mem(addr, len)
+
+ uint32 i;
+ unsigned char data[4];
++ uint32 *wdata = (uint32 *) data;
+ uint32 mem[4], j;
+ char *p;
++ int end;
+
++#ifdef HOST_LITTLE_ENDIAN
++ end = 3;
++#else
++ end = 0;
++#endif
+ for (i = addr & ~3; i < ((addr + len) & ~3); i += 16) {
+ printf("\n %8X ", i);
+ for (j = 0; j < 4; j++) {
+ sis_memory_read((i + (j * 4)), data, 4);
+- printf("%02x%02x%02x%02x ", data[0],data[1],data[2],data[3]);
++ printf("%08x ", *wdata);
+ mem[j] = *((int *) &data);
+ }
+ printf(" ");
+ p = (char *) mem;
+ for (j = 0; j < 16; j++) {
+- if (isprint(p[j]))
+- putchar(p[j]);
++ if (isprint(p[j^end]))
++ putchar(p[j^end]);
+ else
+ putchar('.');
+ }
+@@ -838,10 +845,11 @@ dis_mem(addr, len, info)
+ {
+ uint32 i;
+ unsigned char data[4];
++ uint32 *wdata = (uint32 *) data;
+
+ for (i = addr & -3; i < ((addr & -3) + (len << 2)); i += 4) {
+ sis_memory_read(i, data, 4);
+- printf(" %08x %02x%02x%02x%02x ", i, data[0],data[1],data[2],data[3]);
++ printf(" %08x %08x ", i, *wdata);
+ print_insn_sparc_sis(i, info);
+ if (i >= 0xfffffffc) break;
+ printf("\n");
+@@ -1040,6 +1048,7 @@ bfd_load(fname)
+ asection *section;
+ bfd *pbfd;
+ const bfd_arch_info_type *arch;
++ int i;
+
+ pbfd = bfd_openr(fname, 0);
+
+@@ -1113,13 +1122,17 @@ bfd_load(fname)
+ fptr = 0;
+
+ while (section_size > 0) {
+- char buffer[1024];
+ int count;
++ char buffer[1024];
++ uint32 *wbuffer = (uint32 *) buffer;
+
+ count = min(section_size, 1024);
+
+ bfd_get_section_contents(pbfd, section, buffer, fptr, count);
+
++#ifdef HOST_LITTLE_ENDIAN
++ for (i=0;i<count/4;i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
++#endif
+ sis_memory_write(section_address, buffer, count);
+
+ section_address += count;
+diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
+index 38a2a0d..3a72e7f 100644
+--- a/sim/erc32/interf.c
++++ b/sim/erc32/interf.c
+@@ -265,7 +265,11 @@ sim_open (kind, callback, abfd, argv)
+ sregs.freq = freq ? freq : 15;
+ termsave = fcntl(0, F_GETFL, 0);
+ INIT_DISASSEMBLE_INFO(dinfo, stdout,(fprintf_ftype)fprintf);
++#ifdef HOST_LITTLE_ENDIAN
++ dinfo.endian = BFD_ENDIAN_LITTLE;
++#else
+ dinfo.endian = BFD_ENDIAN_BIG;
++#endif
+ reset_all();
+ ebase.simtime = 0;
+ init_sim();
+@@ -355,7 +359,19 @@ sim_write(sd, mem, buf, length)
+ const unsigned char *buf;
+ int length;
+ {
++#ifdef HOST_LITTLE_ENDIAN
++ int *ibufp = (int *) buf;
++ int ibuf[8192];
++ int i, len;
++
++ if (length >= 4)
++ for (i=0; i<length; i+=4) {
++ ibuf[i] = ntohl(ibufp[i]);
++ }
++ return (sis_memory_write(mem, (char *) ibuf, length));
++#else
+ return (sis_memory_write(mem, buf, length));
++#endif
+ }
+
+ int
+@@ -365,7 +381,20 @@ sim_read(sd, mem, buf, length)
+ unsigned char *buf;
+ int length;
+ {
++#ifdef HOST_LITTLE_ENDIAN
++ int *ibuf = (int *) buf;
++ int i, len;
++
++ len = sis_memory_read(mem, buf, length);
++ if (length >= 4)
++ for (i=0; i<length; i+=4) {
++ *ibuf = htonl(*ibuf);
++ ibuf++;
++ }
++ return (len);
++#else
+ return (sis_memory_read(mem, buf, length));
++#endif
+ }
+
+ void
+diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
+index 7c18c1e..523d8aa 100644
+--- a/sim/erc32/sis.c
++++ b/sim/erc32/sis.c
+@@ -236,7 +236,11 @@ main(argc, argv)
+ sregs.freq = freq;
+
+ INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
++#ifdef HOST_LITTLE_ENDIAN
++ dinfo.endian = BFD_ENDIAN_LITTLE;
++#else
+ dinfo.endian = BFD_ENDIAN_BIG;
++#endif
+
+ termsave = fcntl(0, F_GETFL, 0);
+ using_history();
+--
+1.9.1
+