#54855 - paladine - Fri Sep 23, 2005 4:19 am
I have found a THUMB reference that indicates SXTB can be used to sign extend a byte into a word. This is perfect since I want to take a signed byte and convert to an integer. GCC doesn't like it. Is this supported on the GBA's processor?
#54856 - tepples - Fri Sep 23, 2005 4:24 am
SXTB might be a macroinstruction for a left shift followed by a right shift. I seem to remember that MIPS assemblers support lots of macros out of the box; ARM's own tools might do the same.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#54857 - paladine - Fri Sep 23, 2005 4:29 am
My mind is currently blank as I'm about to go to sleep. How could I accomplish this same task using shifts? The pseudocode works as expected but I'd like to avoid the branch condition if possible. I'm sure it can be done using standard shifting/or'ing.
Code: |
inline static i32 SpriteGetY(LPSPRITE pSprite)
{
if (pSprite->attrib[0] & 0x80)
return (0xFFFFFF00 | pSprite->attrib[0]);
return (pSprite->attrib[0] & 0xFF);
}
|
I'd like to extend bit 8 through bits 9-32 to form the integer.
#54858 - tepples - Fri Sep 23, 2005 4:41 am
To sign-extend an 8-bit value, in C (assuming 32-bit ints):
Code: |
static inline signed int extend_s8_s32(signed int x)
{
return (x << 24) >> 24;
}
|
Or in asm:
Code: |
lsl r0, r0, 24
asr r0, r0, 24
|
If you want to extend a 9-bit value (copy bits 8 onto bits 9 through 31), it's similar. In C:
Code: |
static inline signed int extend_s8_s32(signed int x)
{
return (x << 23) >> 23;
}
|
Or in asm:
Code: |
lsl r0, r0, 23
asr r0, r0, 23
|
Besides...
Don't sprite y values on the GBA or Nintendo DS go from -64 to 191? This kind of wrapping can be done with the following expression:
Code: |
y_component = ((attribute_0 + 64) & 0xff) - 64; |
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#54860 - paladine - Fri Sep 23, 2005 4:51 am
I guess the 'magic' occurs in the right shift. I'm more of a software guy so it didn't occur to me that when the right shift occurs it uses the MSB to fill in the data. Thanks!
#54883 - Cearn - Fri Sep 23, 2005 8:20 am
With the arithmetic right-shift (asr) the magic happens. With the logical right-shift (lsr), it's always zero-extension. They're basically the signed and unsigned right shifts. Don't confuse the two, or there will be trouble.
#54886 - FluBBa - Fri Sep 23, 2005 8:29 am
I'm not sure about Thumb but in Arm you have ldrsb & ldrsh to signextend the value on register load, though it is quite restrictive in it's addressing modes.
_________________
I probably suck, my not is a programmer.
#54913 - paladine - Fri Sep 23, 2005 3:58 pm
Thanks Cearn, you are correct. I looked at the generated assembly from GCC and noticed that the C code (x << 24) >> 24 generated a lsl followed by an asr. GCC is smart enough to use asr,lsr based on the sign of the argument. In my case I was using a signed integer so it worked as expected.