I’ve been looking at this and there’s something weird going on. Here’s some
assembly:
case1:
short *pLocal = (short *)(GetMemory() + 7);
80404aa: f3 61 mov r15,r1
80404ac: 38 d8 mov.l 8040590 <main+0xf0>,r8 ! 0x8040460
80404ae: 0b 48 jsr @r8
80404b0: 09 00 nop
80404b2: 03 61 mov r0,r1
80404b4: 07 71 add #7,r1
80404b6: 11 1e mov.l r1,@(4,r14)
local = *pLocal;
80404b8: e1 51 mov.l @(4,r14),r1
80404ba: 11 62 mov.w @r1,r2
80404bc: 21 2e mov.w r2,@r14
case2:
char *pLocal = GetMemory() + 7;
8040500: f3 61 mov r15,r1
8040502: 23 d8 mov.l 8040590 <main+0xf0>,r8 ! 0x8040460
8040504: 0b 48 jsr @r8
8040506: 09 00 nop
8040508: 03 61 mov r0,r1
804050a: 07 71 add #7,r1
804050c: 11 1e mov.l r1,@(4,r14)
local = ((short)(pLocal[1] << | (short)(pLocal[0]));
804050e: e1 52 mov.l @(4,r14),r2
8040510: 23 61 mov r2,r1
8040512: 01 71 add #1,r1
8040514: 10 62 mov.b @r1,r2
8040516: 23 61 mov r2,r1
8040518: 18 41 shll8 r1
804051a: e1 52 mov.l @(4,r14),r2
804051c: 20 63 mov.b @r2,r3
804051e: 3b 21 or r3,r1
8040520: 11 2e mov.w r1,@r14
My array returned by GetMemory is a short array {1,2,3,4,5,6} which looks
like 0x00020001 0x00040003… in memory.
It looks like the instruction in case 1 at 04ba is where the problem lies.
Instead of getting 0500 from the array (like we do in case2) we wind up with
0xffff0000. The psuedocode for the mov.w instruction is:
MOVWL(long m, long n)
{
R[n]=(long)Read_Word(R[m]);
if ((R[n] & 0x8000) == 0) R[n] &= 0x0000FFFF;
else R[n] |= 0xFFFF0000;
PC+=2;
}
So it seems like we’re getting zero and then sign extending to 0xFFFF0000.
The question, of course, is why the Read_Word is not getting the 0x0500 from
the array. I’ll look further into it. It’s likely that gcc is generating
invalid code in this case but I’ll have to figure out what the valid code is
first.
cheers,
Kris
“HP Reichert” <hp.reichert@idea.REMOVE.soft.de> wrote in message
news:atuff1$fku$1@inn.qnx.com…
I’ve a massive problem if normaly realy legal C/C++ code running on a sh4.
see the example below
char *GetMemory() ;
short local = 0;
// this one is not working
// the value I get is not byte swaped or something else it is only
absolutly
wrong
// the same code running on x86 is working proper
short *pLocal = (short *)(GetMemory() + 7);
local = *pLocal;
// versus this version is working and gets the right value
char *pLocal = GetMemory() + 7;
local = ((short)(pLocal[1]) << > > | (short)(pLocal[0]);