This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: arm/thumb bugs
Philip Blundell wrote:
>
> It looks to me like there are bigger problems with that code than out-of-range branches. Does it actually work at all, even with small functions?
switch statements basically do work. At least, that's what I'd expect
from a release version...
I probably cut away a little bit too much in my earlier mail. so:
On ARM, a switch statement translates to:
sub r3, r0, #1
cmp r3, #44
addls pc, pc, r3, asl #2
b .L17
.align 2
.L18:
b .L3
b .L10
b .L16
b .L19
b .L19
(r0 == the var we're switching on. .L17 is obviously the 'default:'
case. Used compiler: gcc-3.0.2 unmodified, target=arm-linux-elf, run
with -fpic)
The assembler generates relocation entries (R_ARM_PC24 .text) for every
branch instruction. I have tested this - it works as expected. (Tested
with the older gcc with -mdisable-got. The code of this function is
identical, though.)
For thumb:
sub r3, r1, #1
cmp r3, #44
bls .LCB6
b .L17 @long jump
.LCB6:
ldr r2, .L20
lsl r3, r3, #2
ldr r3, [r3, r2]
mov pc, r3
.align 2
.align 2
.L18:
b .L3
b .L10
b .L4
b .L5
b .L5
...
.L20:
.word .L18(GOTOFF)
(now it's r1... compiler is again gcc-3.0.2 unmodified, same target,
flags -fpic -msingle-pic-base [not that this changes anything here]
-mthumb)
Now this does indeed look strange - it expects the jump table to be the
list of offsets you have mentioned in your mail. But in fact it's the
same series of relative jumps as in the 32bit ARM case.
Since the possible offsets in thumb are only 11 bit, I suppose your
proposal would be the best - and would get rid of the 'branch out of
range' issue as well. (Ok, the jump tables would get bigger than with
branches.) Producing non-pic code also uses 32 bit constants.
I would probably have the time to do this adaption, but I have - as I
said previously - no idea where to start.
greets
-- vbi