From 09ba9099c1562c4af1e2f624b9aa2692e563118b Mon Sep 17 00:00:00 2001 From: Jiri Gaisler Date: Sat, 29 Feb 2020 11:07:13 +0100 Subject: Fix incorrect operation on big-endian hosts --- elf.c | 74 ++++++++++++----------- erc32.c | 12 ++-- func.c | 6 +- interf.c | 4 +- leon2.c | 12 ++-- leon3.c | 6 +- riscv.c | 200 +++++++++++++++++++++++++++++++++++++-------------------------- sis.h | 4 +- sparc.c | 10 +++- 9 files changed, 187 insertions(+), 141 deletions(-) diff --git a/elf.c b/elf.c index 96db266..f1d0a37 100644 --- a/elf.c +++ b/elf.c @@ -37,7 +37,7 @@ struct elf_file char *strtab; int arch; int cpu; - int be; + int bswap; }; static struct elf_file efile; @@ -59,19 +59,25 @@ read_elf_header (FILE * fp) { return (-1); } - +#ifdef HOST_LITTLE_ENDIAN if (ehdr.e_ident[EI_DATA] == ELFDATA2MSB) +#else + if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB) +#endif + { + efile.bswap = 1; + } + if (efile.bswap) { - efile.be = 1; - ehdr.e_entry = ntohl (ehdr.e_entry); - ehdr.e_shoff = ntohl (ehdr.e_shoff); - ehdr.e_phoff = ntohl (ehdr.e_phoff); - ehdr.e_phnum = ntohs (ehdr.e_phnum); - ehdr.e_shnum = ntohs (ehdr.e_shnum); - ehdr.e_phentsize = ntohs (ehdr.e_phentsize); - ehdr.e_shentsize = ntohs (ehdr.e_shentsize); - ehdr.e_shstrndx = ntohs (ehdr.e_shstrndx); - ehdr.e_machine = ntohs (ehdr.e_machine); + ehdr.e_entry = SWAP_UINT32 (ehdr.e_entry); + ehdr.e_shoff = SWAP_UINT32 (ehdr.e_shoff); + ehdr.e_phoff = SWAP_UINT32 (ehdr.e_phoff); + ehdr.e_phnum = SWAP_UINT16 (ehdr.e_phnum); + ehdr.e_shnum = SWAP_UINT16 (ehdr.e_shnum); + ehdr.e_phentsize = SWAP_UINT16 (ehdr.e_phentsize); + ehdr.e_shentsize = SWAP_UINT16 (ehdr.e_shentsize); + ehdr.e_shstrndx = SWAP_UINT16 (ehdr.e_shstrndx); + ehdr.e_machine = SWAP_UINT16 (ehdr.e_machine); } switch (ehdr.e_machine) @@ -112,7 +118,7 @@ read_elf_body () char *strtab; char *mem; uint32 *memw, i, j, k, vaddr; - int be = efile.be; + int bswap = efile.bswap; FILE *fp = efile.fp; fseek (fp, ehdr.e_shoff + ((ehdr.e_shstrndx) * ehdr.e_shentsize), SEEK_SET); @@ -122,12 +128,12 @@ read_elf_body () } /* endian swap if big-endian target */ - if (be) + if (bswap) { - ssh.sh_name = ntohl (ssh.sh_name); - ssh.sh_type = ntohl (ssh.sh_type); - ssh.sh_offset = ntohl (ssh.sh_offset); - ssh.sh_size = ntohl (ssh.sh_size); + ssh.sh_name = SWAP_UINT32 (ssh.sh_name); + ssh.sh_type = SWAP_UINT32 (ssh.sh_type); + ssh.sh_offset = SWAP_UINT32 (ssh.sh_offset); + ssh.sh_size = SWAP_UINT32 (ssh.sh_size); } strtab = (char *) malloc (ssh.sh_size); fseek (fp, ssh.sh_offset, SEEK_SET); @@ -143,14 +149,14 @@ read_elf_body () { return (-1); } - if (be) + if (bswap) { - ph[i].p_type = ntohl (ph[i].p_type); - ph[i].p_offset = ntohl (ph[i].p_offset); - ph[i].p_vaddr = ntohl (ph[i].p_vaddr); - ph[i].p_paddr = ntohl (ph[i].p_paddr); - ph[i].p_filesz = ntohl (ph[i].p_filesz); - ph[i].p_memsz = ntohl (ph[i].p_memsz); + ph[i].p_type = SWAP_UINT32 (ph[i].p_type); + ph[i].p_offset = SWAP_UINT32 (ph[i].p_offset); + ph[i].p_vaddr = SWAP_UINT32 (ph[i].p_vaddr); + ph[i].p_paddr = SWAP_UINT32 (ph[i].p_paddr); + ph[i].p_filesz = SWAP_UINT32 (ph[i].p_filesz); + ph[i].p_memsz = SWAP_UINT32 (ph[i].p_memsz); } } @@ -161,14 +167,14 @@ read_elf_body () { return (-1); } - if (be) + if (bswap) { - sh.sh_name = ntohl (sh.sh_name); - sh.sh_addr = ntohl (sh.sh_addr); - sh.sh_size = ntohl (sh.sh_size); - sh.sh_type = ntohl (sh.sh_type); - sh.sh_offset = ntohl (sh.sh_offset); - sh.sh_flags = ntohl (sh.sh_flags); + sh.sh_name = SWAP_UINT32 (sh.sh_name); + sh.sh_addr = SWAP_UINT32 (sh.sh_addr); + sh.sh_size = SWAP_UINT32 (sh.sh_size); + sh.sh_type = SWAP_UINT32 (sh.sh_type); + sh.sh_offset = SWAP_UINT32 (sh.sh_offset); + sh.sh_flags = SWAP_UINT32 (sh.sh_flags); } if ((sh.sh_type != SHT_NOBITS) && (sh.sh_size) @@ -201,9 +207,9 @@ read_elf_body () return (-1); } memw = (unsigned int *) mem; - if (be) + if (bswap) for (j = 0; j < (sh.sh_size) / 4 + 1; j++) - memw[j] = ntohl (memw[j]); + memw[j] = SWAP_UINT32 (memw[j]); ms->sis_memory_write (sh.sh_addr, mem, (sh.sh_size / 4 + 1) * 4); } diff --git a/erc32.c b/erc32.c index 3a7899d..dd86907 100644 --- a/erc32.c +++ b/erc32.c @@ -16,12 +16,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifdef WORDS_BIGENDIAN -#define EBT 0 -#else -#define EBT 3 -#endif - #define ROM_START 0 #define RAM_START 0x02000000 @@ -1620,7 +1614,9 @@ store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws) switch (sz) { case 0: - waddr ^= EBT; +#ifdef HOST_LITTLE_ENDIAN + waddr ^= 3; +#endif mem[waddr] = *data & 0x0ff; *ws = mem_ramw_ws + 3; break; @@ -1628,7 +1624,7 @@ store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws) #ifdef HOST_LITTLE_ENDIAN waddr ^= 2; #endif - memcpy (&mem[waddr], data, 2); + *((uint16 *) & mem[waddr]) = *data & 0x0ffff; *ws = mem_ramw_ws + 3; break; case 2: diff --git a/func.c b/func.c index e9ae888..23bc31a 100644 --- a/func.c +++ b/func.c @@ -890,8 +890,8 @@ disp_mem (addr, len) p = (char *) mem; for (j = 0; j < 16; j++) { - if (isprint (p[j ^ arch->endian])) - putchar (p[j ^ arch->endian]); + if (isprint (p[j ^ arch->bswap])) + putchar (p[j ^ arch->bswap]); else putchar ('.'); } @@ -1566,7 +1566,7 @@ mygetline (char **lineptr, size_t * n, FILE * stream) #define COV_BT 8 #define COV_BNT 16 -unsigned char covram[0x01000000 / 4]; +unsigned char covram[RAM_SIZE / 4]; void cov_start (int address) diff --git a/interf.c b/interf.c index 8a35db9..672388c 100644 --- a/interf.c +++ b/interf.c @@ -88,7 +88,7 @@ sim_write (uint32 mem, const char *buf, int length) for (i = 0; i < length; i++) { - ms->sis_memory_write ((mem + i) ^ arch->endian, &buf[i], 1); + ms->sis_memory_write ((mem + i) ^ arch->bswap, &buf[i], 1); } return length; } @@ -105,7 +105,7 @@ sim_read (uint32 mem, char *buf, int length) } for (i = 0; i < length; i++) { - ms->sis_memory_read ((mem + i) ^ arch->endian, &buf[i], 1); + ms->sis_memory_read ((mem + i) ^ arch->bswap, &buf[i], 1); } return length; } diff --git a/leon2.c b/leon2.c index 6f669a5..b1ed1d6 100644 --- a/leon2.c +++ b/leon2.c @@ -19,12 +19,6 @@ * Leon2 emulation, based on leon3.c and erc32.c/ */ -#ifdef WORDS_BIGENDIAN -#define EBT 0 -#else -#define EBT 3 -#endif - #define ROM_START 0x00000000 #define RAM_START 0x40000000 @@ -796,7 +790,9 @@ store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws) switch (sz) { case 0: - waddr ^= EBT; +#ifdef HOST_LITTLE_ENDIAN + waddr ^= 3; +#endif mem[waddr] = *data & 0x0ff; *ws = 0; break; @@ -804,7 +800,7 @@ store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws) #ifdef HOST_LITTLE_ENDIAN waddr ^= 2; #endif - memcpy (&mem[waddr], data, 2); + *((uint16 *) & mem[waddr]) = *data & 0x0ffff; *ws = 0; break; case 2: diff --git a/leon3.c b/leon3.c index 0a051d3..16b185e 100644 --- a/leon3.c +++ b/leon3.c @@ -996,12 +996,12 @@ store_bytes (char *mem, uint32 waddr, uint32 * data, int32 sz, int32 * ws) switch (sz) { case 0: - waddr ^= arch->endian; + waddr ^= arch->bswap; mem[waddr] = *data & 0x0ff; break; case 1: - waddr ^= arch->endian & 2; - memcpy (&mem[waddr], data, 2); + waddr ^= arch->bswap & 2; + *((uint16 *) & mem[waddr]) = (*data & 0x0ffff); break; case 3: memcpy (&mem[waddr], data, 8); diff --git a/riscv.c b/riscv.c index f1cc16d..d097fb2 100644 --- a/riscv.c +++ b/riscv.c @@ -24,6 +24,12 @@ #include #include +#ifdef WORDS_BIGENDIAN +#define BEH 1 +#else +#define BEH 0 +#endif + static int set_csr (address, sregs, value) uint32 address; @@ -222,9 +228,9 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rs2p << 1] = op1; + sregs->fsi[(rs2p << 1) + BEH] = op1; #ifdef FPU_D_ENABLED - sregs->fsi[(rs2p << 1) + 1] = -1; + sregs->fsi[(rs2p << 1) + 1 - BEH] = -1; #endif } break; @@ -249,8 +255,8 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rs2p << 1] = op1; - sregs->fsi[(rs2p << 1) + 1] = op2; + sregs->fsi[(rs2p << 1) + BEH] = op1; + sregs->fsi[(rs2p << 1) + 1 - BEH] = op2; } break; #endif @@ -262,7 +268,8 @@ riscv_dispatch_instruction (sregs) break; } mexc = - ms->memory_write (address, (uint32 *) & sregs->fsi[rs2p << 1], + ms->memory_write (address, + (uint32 *) & sregs->fsi[(rs2p << 1) + BEH], 2, &ws); sregs->hold += ws; if (mexc) @@ -282,8 +289,14 @@ riscv_dispatch_instruction (sregs) break; } mexc = - ms->memory_write (address, (uint32 *) & sregs->fsi[rs2p << 1], - 3, &ws); + ms->memory_write (address, + (uint32 *) & sregs->fsi[(rs2p << 1) + BEH], + 2, &ws); + sregs->hold += ws; + mexc |= + ms->memory_write (address + 4, + (uint32 *) & sregs->fsi[(rs2p << 1) + 1 - + BEH], 2, &ws); sregs->hold += ws; if (mexc) { @@ -467,8 +480,8 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rs1 << 1] = op1; - sregs->fsi[(rs1 << 1) + 1] = op2; + sregs->fsi[(rs1 << 1) + BEH] = op1; + sregs->fsi[(rs1 << 1) + 1 - BEH] = op2; } break; #endif @@ -489,7 +502,7 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rs1 << 1] = op1; + sregs->fsi[(rs1 << 1) + BEH] = op1; } break; case 4: @@ -566,8 +579,14 @@ riscv_dispatch_instruction (sregs) break; } mexc = - ms->memory_write (address, (uint32 *) & sregs->fsi[rs2 << 1], - 3, &ws); + ms->memory_write (address, + (uint32 *) & sregs->fsi[(rs2 << 1) + BEH], + 2, &ws); + sregs->hold += ws; + mexc |= + ms->memory_write (address + 4, + (uint32 *) & sregs->fsi[(rs2 << 1) + 1 - + BEH], 2, &ws); sregs->hold += ws; if (mexc) { @@ -585,7 +604,8 @@ riscv_dispatch_instruction (sregs) break; } mexc = - ms->memory_write (address, (uint32 *) & sregs->fsi[rs2 << 1], + ms->memory_write (address, + (uint32 *) & sregs->fsi[(rs2 << 1) + BEH], 2, &ws); sregs->hold += ws; if (mexc) @@ -981,7 +1001,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } - mexc = ms->memory_write (address, wdata, 2, &ws); + mexc = ms->memory_write (address, &wdata[BEH], 2, &ws); sregs->hold += ws; if (mexc) { @@ -996,7 +1016,9 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } - mexc = ms->memory_write (address, wdata, 3, &ws); + mexc = ms->memory_write (address, &wdata[BEH], 2, &ws); + sregs->hold += ws; + mexc |= ms->memory_write (address + 4, &wdata[1 - BEH], 2, &ws); sregs->hold += ws; if (mexc) { @@ -1060,7 +1082,7 @@ riscv_dispatch_instruction (sregs) sregs->trap = TRAP_ILLEG; break; } - mexc = ms->memory_read (address, (uint32 *) & data, &ws); + mexc = ms->memory_read (address & ~3, (uint32 *) & data, &ws); sregs->hold += ws; if (mexc) { @@ -1068,11 +1090,12 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } + data >>= (address & 3) * 8; data = (data << 24) >> 24; sregs->r[rd] = data; break; case LBU: - mexc = ms->memory_read (address, &op1, &ws); + mexc = ms->memory_read (address & ~3, &op1, &ws); sregs->hold += ws; if (mexc) { @@ -1080,6 +1103,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } + op1 >>= (address & 3) * 8; sregs->r[rd] = op1 & 0x0ff; break; case LH: @@ -1089,7 +1113,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } - mexc = ms->memory_read (address, (uint32 *) & data, &ws); + mexc = ms->memory_read (address & ~3, (uint32 *) & data, &ws); sregs->hold += ws; if (mexc) { @@ -1097,6 +1121,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } + data >>= (address & 2) * 8; data = (data << 16) >> 16; sregs->r[rd] = data; break; @@ -1107,7 +1132,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } - mexc = ms->memory_read (address, &op1, &ws); + mexc = ms->memory_read (address & ~3, &op1, &ws); sregs->hold += ws; if (mexc) { @@ -1115,6 +1140,7 @@ riscv_dispatch_instruction (sregs) sregs->wpaddress = address; break; } + op1 >>= (address & 2) * 8; op1 &= 0x0ffff; sregs->r[rd] = op1; break; @@ -1386,8 +1412,8 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rd << 1] = op1; - sregs->fsi[(rd << 1) + 1] = -1; + sregs->fsi[(rd << 1) + BEH] = op1; + sregs->fsi[(rd << 1) + 1 - BEH] = -1; } break; case LD: @@ -1409,8 +1435,8 @@ riscv_dispatch_instruction (sregs) } else { - sregs->fsi[rd << 1] = op1; - sregs->fsi[(rd << 1) + 1] = op2; + sregs->fsi[(rd << 1) + BEH] = op1; + sregs->fsi[(rd << 1) + 1 - BEH] = op2; } break; default: @@ -1432,29 +1458,29 @@ riscv_dispatch_instruction (sregs) switch (funct2) { case 0: /* single-precision ops */ - frs1 = rs1 << 1; - frs2 = rs2 << 1; - frd = rd << 1; + frs1 = (rs1 << 1) + BEH; + frs2 = (rs2 << 1) + BEH; + frd = (rd << 1) + BEH; switch (funct5) { case 0: /* FADDS */ sregs->fs[frd] = sregs->fs[frs1] + sregs->fs[frs2]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FADDs; break; case 1: /* FSUBS */ sregs->fs[frd] = sregs->fs[frs1] - sregs->fs[frs2]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FSUBs; break; case 2: /* FMULS */ sregs->fs[frd] = sregs->fs[frs1] * sregs->fs[frs2]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FMULs; break; case 3: /* FDIVS */ sregs->fs[frd] = sregs->fs[frs1] / sregs->fs[frs2]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FDIVs; break; case 4: /* FSGX */ @@ -1463,17 +1489,17 @@ riscv_dispatch_instruction (sregs) case 0: /* FSGNJ */ sregs->fsi[frd] = (sregs->fsi[frs1] & 0x7fffffff) | (sregs->fsi[frs2] & 0x80000000); - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; case 1: /* FSGNJN */ sregs->fsi[frd] = (sregs->fsi[frs1] & 0x7fffffff) | (~sregs->fsi[frs2] & 0x80000000); - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; case 2: /* FSGNJX */ sregs->fsi[frd] = sregs->fsi[frs1] ^ (sregs->fsi[frs2] & 0x80000000); - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; default: sregs->trap = TRAP_ILLEG; @@ -1485,7 +1511,7 @@ riscv_dispatch_instruction (sregs) sregs->fs[frd] = sregs->fs[frs1]; else sregs->fs[frd] = sregs->fs[frs2]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FSUBs; break; #ifdef FPU_D_ENABLED @@ -1494,7 +1520,7 @@ riscv_dispatch_instruction (sregs) { case 0: /* FCVTSD */ sregs->fs[frd] = (float32) sregs->fd[rs1]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; default: sregs->trap = TRAP_ILLEG; @@ -1503,7 +1529,7 @@ riscv_dispatch_instruction (sregs) #endif case 0x0b: /* FSQRTS */ sregs->fs[frd] = sqrtf (sregs->fs[frs1]); - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; sregs->fhold += T_FSQRTs; break; case 0x14: /* FCMPS */ @@ -1551,12 +1577,12 @@ riscv_dispatch_instruction (sregs) case 0: /* FCVTSW */ sop1 = sregs->r[rs1]; sregs->fs[frd] = (float32) sop1; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; case 1: /* FCVTSWU */ op1 = sregs->r[rs1]; sregs->fs[frd] = (float32) op1; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; default: sregs->trap = TRAP_ILLEG; @@ -1608,7 +1634,7 @@ riscv_dispatch_instruction (sregs) break; case 0x1e: /* FMVSX */ sregs->fsi[frd] = sregs->r[rs1]; - sregs->fsi[frd + 1] = -1; + sregs->fsi[frd ^ 1] = -1; break; default: sregs->trap = TRAP_ILLEG; @@ -1637,30 +1663,35 @@ riscv_dispatch_instruction (sregs) case 4: /* FSGX */ frd = (rd << 1); frs1 = (rs1 << 1); - frs2 = (rs2 <<= 1); + frs2 = (rs2 << 1); switch (funct3) { case 0: /* FSGNJ */ - sregs->fsi[frd] = sregs->fsi[frs1]; - sregs->fsi[frd + 1] = - (sregs-> - fsi[frs1 + 1] & 0x7fffffff) | (sregs->fsi[frs2 + - 1] & - 0x80000000); + sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH]; + sregs->fsi[frd + 1 - BEH] = + (sregs->fsi[frs1 + 1 - BEH] & 0x7fffffff) | (sregs-> + fsi[frs2 + + 1 - + BEH] + & + 0x80000000); break; case 1: /* FSGNJN */ - sregs->fsi[frd] = sregs->fsi[frs1]; - sregs->fsi[frd + 1] = - (sregs-> - fsi[frs1 + 1] & 0x7fffffff) | (~sregs->fsi[frs2 + - 1] & - 0x80000000); + sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH]; + sregs->fsi[frd + 1 - BEH] = + (sregs->fsi[frs1 + 1 - BEH] & 0x7fffffff) | (~sregs-> + fsi[frs2 + + 1 - + BEH] + & + 0x80000000); break; case 2: /* FSGNJX */ - sregs->fsi[frd] = sregs->fsi[frs1]; - sregs->fsi[frd + 1] = + sregs->fsi[frd + BEH] = sregs->fsi[frs1 + BEH]; + sregs->fsi[frd + 1 - BEH] = sregs->fsi[frs1 + - 1] ^ (sregs->fsi[frs2 + 1] & 0x80000000); + 1 - BEH] ^ (sregs->fsi[frs2 + 1 - + BEH] & 0x80000000); break; default: sregs->trap = TRAP_ILLEG; @@ -1679,7 +1710,7 @@ riscv_dispatch_instruction (sregs) switch (funct2) { case 1: /* FCVTDS */ - sregs->fd[rd] = (float64) sregs->fs[(rs1 << 1)]; + sregs->fd[rd] = (float64) sregs->fs[(rs1 << 1) + BEH]; break; default: sregs->trap = TRAP_ILLEG; @@ -1755,25 +1786,25 @@ riscv_dispatch_instruction (sregs) op1 = (1 << 8); // FIX ME, add quiet NaN break; case FP_INFINITE: - if (sregs->fsi[(rs1 << 1) + 1] & 0x80000000) + if (sregs->fsi[(rs1 << 1) + 1 - BEH] & 0x80000000) op1 = (1 << 0); else op1 = (1 << 7); break; case FP_ZERO: - if (sregs->fsi[(rs1 << 1) + 1] & 0x80000000) + if (sregs->fsi[(rs1 << 1) + 1 - BEH] & 0x80000000) op1 = (1 << 3); else op1 = (1 << 4); break; case FP_SUBNORMAL: - if (sregs->fsi[(rs1 << 1) + 1] & 0x80000000) + if (sregs->fsi[(rs1 << 1) + 1 - BEH] & 0x80000000) op1 = (1 << 2); else op1 = (1 << 5); break; case FP_NORMAL: - if (sregs->fsi[(rs1 << 1) + 1] & 0x80000000) + if (sregs->fsi[(rs1 << 1) + 1 - BEH] & 0x80000000) op1 = (1 << 1); else op1 = (1 << 6); @@ -1802,9 +1833,10 @@ riscv_dispatch_instruction (sregs) switch ((sregs->inst >> 25) & 3) { case 0: /* OP_FMADDS */ - sregs->fs[rd << 1] = (sregs->fs[rs1 << 1] * sregs->fs[rs2 << 1]) - + sregs->fs[(sregs->inst >> 27) << 1]; - sregs->fsi[(rd << 1) + 1] = -1; + sregs->fs[(rd << 1) + BEH] = + (sregs->fs[(rs1 << 1) + BEH] * sregs->fs[(rs2 << 1) + BEH]) + + sregs->fs[((sregs->inst >> 27) << 1) + BEH]; + sregs->fsi[(rd << 1) + 1 - BEH] = -1; sregs->fhold += T_FADDs + T_FMULs; break; #ifdef FPU_D_ENABLED @@ -1826,9 +1858,10 @@ riscv_dispatch_instruction (sregs) switch ((sregs->inst >> 25) & 3) { case 0: /* OP_FMSUBS */ - sregs->fs[rd << 1] = (sregs->fs[rs1 << 1] * sregs->fs[rs2 << 1]) - - sregs->fs[(sregs->inst >> 27) << 1]; - sregs->fsi[(rd << 1) + 1] = -1; + sregs->fs[(rd << 1) + BEH] = + (sregs->fs[(rs1 << 1) + BEH] * sregs->fs[(rs2 << 1) + BEH]) - + sregs->fs[((sregs->inst >> 27) << 1) + BEH]; + sregs->fsi[(rd << 1) + 1 - BEH] = -1; sregs->fhold += T_FMULs + T_FSUBs; break; #ifdef FPU_D_ENABLED @@ -1850,10 +1883,10 @@ riscv_dispatch_instruction (sregs) switch ((sregs->inst >> 25) & 3) { case 0: /* OP_FNMSUBS */ - sregs->fs[rd << 1] = - (-sregs->fs[rs1 << 1] * sregs->fs[rs2 << 1]) + - sregs->fs[(sregs->inst >> 27) << 1]; - sregs->fsi[(rd << 1) + 1] = -1; + sregs->fs[(rd << 1) + BEH] = + (-sregs->fs[(rs1 << 1) + BEH] * sregs->fs[(rs2 << 1) + BEH]) + + sregs->fs[((sregs->inst >> 27) << 1) + BEH]; + sregs->fsi[(rd << 1) + 1 - BEH] = -1; sregs->fhold += T_FADDs + T_FSUBs; break; #ifdef FPU_D_ENABLED @@ -1875,10 +1908,10 @@ riscv_dispatch_instruction (sregs) switch ((sregs->inst >> 25) & 3) { case 0: /* OP_FNMADDS */ - sregs->fs[rd << 1] = - (-sregs->fs[rs1 << 1] * sregs->fs[rs2 << 1]) - - sregs->fs[(sregs->inst >> 27) << 1]; - sregs->fsi[(rd << 1) + 1] = -1; + sregs->fs[(rd << 1) + BEH] = + (-sregs->fs[(rs1 << 1) + BEH] * sregs->fs[(rs2 << 1) + BEH]) - + sregs->fs[((sregs->inst >> 27) << 1) + BEH]; + sregs->fsi[(rd << 1) + 1 - BEH] = -1; sregs->fhold += T_FADDs + T_FMULs; break; #ifdef FPU_D_ENABLED @@ -2065,13 +2098,13 @@ riscv_get_regi (struct pstate *sregs, int32 reg, char *buf, int length) { if (length == 8) { - rval = sregs->fsi[((reg - 33) << 1) + 1]; + rval = sregs->fsi[((reg - 33) << 1) + 1 - BEH]; buf[7] = (rval >> 24) & 0x0ff; buf[6] = (rval >> 16) & 0x0ff; buf[5] = (rval >> 8) & 0x0ff; buf[4] = rval & 0x0ff; } - rval = sregs->fsi[(reg - 33) << 1]; + rval = sregs->fsi[((reg - 33) << 1) + BEH]; } else if ((reg >= 65) && (reg < 4161)) { @@ -2188,11 +2221,11 @@ riscv_display_ctrl (struct pstate *sregs) { uint32 i; - printf ("\n mtvec: %08X mcause: %08X mepc: %08X mtval: %08X \ + printf ("\n mtvec: %08X mcause: %08X mepc: %08X mtval: %08X \ mstatus: %08X\n", get_csr (CSR_MTVEC, sregs), get_csr (CSR_MCAUSE, sregs), get_csr (CSR_MEPC, sregs), sregs->mtval, get_csr (CSR_MSTATUS, sregs)); ms->sis_memory_read (sregs->pc, (char *) &i, 4); - printf ("\n pc: %08X = %08X ", sregs->pc, i); -// print_insn_sis (sregs->pc, &dinfo); + printf ("\n pc: %08X = %08X ", sregs->pc, i); + print_insn_sis (sregs->pc); if (sregs->err_mode) printf ("\n CPU in error mode"); else if (sregs->pwd_mode) @@ -2246,8 +2279,9 @@ riscv_display_fpu (struct pstate *sregs) else printf ("ft%d ", i - 20); - printf (" f%02d %08x%08x %.15e %.15e\n", i, sregs->fsi[(i << 1) + 1], - sregs->fsi[i << 1], sregs->fs[i << 1], sregs->fd[i]); + printf (" f%02d %08x%08x %.15e %.15e\n", i, + sregs->fsi[(i << 1) + 1 - BEH], sregs->fsi[(i << 1) + BEH], + sregs->fs[(i << 1) + BEH], sregs->fd[i]); } printf ("\n"); } @@ -3244,7 +3278,11 @@ riscv_print_insn (uint32 addr) } const struct cpu_arch riscv = { +#ifdef HOST_LITTLE_ENDIAN 0, +#else + 3, +#endif riscv_dispatch_instruction, riscv_execute_trap, riscv_check_interrupts, diff --git a/sis.h b/sis.h index d4d6f6a..35797e4 100644 --- a/sis.h +++ b/sis.h @@ -21,6 +21,8 @@ #endif #define VAL(x) strtoul(x,(char **)NULL,0) +#define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8)) +#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24)) #define I_ACC_EXC 1 #define NWIN 8 @@ -179,7 +181,7 @@ struct evcell struct cpu_arch { - int endian; + int bswap; int (*dispatch_instruction) (struct pstate * sregs); int (*execute_trap) (struct pstate * sregs); int (*check_interrupts) (struct pstate * sregs); diff --git a/sparc.c b/sparc.c index fc899d9..03a78d8 100644 --- a/sparc.c +++ b/sparc.c @@ -2286,7 +2286,11 @@ gdb_sp_read (uint32 mem, char *buf, int length) &sregs[cpu].r[((i + 1) * 16 + ((mem - sregs->sp[i]) >> 2)) % (NWIN * 16)]; for (j = 0; j < length; j++) - buf[j] = data[j ^ arch->endian]; +#ifdef HOST_LITTLE_ENDIAN + buf[j] = data[j ^ 3]; +#else + buf[j] = data[j]; +#endif if (sis_verbose) printf ("gdb_sp_read: 0x%08x\n", mem); return length; @@ -3470,7 +3474,11 @@ sparc_print_insn (uint32 addr) } const struct cpu_arch sparc32 = { +#ifdef HOST_LITTLE_ENDIAN 3, +#else + 0, +#endif sparc_dispatch_instruction, sparc_execute_trap, sparc_check_interrupts, -- cgit v1.2.3