[v3,03/14] sim/erc32: Switched emulated memory to host endian order.

Message ID 1425244244-27709-4-git-send-email-jiri@gaisler.se
State Superseded
Headers

Commit Message

Jiri Gaisler March 1, 2015, 9:10 p.m. UTC
  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  | 166 ++++++++++++-----------------------------------------
 sim/erc32/exec.c   |  60 +++++++++++++++----
 sim/erc32/func.c   |  41 ++++++++-----
 sim/erc32/interf.c |  29 ++++++++++
 sim/erc32/sis.c    |   4 ++
 5 files changed, 147 insertions(+), 153 deletions(-)
  

Comments

Mike Frysinger March 2, 2015, 1:13 a.m. UTC | #1
On 01 Mar 2015 22:10, Jiri Gaisler wrote:
> --- a/sim/erc32/erc32.c
> +++ b/sim/erc32/erc32.c
>
>      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]));

pretty sure this too should be a memcpy.  also applies to the other updates to 
this func in this patch.

> --- a/sim/erc32/exec.c
> +++ b/sim/erc32/exec.c
>  
> +static int
> +extract_short (uint32 data, uint32 address)
> +{
> +    return((data >> ((2 - (address & 2)) * 8)) & 0xffff);

needs to be a space after the return

> +static int
> +extract_short_signed (uint32 data, uint32 address)
> +{
> +    uint32 tmp;
> +    tmp = ((data >> ((2 - (address & 2)) * 8)) & 0xffff);

you could merge these two statements if you wanted

> +    if (tmp & 0x8000) tmp |= 0xffff0000;

uncuddle this

> +    return(tmp);

drop the paren

> +static int
> +extract_byte (uint32 data, uint32 address)
> +{
> +    return((data >> ((3 - (address & 3)) * 8)) & 0xff);

space after the return

> +static int
> +extract_byte_signed (uint32 data, uint32 address)
> +{
> +    uint32 tmp;
> +    tmp = ((data >> ((3 - (address & 3)) * 8)) & 0xff);

merge if you want

> +    if (tmp & 0x80) tmp |= 0xffffff00;

uncuddle

> +    return(tmp);

drop paren

> --- a/sim/erc32/func.c
> +++ b/sim/erc32/func.c
>
> +	    if (isprint(p[j^end]))
> +		putchar(p[j^end]);

spaces around that ^ operator

> @@ -841,10 +850,11 @@ dis_mem(addr, len, info)
>  {
>      uint32          i;
>      unsigned char   data[4];
> +    uint32          *wdata = (uint32 *) data;

use a union ? :)

>  		while (section_size > 0) {
> -		    char            buffer[1024];
>  		    int             count;
> +		    char            buffer[1024];
> +		    uint32          *wbuffer = (uint32 *) buffer;

use a union

> +#ifdef HOST_LITTLE_ENDIAN
> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
> +#endif

sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
can use here.

> @@ -356,7 +360,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

same here

> @@ -366,7 +382,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

and here
-mike
  
Jiri Gaisler March 12, 2015, 9:25 p.m. UTC | #2
On 02/03/15 02:13, Mike Frysinger wrote:
>> +#ifdef HOST_LITTLE_ENDIAN
>> > +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
>> > +#endif
> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
> can use here.
> 

I don't understand why ntohl() is a problem. It is a common Posix function
that converts big endian to host endian, exactly what is needed. Using
sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
makes the simulator larger than necessary ....

Jiri.
  
Mike Frysinger March 12, 2015, 11:55 p.m. UTC | #3
On 12 Mar 2015 22:25, Jiri Gaisler wrote:
> On 02/03/15 02:13, Mike Frysinger wrote:
> >> +#ifdef HOST_LITTLE_ENDIAN
> >> > +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
> >> > +#endif
> >
> > sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
> > can use here.
> 
> I don't understand why ntohl() is a problem. It is a common Posix function
> that converts big endian to host endian, exactly what is needed. Using
> sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
> makes the simulator larger than necessary ....

"network" has no meaning here.  using it as a proxy for moving between big 
endian and native endian when there are clear functions that the sim has 
standardized on isn't correct.  your code also (1) requires duplicating branches 
and (2) inline preprocessor checks.  it also does not properly handle bi-endian 
builds.  sim-endian does all of these for you.  the whole point of common/ is 
to delete code from each sim rather than open coding it everywhere.

wrt size, i don't think that's a compelling argument.  we're talking units of 
KiB here, and i can't even count that low :P.

if you're having trouble converting the build over (compiling/linking errors), 
then we can discuss that.  but it'd be a matter of "do we do it now or later" 
rather than "do we do ever convert".
-mike
  
Mike Frysinger March 14, 2015, 7:45 a.m. UTC | #4
[ read gdb lists to cc ]

On 13 Mar 2015 09:24, Jiri Gaisler wrote:
> On 13/03/15 00:55, Mike Frysinger wrote:
> > On 12 Mar 2015 22:25, Jiri Gaisler wrote:
> >> On 02/03/15 02:13, Mike Frysinger wrote:
> >>>> +#ifdef HOST_LITTLE_ENDIAN
> >>>>> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
> >>>>> +#endif
> >>>
> >>> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
> >>> can use here.
> >>
> >> I don't understand why ntohl() is a problem. It is a common Posix function
> >> that converts big endian to host endian, exactly what is needed. Using
> >> sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
> >> makes the simulator larger than necessary ....
> > 
> > "network" has no meaning here.  using it as a proxy for moving between big 
> > endian and native endian when there are clear functions that the sim has 
> > standardized on isn't correct.  your code also (1) requires duplicating branches 
> > and (2) inline preprocessor checks.  it also does not properly handle bi-endian 
> > builds.  sim-endian does all of these for you.  the whole point of common/ is 
> > to delete code from each sim rather than open coding it everywhere.
> > 
> > wrt size, i don't think that's a compelling argument.  we're talking units of 
> > KiB here, and i can't even count that low :P.
> > 
> > if you're having trouble converting the build over (compiling/linking errors), 
> > then we can discuss that.  but it'd be a matter of "do we do it now or later" 
> > rather than "do we do ever convert".
> 
> Right. I tried to use the T2H_4 macro, but can't get it to compile.
> I included <sim-basics.h> and added sim-endian.o and sim-io.o to the
> Makefile, but it complains about unresolved function etc. Do I really
> need to create a sim-main.c and sim-main.h just to use T2H?

i've pushed a patch to bury the sim-io.h include in sim-assert.h (since that's 
the header that actually uses the sim_io_xxx funcs).  if you define your own 
ASSERT/SIM_ASSERT macros, it should be avoided for now.  just make sure you add 
a note that they should get converted to sim-assert.h at some point.

> Is there
> any documentation whatsoever on how to use the sim/common interface?

not really ... normally you'd use the nrun.c main which implies you'd write the 
overall sim in a certain way, so you'd get all the funcs in there for free.  but 
for existing old sims (like the sparc one), it's harder to deal with.

i've been very slowly converting things over
-mike
  
Mike Frysinger March 14, 2015, 10:23 a.m. UTC | #5
On 14 Mar 2015 10:23, Jiri Gaisler wrote:
> On 14/03/15 08:45, Mike Frysinger wrote:
> > On 13 Mar 2015 09:24, Jiri Gaisler wrote:
> >> On 13/03/15 00:55, Mike Frysinger wrote:
> >>> On 12 Mar 2015 22:25, Jiri Gaisler wrote:
> >>>> On 02/03/15 02:13, Mike Frysinger wrote:
> >>>>>> +#ifdef HOST_LITTLE_ENDIAN
> >>>>>>> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
> >>>>>>> +#endif
> >>>>>
> >>>>> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
> >>>>> can use here.
> >>>>
> >>>> I don't understand why ntohl() is a problem. It is a common Posix function
> >>>> that converts big endian to host endian, exactly what is needed. Using
> >>>> sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
> >>>> makes the simulator larger than necessary ....
> >>>
> >>> "network" has no meaning here.  using it as a proxy for moving between big 
> >>> endian and native endian when there are clear functions that the sim has 
> >>> standardized on isn't correct.  your code also (1) requires duplicating branches 
> >>> and (2) inline preprocessor checks.  it also does not properly handle bi-endian 
> >>> builds.  sim-endian does all of these for you.  the whole point of common/ is 
> >>> to delete code from each sim rather than open coding it everywhere.
> >>>
> >>> wrt size, i don't think that's a compelling argument.  we're talking units of 
> >>> KiB here, and i can't even count that low :P.
> >>>
> >>> if you're having trouble converting the build over (compiling/linking errors), 
> >>> then we can discuss that.  but it'd be a matter of "do we do it now or later" 
> >>> rather than "do we do ever convert".
> >>
> >> Right. I tried to use the T2H_4 macro, but can't get it to compile.
> >> I included <sim-basics.h> and added sim-endian.o and sim-io.o to the
> >> Makefile, but it complains about unresolved function etc. Do I really
> >> need to create a sim-main.c and sim-main.h just to use T2H?
> > 
> > i've pushed a patch to bury the sim-io.h include in sim-assert.h (since that's 
> > the header that actually uses the sim_io_xxx funcs).  if you define your own 
> > ASSERT/SIM_ASSERT macros, it should be avoided for now.  just make sure you add 
> > a note that they should get converted to sim-assert.h at some point.
> 
> I'm not sure this helps. sim-endian.c includes sim-assert.h, so I get the
> same problem even after your patch:
> 
> gcc -DHAVE_CONFIG_H     -DPROFILE=1 -DWITH_PROFILE=-1         -DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN -DDEFAULT_INLINE=0           -DFAST_UART -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../..   -I. -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32 -I../common
> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common -I../../include -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../include -I../../bfd -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../bfd -I../../opcodes
> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../opcodes  -g -O2 -static-libstdc++ -static-libgcc  -o run \
> 	  run.o libsim.a ../../bfd/libbfd.a ../../opcodes/libopcodes.a  ../../libiberty/libiberty.a -ltermcap -ldl -lz -lnsl  ../../readline/libreadline.a -ltermcap -lm
> libsim.a(sim-endian.o): In function `offset_1':
> /home/jiri/src/gdb/v4/sim/erc32/../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common/sim-n-endian.h:145: undefined reference to `sim_io_error'

did you define ASSERT/SIM_ASSERT before including sim-endian.h ?
-mike
  
Jiri Gaisler March 14, 2015, 8:44 p.m. UTC | #6
On 14/03/15 11:23, Mike Frysinger wrote:
> On 14 Mar 2015 10:23, Jiri Gaisler wrote:
>> On 14/03/15 08:45, Mike Frysinger wrote:
>>> On 13 Mar 2015 09:24, Jiri Gaisler wrote:
>>>> On 13/03/15 00:55, Mike Frysinger wrote:
>>>>> On 12 Mar 2015 22:25, Jiri Gaisler wrote:
>>>>>> On 02/03/15 02:13, Mike Frysinger wrote:
>>>>>>>> +#ifdef HOST_LITTLE_ENDIAN
>>>>>>>>> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
>>>>>>>>> +#endif
>>>>>>>
>>>>>>> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
>>>>>>> can use here.
>>>>>>
>>>>>> I don't understand why ntohl() is a problem. It is a common Posix function
>>>>>> that converts big endian to host endian, exactly what is needed. Using
>>>>>> sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
>>>>>> makes the simulator larger than necessary ....
>>>>>
>>>>> "network" has no meaning here.  using it as a proxy for moving between big 
>>>>> endian and native endian when there are clear functions that the sim has 
>>>>> standardized on isn't correct.  your code also (1) requires duplicating branches 
>>>>> and (2) inline preprocessor checks.  it also does not properly handle bi-endian 
>>>>> builds.  sim-endian does all of these for you.  the whole point of common/ is 
>>>>> to delete code from each sim rather than open coding it everywhere.
>>>>>
>>>>> wrt size, i don't think that's a compelling argument.  we're talking units of 
>>>>> KiB here, and i can't even count that low :P.
>>>>>
>>>>> if you're having trouble converting the build over (compiling/linking errors), 
>>>>> then we can discuss that.  but it'd be a matter of "do we do it now or later" 
>>>>> rather than "do we do ever convert".
>>>>
>>>> Right. I tried to use the T2H_4 macro, but can't get it to compile.
>>>> I included <sim-basics.h> and added sim-endian.o and sim-io.o to the
>>>> Makefile, but it complains about unresolved function etc. Do I really
>>>> need to create a sim-main.c and sim-main.h just to use T2H?
>>>
>>> i've pushed a patch to bury the sim-io.h include in sim-assert.h (since that's 
>>> the header that actually uses the sim_io_xxx funcs).  if you define your own 
>>> ASSERT/SIM_ASSERT macros, it should be avoided for now.  just make sure you add 
>>> a note that they should get converted to sim-assert.h at some point.
>>
>> I'm not sure this helps. sim-endian.c includes sim-assert.h, so I get the
>> same problem even after your patch:
>>
>> gcc -DHAVE_CONFIG_H     -DPROFILE=1 -DWITH_PROFILE=-1         -DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN -DDEFAULT_INLINE=0           -DFAST_UART -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../..   -I. -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32 -I../common
>> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common -I../../include -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../include -I../../bfd -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../bfd -I../../opcodes
>> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../opcodes  -g -O2 -static-libstdc++ -static-libgcc  -o run \
>> 	  run.o libsim.a ../../bfd/libbfd.a ../../opcodes/libopcodes.a  ../../libiberty/libiberty.a -ltermcap -ldl -lz -lnsl  ../../readline/libreadline.a -ltermcap -lm
>> libsim.a(sim-endian.o): In function `offset_1':
>> /home/jiri/src/gdb/v4/sim/erc32/../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common/sim-n-endian.h:145: undefined reference to `sim_io_error'
> 
> did you define ASSERT/SIM_ASSERT before including sim-endian.h ?

No, I included sim-basic.h in my code. Including sim-endian.h only will not
work due to dependencies on other include files. I don't see how this will
change how sim-endian.o is built though, as it is compiled separately.

I did manage to compile the code by including sim-endian.c directly into my
own code (func.c) rather then building it separately:

#include <sim-assert.h>
#undef  ASSERT
#define ASSERT(x) if (0) {}
#include <sim-endian.c>

Is this acceptable ...?

Jiri.
  
Mike Frysinger March 17, 2015, 8:06 a.m. UTC | #7
On 14 Mar 2015 21:44, Jiri Gaisler wrote:
> On 14/03/15 11:23, Mike Frysinger wrote:
> > On 14 Mar 2015 10:23, Jiri Gaisler wrote:
> >> On 14/03/15 08:45, Mike Frysinger wrote:
> >>> On 13 Mar 2015 09:24, Jiri Gaisler wrote:
> >>>> On 13/03/15 00:55, Mike Frysinger wrote:
> >>>>> On 12 Mar 2015 22:25, Jiri Gaisler wrote:
> >>>>>> On 02/03/15 02:13, Mike Frysinger wrote:
> >>>>>>>> +#ifdef HOST_LITTLE_ENDIAN
> >>>>>>>>> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap
> >>>>>>>>> +#endif
> >>>>>>>
> >>>>>>> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you 
> >>>>>>> can use here.
> >>>>>>
> >>>>>> I don't understand why ntohl() is a problem. It is a common Posix function
> >>>>>> that converts big endian to host endian, exactly what is needed. Using
> >>>>>> sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and
> >>>>>> makes the simulator larger than necessary ....
> >>>>>
> >>>>> "network" has no meaning here.  using it as a proxy for moving between big 
> >>>>> endian and native endian when there are clear functions that the sim has 
> >>>>> standardized on isn't correct.  your code also (1) requires duplicating branches 
> >>>>> and (2) inline preprocessor checks.  it also does not properly handle bi-endian 
> >>>>> builds.  sim-endian does all of these for you.  the whole point of common/ is 
> >>>>> to delete code from each sim rather than open coding it everywhere.
> >>>>>
> >>>>> wrt size, i don't think that's a compelling argument.  we're talking units of 
> >>>>> KiB here, and i can't even count that low :P.
> >>>>>
> >>>>> if you're having trouble converting the build over (compiling/linking errors), 
> >>>>> then we can discuss that.  but it'd be a matter of "do we do it now or later" 
> >>>>> rather than "do we do ever convert".
> >>>>
> >>>> Right. I tried to use the T2H_4 macro, but can't get it to compile.
> >>>> I included <sim-basics.h> and added sim-endian.o and sim-io.o to the
> >>>> Makefile, but it complains about unresolved function etc. Do I really
> >>>> need to create a sim-main.c and sim-main.h just to use T2H?
> >>>
> >>> i've pushed a patch to bury the sim-io.h include in sim-assert.h (since that's 
> >>> the header that actually uses the sim_io_xxx funcs).  if you define your own 
> >>> ASSERT/SIM_ASSERT macros, it should be avoided for now.  just make sure you add 
> >>> a note that they should get converted to sim-assert.h at some point.
> >>
> >> I'm not sure this helps. sim-endian.c includes sim-assert.h, so I get the
> >> same problem even after your patch:
> >>
> >> gcc -DHAVE_CONFIG_H     -DPROFILE=1 -DWITH_PROFILE=-1         -DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN -DDEFAULT_INLINE=0           -DFAST_UART -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../..   -I. -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32 -I../common
> >> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common -I../../include -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../include -I../../bfd -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../bfd -I../../opcodes
> >> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../opcodes  -g -O2 -static-libstdc++ -static-libgcc  -o run \
> >> 	  run.o libsim.a ../../bfd/libbfd.a ../../opcodes/libopcodes.a  ../../libiberty/libiberty.a -ltermcap -ldl -lz -lnsl  ../../readline/libreadline.a -ltermcap -lm
> >> libsim.a(sim-endian.o): In function `offset_1':
> >> /home/jiri/src/gdb/v4/sim/erc32/../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common/sim-n-endian.h:145: undefined reference to `sim_io_error'
> > 
> > did you define ASSERT/SIM_ASSERT before including sim-endian.h ?
> 
> No, I included sim-basic.h in my code. Including sim-endian.h only will not
> work due to dependencies on other include files. I don't see how this will
> change how sim-endian.o is built though, as it is compiled separately.
> 
> I did manage to compile the code by including sim-endian.c directly into my
> own code (func.c) rather then building it separately:
> 
> #include <sim-assert.h>
> #undef  ASSERT
> #define ASSERT(x) if (0) {}
> #include <sim-endian.c>
> 
> Is this acceptable ...?

lets go with your first patch with some /* TODO */ added in these areas.  we 
need to some more clean up in this sim and lay some basic ground work before we 
can have it start using common/.  i didn't realize just how disconnected erc32 
was from everything else.
-mike
  
Jiri Gaisler March 21, 2015, 8:40 p.m. UTC | #8
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



On 17/03/15 09:06, Mike Frysinger wrote:
> On 14 Mar 2015 21:44, Jiri Gaisler wrote:
>> On 14/03/15 11:23, Mike Frysinger wrote:
>>> On 14 Mar 2015 10:23, Jiri Gaisler wrote:
>>>> On 14/03/15 08:45, Mike Frysinger wrote:
>>>>> On 13 Mar 2015 09:24, Jiri Gaisler wrote:
>>>>>> On 13/03/15 00:55, Mike Frysinger wrote:
>>>>>>> On 12 Mar 2015 22:25, Jiri Gaisler wrote:
>>>>>>>> On 02/03/15 02:13, Mike Frysinger wrote:
>>>>>>>>>> +#ifdef HOST_LITTLE_ENDIAN
>>>>>>>>>>> +		    for (i = 0; i < (count / 4); i++) wbuffer[i] = ntohl(wbuffer[i]); // endian swap +#endif
>>>>>>>>> 
>>>>>>>>> sim-endian.h already provides a lot of helper funcs that i'm pretty sure you can use here.
>>>>>>>> 
>>>>>>>> I don't understand why ntohl() is a problem. It is a common Posix function that converts big endian to host endian, exactly what is needed. Using sim-endian.h pulls in a lot of the sim-*.c files due to dependencies and makes the simulator larger than necessary
>>>>>>>> ....
>>>>>>> 
>>>>>>> "network" has no meaning here.  using it as a proxy for moving between big endian and native endian when there are clear functions that the sim has standardized on isn't correct.  your code also (1) requires duplicating branches and (2) inline preprocessor
>>>>>>> checks.  it also does not properly handle bi-endian builds.  sim-endian does all of these for you.  the whole point of common/ is to delete code from each sim rather than open coding it everywhere.
>>>>>>> 
>>>>>>> wrt size, i don't think that's a compelling argument.  we're talking units of KiB here, and i can't even count that low :P.
>>>>>>> 
>>>>>>> if you're having trouble converting the build over (compiling/linking errors), then we can discuss that.  but it'd be a matter of "do we do it now or later" rather than "do we do ever convert".
>>>>>> 
>>>>>> Right. I tried to use the T2H_4 macro, but can't get it to compile. I included <sim-basics.h> and added sim-endian.o and sim-io.o to the Makefile, but it complains about unresolved function etc. Do I really need to create a sim-main.c and sim-main.h just to use
>>>>>> T2H?
>>>>> 
>>>>> i've pushed a patch to bury the sim-io.h include in sim-assert.h (since that's the header that actually uses the sim_io_xxx funcs).  if you define your own ASSERT/SIM_ASSERT macros, it should be avoided for now.  just make sure you add a note that they should get
>>>>> converted to sim-assert.h at some point.
>>>> 
>>>> I'm not sure this helps. sim-endian.c includes sim-assert.h, so I get the same problem even after your patch:
>>>> 
>>>> gcc -DHAVE_CONFIG_H     -DPROFILE=1 -DWITH_PROFILE=-1         -DWITH_HOST_BYTE_ORDER=LITTLE_ENDIAN -DDEFAULT_INLINE=0           -DFAST_UART -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../..   -I. -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32 -I../common 
>>>> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common -I../../include -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../include -I../../bfd -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../bfd -I../../opcodes 
>>>> -I../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../../opcodes  -g -O2 -static-libstdc++ -static-libgcc  -o run \ run.o libsim.a ../../bfd/libbfd.a ../../opcodes/libopcodes.a  ../../libiberty/libiberty.a -ltermcap -ldl -lz -lnsl  ../../readline/libreadline.a
>>>> -ltermcap -lm libsim.a(sim-endian.o): In function `offset_1': /home/jiri/src/gdb/v4/sim/erc32/../../../../../ibm/src/gdb/binutils-gdb/sim/erc32/../common/sim-n-endian.h:145: undefined reference to `sim_io_error'
>>> 
>>> did you define ASSERT/SIM_ASSERT before including sim-endian.h ?
>> 
>> No, I included sim-basic.h in my code. Including sim-endian.h only will not work due to dependencies on other include files. I don't see how this will change how sim-endian.o is built though, as it is compiled separately.
>> 
>> I did manage to compile the code by including sim-endian.c directly into my own code (func.c) rather then building it separately:
>> 
>> #include <sim-assert.h> #undef  ASSERT #define ASSERT(x) if (0) {} #include <sim-endian.c>
>> 
>> Is this acceptable ...?
> 
> lets go with your first patch with some /* TODO */ added in these areas.  we need to some more clean up in this sim and lay some basic ground work before we can have it start using common/.  i didn't realize just how disconnected erc32 was from everything else. -mike

v4 of this patch uses sim-endian.c and everything compiles fine.
Should I revert to not using sim-endian.c and post a v5 of the patches?

Jiri.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJVDddLAAoJEIAIwBKmO2+bOjUQALoZ/PXNgnYal4UXOndq6C5l
5onSEB4jTU72eK1aDMWSQPlcTLwT2uuG9sqp1yMcoL1sZY7rGDawaFd8SzP5WeV+
1vD6v7buhakLWzR5wn8O1yDD2+hHyKOZdMpMTzND3MVaf4KIHs4EVPaCg/6Um2qW
Co2e9xP0cgj+vRhg2BWY9bL3PvpBGy/pa0/KWqxZd7SsYuh3vWFnFq2htZTlPgi5
jFKlJN2t4rQ67fZOaicD5rNutmNbmaTaakfOReA4d/UvEXR/dTOqReEkQaUAT4MM
YxncGa+ecuVApQ5qIPZaZQPZHXNbTQb6mfOvpIR+yXnYA+6S2VKWf3DGBzg5K8eS
APz9DEj4677tmtWRjs/PkFQpCyAX34s1pEscMWnJJQgQXY17IpRwmcXZx+QlKMdQ
peOmS2YmjYxjAApXGZ9gRa4yRG5sW09SDSjj0mXaH/2lD0u3C76Aqp1n/jTPauVk
/TdmWhoVRdVhLQ0QZ9uU1NSql84taDeGfvJSGE/MQxSMAulj0GbAHDlph1EiCIvu
5WPmII6ibCX2B5uVvgSJN4fyxnmunzcDEdUH/7L7IljIfI9DjyXp48dDTkmFn7mX
wggEjAULUxHIss8/ldGEPvdJyU8+jQVzusi9xNMTS3qo7RX6fBMGo9FRyvcY38b/
t1GBKmiDO8IT72/uEtgI
=vYan
-----END PGP SIGNATURE-----
  

Patch

diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
index 428d6c4..18913dd 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,43 @@  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
+	    memcpy(&mem[waddr], data, 2);
+	    *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;
+	    memcpy(&mem[waddr], data, 4);
+	    *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;
+	    memcpy(&mem[waddr], data, 8);
+	    *ws = 2 * mem_ramw_ws + STD_WS;
 	    break;
-	    
-	}
     }
 }
 
@@ -1671,7 +1588,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 +1606,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 +1617,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 +1686,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 +1712,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 +1728,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 +1739,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..68c77c6 100644
--- a/sim/erc32/exec.c
+++ b/sim/erc32/exec.c
@@ -371,8 +371,38 @@  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)
+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 e0037e7..9a41e0b 100644
--- a/sim/erc32/func.c
+++ b/sim/erc32/func.c
@@ -788,15 +788,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");
@@ -810,22 +810,31 @@  disp_mem(addr, len)
 {
 
     uint32          i;
-    unsigned char   data[4];
+    union {
+	    unsigned char u8[4];
+	    uint32 u32;
+    } 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]);
-	    mem[j] = *((int *) &data);
+	    sis_memory_read((i + (j * 4)), data.u8, 4);
+	    printf("%08x  ", data.u32);
+	    mem[j] = data.u32;
 	}
 	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('.');
 	}
@@ -841,10 +850,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");
@@ -1043,6 +1053,7 @@  bfd_load(fname)
     asection       *section;
     bfd            *pbfd;
     const bfd_arch_info_type *arch;
+    int            i;
 
     pbfd = bfd_openr(fname, 0);
 
@@ -1116,13 +1127,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 608b224..0a83c4d 100644
--- a/sim/erc32/interf.c
+++ b/sim/erc32/interf.c
@@ -266,7 +266,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();
@@ -356,7 +360,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
@@ -366,7 +382,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 931e3f3..dcb5ebf 100644
--- a/sim/erc32/sis.c
+++ b/sim/erc32/sis.c
@@ -227,7 +227,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();