[LLVMdev] ARMFrameLowering::adjustForSegmentedStacks is broken in several places

Vladimir Pouzanov farcaller at gmail.com
Thu May 1 10:47:00 PDT 2014


I'm working with rust based embedded stack, and I got a few issues with
current implementation of ARMFrameLowering::adjustForSegmentedStacks.

There are two places where prologue expects to find the stack limit. If the
CPU supports thumb 1 only, stack limit is loaded from a global symbol
__STACK_LIMIT. Otherwise it's read from the coprocessor (two available
platform-specific options are linux and android).

There is a problem with a bunch of Cortex-M MCUs, as all of them support at
least a few thumb 2 instructions but don't have a coprocessor, so the first
way to get stack limit should be used.

The first thing that must be changed is that if CPU is a cortex-m, the
stack limit should be taken from a global symbol __STACK_LIMIT. I have a
trivial patch for this, albeit without tests. As of now, llvm produces
machine code, which is not executable and results in cpu fault.

The second problem is that llvm expects that there is at least 256 bytes
(defined in kSplitStackAvailable) after the stack end available for scratch
purposes. I don't really see the reasoning behind this check at all, it's
not that it drastically reduces the size of prologue. The problem is that
each stack must be 256 bytes bigger, a big price if you have stacks of 512
bytes.

As I don't see a reason to have this check in a first place, I suggest to
completely remove it. Alternatively, it should be some kind of a flag, that
could be passed down to specify the "scratch size".

Here's the trivial patch for the first issue:

diff --git a/lib/Target/ARM/ARMFrameLowering.cpp
b/lib/Target/ARM/ARMFrameLowering.cpp
index c18e741..325a124 100644
--- a/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/lib/Target/ARM/ARMFrameLowering.cpp
@@ -1774,7 +1774,8 @@ void
ARMFrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
                       .addReg(ARM::SP).addImm(AlignedStackSize)).addReg(0);
   }

-  if (Thumb && ST->isThumb1Only()) {
+  if ((Thumb && ST->isThumb1Only()) ||
+      ST->getCPUString().find("cortex-m") == 0) {
     unsigned PCLabelId = ARMFI->createPICLabelUId();
     ARMConstantPoolValue *NewCPV = ARMConstantPoolSymbol::Create(
         MF.getFunction()->getContext(), "__STACK_LIMIT", PCLabelId, 0);

Please advice on what do I need to do to get this submitted or otherwise
fixed.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140501/ab48b844/attachment.html>


More information about the llvm-dev mailing list