Subject: RE: Questions?

From: "Siders, Keith" <[email-masked]>
Date: Thu, 7 Mar 2002 15:44:30 -0600

Hmm, assembly or C? Your original message had examples in both. In C the
large part is the definitions in the union. 

If you define

struct le_bitfield {
	unsigned long low:8;
	unsigned long lmid:8;
	unsigned long hmid:8;
	unsigned long high:8;
};

struct be_bitfield {
	unsigned long high:8;
	unsigned long hmid:8;
	unsigned long lmid:8;
	unsigned long low:8;
};

union byte_swap {
	unsigned long original;
	struct le_bitfield le;
	struct be_bitfield be;
}swapper;

Now you can use your previous char pointer

	swapper.original = *((unsigned long *)mptr);
	mptr[0] = swapper.le.low;
	mptr[1] = swapper.le.lmid;
	mptr[2] = swapper.le.hmid;
	mptr[3] = swapper.le.high;

5 instructions in C.

To swap the other way, just use swapper.be.xxxx. If this still translates to
8 assembly instructions (or worse), oh well... just trying to help. ;)

-> -----Original Message-----
-> From: Richard Hodges [mailto:[email-masked]]
-> Sent: Thursday, March 07, 2002 3:00 PM
-> To: Siders, Keith
-> Cc: Linux MIPS
-> Subject: RE: Questions?
-> 
-> 
-> On Thu, 7 Mar 2002, Siders, Keith wrote:
-> 
-> > You can get that down to 5 instructions. You could either 
-> use a typecast, or
-> > for portability, use a union definition. For that matter 
-> you could even
-> > typecast *mptr as a pointer to the union and extract the 
-> data from the
-> > string however you choose. But it still takes 5 
-> instructions, unless you're
-> > pulling the data into another buffer, in which case you're 
-> down to 4.
-> 
-> Which 5 instructions are those?  For htonl from memory, the 
-> only sequence
-> I can think of is the "obvious" one of lbu/shift (7 
-> instructions).  And
-> for swapping BE-LE in memory (an important thing for me), I 
-> do not see any
-> method better than the "obvious" one I mentioned earlier:
-> 
->     90c50000        lbu     a1,0(a2)
->     90c40001        lbu     a0,1(a2)
->     90c30002        lbu     v1,2(a2)
->     90c20003        lbu     v0,3(a2)
->     a0c20000        sb      v0,0(a2)
->     a0c30001        sb      v1,1(a2)
->     a0c40002        sb      a0,2(a2)
->     a0c50003        sb      a1,3(a2)
-> 
-> Thanks,
-> 
-> -Richard
-> 
-> > -> From: Richard Hodges [mailto:[email-masked]]
-> 
-> > -> To me, byte swapping on MIPS actually seems rather 
-> > -> expensive.  The code
-> > -> for htonl (linux/byteorder/swab.h) ends up something like this:
-> > -> 
-> > ->         srl     $5,$4,8
-> > ->         andi    $5,$5,0xff00
-> > ->         srl     $2,$4,24
-> > ->         andi    $3,$4,0xff00
-> > ->         or      $2,$2,$5
-> > ->         sll     $3,$3,8
-> > ->         or      $2,$2,$3
-> > ->         sll     $4,$4,24
-> 
->