Re: [rust-dev] [PATCH] Add stack overflow check for ARM Thumb instruction set.

2014-02-16 Thread Svetoslav Neykov
I don't find any of the ARM split stack changes in the LLVM tree, just a
single 
patch to the llvm-commits a year ago with no followup.
(http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20130318/168838
.html)
Since my changes depend on the ARM changes it doesn't make sense to try to
merge 
them before the previous changes are accepted.

I guess I should use the rust-llvm-2014-02-11 branch as the base for my PR?

Svetoslav.


-Original Message-
From: alexc...@gmail.com [mailto:alexc...@gmail.com] On Behalf Of Alex
Crichton
Sent: Sunday, February 16, 2014 1:16 AM
To: Svetoslav Neykov
Cc: rust-dev@mozilla.org
Subject: Re: [rust-dev] [PATCH] Add stack overflow check for ARM Thumb
instruction set.

For LLVM patches, we prefer if you have first attempted to upstream
the patch with LLVM before we push it to our local fork. This normally
entails emailing the llvm-commits mailing list. Once this upstream
attempt has been made, you can open a PR against the rust-lang/llvm
repo on github.

This looks pretty awesome though, nice work!


On Sat, Feb 15, 2014 at 8:36 AM, Svetoslav Neykov svetos...@neykov.name
wrote:
 Hi,

 I am working on getting Rust to directly compile code for bare metal ARM
 devices working in Thumb mode. I created a patch for LLVM to emit
 the appropriate function prologue. Since I couldn't find instructions on
how
 to submit the change for review and inclusion in the Rust's copy of LLVM I
 am sending it here on the dev mailing list.

 Besides the mechanincal differences between the ARM and Thumb functions,
 because of the different instruction sets, there is difference in how the
 stack limit is located. The ARM version uses hardware which isn't
available
 on the lower-end Thumb processors (namely system co-processor and MMU)
 therefore I am looking for the stack limit at a predefined location in
 memory - STACK_LIMIT. It is the responsibility of the wrapping runtime
 to manage this location with the correct value. It can vary from a simple
 constant defined by the linker to actively managed variable by a RTOS
 implementation.
 (thanks to whitequark for discussing the possible approaches)

 There is an old pull request for Rust which was the precursor to this
change
 located at https://github.com/mozilla/rust/pull/10942. Once the patch is
 accepted I will try to update it to the latest changes in the repository.

 Here is the patch itself:


===

 Add stack overflow check for ARM Thumb instruction set.

 The code assumes that the stack limit will be located at the
 address labeled STACK_LIMIT.
 ---
  lib/Target/ARM/ARMFrameLowering.cpp | 184
+++-
  lib/Target/ARM/ARMFrameLowering.h   |   2 +
  2 files changed, 185 insertions(+), 1 deletion(-)

 diff --git a/lib/Target/ARM/ARMFrameLowering.cpp
b/lib/Target/ARM/ARMFrameLowering.cpp
 index bdf0480..c286228 100644
 --- a/lib/Target/ARM/ARMFrameLowering.cpp
 +++ b/lib/Target/ARM/ARMFrameLowering.cpp
 @@ -14,6 +14,7 @@
  #include ARMFrameLowering.h
  #include ARMBaseInstrInfo.h
  #include ARMBaseRegisterInfo.h
 +#include ARMConstantPoolValue.h
  #include ARMInstrInfo.h
  #include ARMMachineFunctionInfo.h
  #include ARMTargetMachine.h
 @@ -1481,10 +1482,20 @@ static uint32_t AlignToARMConstant(uint32_t Value)
{
  // stack limit.
  static const uint64_t kSplitStackAvailable = 256;

 +void
 +ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +  const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();
 +  if(ST-isThumb()) {
 +adjustForSegmentedStacksThumb(MF);
 +  } else {
 +adjustForSegmentedStacksARM(MF);
 +  }
 +}
 +
  // Adjust function prologue to enable split stack.
  // Only support android and linux.
  void
 -ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +ARMFrameLowering::adjustForSegmentedStacksARM(MachineFunction MF) const
{
const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();

// Doesn't support vararg function.
 @@ -1697,3 +1708,174 @@
ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
MF.verify();
  #endif
  }
 +
 +void
 +ARMFrameLowering::adjustForSegmentedStacksThumb(MachineFunction MF)
const {
 +//  const ARMSubtarget *ST =
MF.getTarget().getSubtargetARMSubtarget();
 +
 +  // Doesn't support vararg function.
 +  if (MF.getFunction()-isVarArg())
 +report_fatal_error(Segmented stacks do not support vararg
functions.);
 +
 +  MachineBasicBlock prologueMBB = MF.front();
 +  MachineFrameInfo* MFI = MF.getFrameInfo();
 +  const ARMBaseInstrInfo TII = *TM.getInstrInfo();
 +  ARMFunctionInfo* ARMFI = MF.getInfoARMFunctionInfo();
 +  DebugLoc DL;
 +
 +  // Use R4 and R5 as scratch register.
 +  // We should save R4 and R5 before use it and restore before
 +  // leave the function.
 +  unsigned ScratchReg0 = ARM::R4;
 +  unsigned ScratchReg1 = ARM::R5;
 +  uint64_t AlignedStackSize;
 +
 +  MachineBasicBlock

Re: [rust-dev] [PATCH] Add stack overflow check for ARM Thumb instruction set.

2014-02-16 Thread Alex Crichton
Yes, if you use rust-llvm-2014-02-11 as the base of the PR I can merge
it in and update the LLVM that rust is using.

On Sun, Feb 16, 2014 at 4:08 AM, Svetoslav Neykov svetos...@neykov.name wrote:
 I don't find any of the ARM split stack changes in the LLVM tree, just a
 single
 patch to the llvm-commits a year ago with no followup.
 (http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20130318/168838
 .html)
 Since my changes depend on the ARM changes it doesn't make sense to try to
 merge
 them before the previous changes are accepted.

 I guess I should use the rust-llvm-2014-02-11 branch as the base for my PR?

 Svetoslav.


 -Original Message-
 From: alexc...@gmail.com [mailto:alexc...@gmail.com] On Behalf Of Alex
 Crichton
 Sent: Sunday, February 16, 2014 1:16 AM
 To: Svetoslav Neykov
 Cc: rust-dev@mozilla.org
 Subject: Re: [rust-dev] [PATCH] Add stack overflow check for ARM Thumb
 instruction set.

 For LLVM patches, we prefer if you have first attempted to upstream
 the patch with LLVM before we push it to our local fork. This normally
 entails emailing the llvm-commits mailing list. Once this upstream
 attempt has been made, you can open a PR against the rust-lang/llvm
 repo on github.

 This looks pretty awesome though, nice work!


 On Sat, Feb 15, 2014 at 8:36 AM, Svetoslav Neykov svetos...@neykov.name
 wrote:
 Hi,

 I am working on getting Rust to directly compile code for bare metal ARM
 devices working in Thumb mode. I created a patch for LLVM to emit
 the appropriate function prologue. Since I couldn't find instructions on
 how
 to submit the change for review and inclusion in the Rust's copy of LLVM I
 am sending it here on the dev mailing list.

 Besides the mechanincal differences between the ARM and Thumb functions,
 because of the different instruction sets, there is difference in how the
 stack limit is located. The ARM version uses hardware which isn't
 available
 on the lower-end Thumb processors (namely system co-processor and MMU)
 therefore I am looking for the stack limit at a predefined location in
 memory - STACK_LIMIT. It is the responsibility of the wrapping runtime
 to manage this location with the correct value. It can vary from a simple
 constant defined by the linker to actively managed variable by a RTOS
 implementation.
 (thanks to whitequark for discussing the possible approaches)

 There is an old pull request for Rust which was the precursor to this
 change
 located at https://github.com/mozilla/rust/pull/10942. Once the patch is
 accepted I will try to update it to the latest changes in the repository.

 Here is the patch itself:

 
 ===

 Add stack overflow check for ARM Thumb instruction set.

 The code assumes that the stack limit will be located at the
 address labeled STACK_LIMIT.
 ---
  lib/Target/ARM/ARMFrameLowering.cpp | 184
 +++-
  lib/Target/ARM/ARMFrameLowering.h   |   2 +
  2 files changed, 185 insertions(+), 1 deletion(-)

 diff --git a/lib/Target/ARM/ARMFrameLowering.cpp
 b/lib/Target/ARM/ARMFrameLowering.cpp
 index bdf0480..c286228 100644
 --- a/lib/Target/ARM/ARMFrameLowering.cpp
 +++ b/lib/Target/ARM/ARMFrameLowering.cpp
 @@ -14,6 +14,7 @@
  #include ARMFrameLowering.h
  #include ARMBaseInstrInfo.h
  #include ARMBaseRegisterInfo.h
 +#include ARMConstantPoolValue.h
  #include ARMInstrInfo.h
  #include ARMMachineFunctionInfo.h
  #include ARMTargetMachine.h
 @@ -1481,10 +1482,20 @@ static uint32_t AlignToARMConstant(uint32_t Value)
 {
  // stack limit.
  static const uint64_t kSplitStackAvailable = 256;

 +void
 +ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +  const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();
 +  if(ST-isThumb()) {
 +adjustForSegmentedStacksThumb(MF);
 +  } else {
 +adjustForSegmentedStacksARM(MF);
 +  }
 +}
 +
  // Adjust function prologue to enable split stack.
  // Only support android and linux.
  void
 -ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +ARMFrameLowering::adjustForSegmentedStacksARM(MachineFunction MF) const
 {
const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();

// Doesn't support vararg function.
 @@ -1697,3 +1708,174 @@
 ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
MF.verify();
  #endif
  }
 +
 +void
 +ARMFrameLowering::adjustForSegmentedStacksThumb(MachineFunction MF)
 const {
 +//  const ARMSubtarget *ST =
 MF.getTarget().getSubtargetARMSubtarget();
 +
 +  // Doesn't support vararg function.
 +  if (MF.getFunction()-isVarArg())
 +report_fatal_error(Segmented stacks do not support vararg
 functions.);
 +
 +  MachineBasicBlock prologueMBB = MF.front();
 +  MachineFrameInfo* MFI = MF.getFrameInfo();
 +  const ARMBaseInstrInfo TII = *TM.getInstrInfo();
 +  ARMFunctionInfo* ARMFI = MF.getInfoARMFunctionInfo();
 +  DebugLoc DL;
 +
 +  // Use R4 and R5

Re: [rust-dev] [PATCH] Add stack overflow check for ARM Thumb instruction set.

2014-02-15 Thread Alex Crichton
For LLVM patches, we prefer if you have first attempted to upstream
the patch with LLVM before we push it to our local fork. This normally
entails emailing the llvm-commits mailing list. Once this upstream
attempt has been made, you can open a PR against the rust-lang/llvm
repo on github.

This looks pretty awesome though, nice work!


On Sat, Feb 15, 2014 at 8:36 AM, Svetoslav Neykov svetos...@neykov.name wrote:
 Hi,

 I am working on getting Rust to directly compile code for bare metal ARM
 devices working in Thumb mode. I created a patch for LLVM to emit
 the appropriate function prologue. Since I couldn't find instructions on how
 to submit the change for review and inclusion in the Rust's copy of LLVM I
 am sending it here on the dev mailing list.

 Besides the mechanincal differences between the ARM and Thumb functions,
 because of the different instruction sets, there is difference in how the
 stack limit is located. The ARM version uses hardware which isn't available
 on the lower-end Thumb processors (namely system co-processor and MMU)
 therefore I am looking for the stack limit at a predefined location in
 memory - STACK_LIMIT. It is the responsibility of the wrapping runtime
 to manage this location with the correct value. It can vary from a simple
 constant defined by the linker to actively managed variable by a RTOS
 implementation.
 (thanks to whitequark for discussing the possible approaches)

 There is an old pull request for Rust which was the precursor to this change
 located at https://github.com/mozilla/rust/pull/10942. Once the patch is
 accepted I will try to update it to the latest changes in the repository.

 Here is the patch itself:
 ===

 Add stack overflow check for ARM Thumb instruction set.

 The code assumes that the stack limit will be located at the
 address labeled STACK_LIMIT.
 ---
  lib/Target/ARM/ARMFrameLowering.cpp | 184 
 +++-
  lib/Target/ARM/ARMFrameLowering.h   |   2 +
  2 files changed, 185 insertions(+), 1 deletion(-)

 diff --git a/lib/Target/ARM/ARMFrameLowering.cpp 
 b/lib/Target/ARM/ARMFrameLowering.cpp
 index bdf0480..c286228 100644
 --- a/lib/Target/ARM/ARMFrameLowering.cpp
 +++ b/lib/Target/ARM/ARMFrameLowering.cpp
 @@ -14,6 +14,7 @@
  #include ARMFrameLowering.h
  #include ARMBaseInstrInfo.h
  #include ARMBaseRegisterInfo.h
 +#include ARMConstantPoolValue.h
  #include ARMInstrInfo.h
  #include ARMMachineFunctionInfo.h
  #include ARMTargetMachine.h
 @@ -1481,10 +1482,20 @@ static uint32_t AlignToARMConstant(uint32_t Value) {
  // stack limit.
  static const uint64_t kSplitStackAvailable = 256;

 +void
 +ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +  const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();
 +  if(ST-isThumb()) {
 +adjustForSegmentedStacksThumb(MF);
 +  } else {
 +adjustForSegmentedStacksARM(MF);
 +  }
 +}
 +
  // Adjust function prologue to enable split stack.
  // Only support android and linux.
  void
 -ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
 +ARMFrameLowering::adjustForSegmentedStacksARM(MachineFunction MF) const {
const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();

// Doesn't support vararg function.
 @@ -1697,3 +1708,174 @@ 
 ARMFrameLowering::adjustForSegmentedStacks(MachineFunction MF) const {
MF.verify();
  #endif
  }
 +
 +void
 +ARMFrameLowering::adjustForSegmentedStacksThumb(MachineFunction MF) const {
 +//  const ARMSubtarget *ST = MF.getTarget().getSubtargetARMSubtarget();
 +
 +  // Doesn't support vararg function.
 +  if (MF.getFunction()-isVarArg())
 +report_fatal_error(Segmented stacks do not support vararg functions.);
 +
 +  MachineBasicBlock prologueMBB = MF.front();
 +  MachineFrameInfo* MFI = MF.getFrameInfo();
 +  const ARMBaseInstrInfo TII = *TM.getInstrInfo();
 +  ARMFunctionInfo* ARMFI = MF.getInfoARMFunctionInfo();
 +  DebugLoc DL;
 +
 +  // Use R4 and R5 as scratch register.
 +  // We should save R4 and R5 before use it and restore before
 +  // leave the function.
 +  unsigned ScratchReg0 = ARM::R4;
 +  unsigned ScratchReg1 = ARM::R5;
 +  uint64_t AlignedStackSize;
 +
 +  MachineBasicBlock* prevStackMBB = MF.CreateMachineBasicBlock();
 +  MachineBasicBlock* postStackMBB = MF.CreateMachineBasicBlock();
 +  MachineBasicBlock* allocMBB = MF.CreateMachineBasicBlock();
 +  MachineBasicBlock* getMBB = MF.CreateMachineBasicBlock();
 +  MachineBasicBlock* mcrMBB = MF.CreateMachineBasicBlock();
 +  MachineBasicBlock* magicMBB = MF.CreateMachineBasicBlock();
 +
 +  for (MachineBasicBlock::livein_iterator i = prologueMBB.livein_begin(),
 + e = prologueMBB.livein_end(); i != e; ++i) {
 +allocMBB-addLiveIn(*i);
 +getMBB-addLiveIn(*i);
 +magicMBB-addLiveIn(*i);
 +mcrMBB-addLiveIn(*i);
 +prevStackMBB-addLiveIn(*i);
 +postStackMBB-addLiveIn(*i);
 +  }
 +
 +