[PATCH] ARM and Thumb Segmented Stacks

Alex Crichton alex at crichton.co
Thu Feb 27 11:59:35 PST 2014


> There still seems to be a separate code path for Thumb here, involving
> a special STACK_LIMIT symbol by the looks of it. Thumb's got MRC
> instructions too, so you should probably be using those.

According to our initial pull request [1], it sounded like the Thumb
support was specifically targeting not using a coprocessor for the
stack limit. It sounds like the stack limit can be in any number of
locations, and it should have some configuration which dictates how
you find it. Do you think this configuration should be added, and if
so, what would be the best way to do that?

>> On x86 at least the __morestack function is invoked with an unaligned
>> stack. I wouldn't consider myself an expert on this function, but all
>> examples I've seen write __morestack in assembly, so I don't think
>> it's meant to be written in something like C (as in, I don't think it
>> expects an aligned stack).
>
> But doesn't it then jump back to this callee in some weird way? Unless
> it specifically realigns the stack, the rest of the program is going
> to be non-conformant.

The x86 implementation at least specifically re-aligns the stack
before doing anything else (calling the stack allocation function).

> +    AddDefaultPred(BuildMI(AllocMBB, DL, TII.get(ARM::tPOP)))
> +      .addReg(ScratchReg0);
> +
> +    // mov lr, SR0
> +    AddDefaultPred(BuildMI(AllocMBB, DL, TII.get(ARM::tMOVr), ARM::LR)
> +                   .addReg(ScratchReg0));
>
> If you use t2LDMIA_UPD here you save an instruction (LR can be used
> directly) and make the sequence more similar between ARM & Thumb.

Good catch! I have updated the push to use STMDB_UPD as well to make
sure that the push/pop are symmetrical.

I also changed the initial push/last pop to not have a big if
statement for arm/thumb by using this opcode as well.

> +    AddDefaultPred(BuildMI(AllocMBB, DL, TII.get(ARM::tMOVr), ARM::PC)
> +                   .addReg(ARM::LR));
>
> These need to be "bx lr" instructions otherwise Thumb-interworking
> will be broken: "mov pc, lr" doesn't switch to/from thumb mode if
> needed. An alternative would be to fold it into the push/pop
> instructions, though that would mean always pushing 4 regs (3 + 1 for
> alignment) since the last one has to be lr for that to work. Something
> like:

I agree that for speed this should probably stick to only pushing 2
regs at the beginning of the function, but I've changed this to using
"bx" instead of "mov.


[1] - https://github.com/rust-lang/llvm/pull/4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arm-segstk.patch
Type: application/octet-stream
Size: 31955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140227/19ac7e03/attachment.obj>


More information about the llvm-commits mailing list