llvm.org GIT mirror llvm / ddbde80
ARM: support stack probe emission for Windows on ARM This introduces the stack lowering emission of the stack probe function for Windows on ARM. The stack on Windows on ARM is a dynamically paged stack where any page allocation which crosses a page boundary of the following guard page will cause a page fault. This page fault must be handled by the kernel to ensure that the page is faulted in. If this does not occur and a write access any memory beyond that, the page fault will go unserviced, resulting in an abnormal program termination. The watermark for the stack probe appears to be at 4080 bytes (for accommodating the stack guard canaries and stack alignment) when SSP is enabled. Otherwise, the stack probe is emitted on the page size boundary of 4096 bytes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207615 91177308-0d34-0410-b5e6-96231b3b80d8 Saleem Abdulrasool 6 years ago
3 changed file(s) with 114 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
158158 .globl Symbol2
159159 Symbol2:
160160 .long 1
161
162 Target Specific Behaviour
163 =========================
164
165 Windows on ARM
166 --------------
167
168 Stack Probe Emission
169 ^^^^^^^^^^^^^^^^^^^^
170
171 The reference implementation (Microsoft Visual Studio 2012) emits stack probes
172 in the following fashion:
173
174 .. code-block:: gas
175
176 movw r4, #constant
177 bl __chkstk
178 sub.w sp, sp, r4
179
180 However, this has the limitation of 32 MiB (±16MiB). In order to accomodate
181 larger binaries, LLVM supports the use of ``-mcode-model=large`` to allow a 4GiB
182 range via a slight deviation. It will generate an indirect jump as follows:
183
184 .. code-block:: gas
185
186 movw r4, #constant
187 movw r12, :lower16:__chkstk
188 movt r12, :upper16:__chkstk
189 blx r12
190 sub.w sp, sp, r4
191
2424 #include "llvm/CodeGen/RegisterScavenging.h"
2525 #include "llvm/IR/CallingConv.h"
2626 #include "llvm/IR/Function.h"
27 #include "llvm/IR/Module.h"
2728 #include "llvm/MC/MCContext.h"
2829 #include "llvm/Support/CommandLine.h"
2930 #include "llvm/Target/TargetOptions.h"
141142 return count;
142143 }
143144
145 static bool WindowsRequiresStackProbe(const MachineFunction &MF,
146 size_t StackSizeInBytes) {
147 const MachineFrameInfo *MFI = MF.getFrameInfo();
148 if (MFI->getStackProtectorIndex() > 0)
149 return StackSizeInBytes >= 4080;
150 return StackSizeInBytes >= 4096;
151 }
152
144153 void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
145154 MachineBasicBlock &MBB = MF.front();
146155 MachineBasicBlock::iterator MBBI = MBB.begin();
148157 ARMFunctionInfo *AFI = MF.getInfo();
149158 MachineModuleInfo &MMI = MF.getMMI();
150159 MCContext &Context = MMI.getContext();
160 const TargetMachine &TM = MF.getTarget();
151161 const MCRegisterInfo *MRI = Context.getRegisterInfo();
152162 const ARMBaseRegisterInfo *RegInfo =
153 static_cast(MF.getTarget().getRegisterInfo());
163 static_cast(TM.getRegisterInfo());
154164 const ARMBaseInstrInfo &TII =
155 *static_cast(MF.getTarget().getInstrInfo());
165 *static_cast(TM.getInstrInfo());
156166 assert(!AFI->isThumb1OnlyFunction() &&
157167 "This emitPrologue does not support Thumb1!");
158168 bool isARM = !AFI->isThumbFunction();
159 unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment();
169 unsigned Align = TM.getFrameLowering()->getStackAlignment();
160170 unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align);
161171 unsigned NumBytes = MFI->getStackSize();
162172 const std::vector &CSI = MFI->getCalleeSavedInfo();
186196 .addCFIIndex(CFIIndex);
187197 }
188198
189 if (!AFI->hasStackFrame()) {
199 if (!AFI->hasStackFrame() &&
200 (!STI.isTargetWindows() || !WindowsRequiresStackProbe(MF, NumBytes))) {
190201 if (NumBytes - ArgRegsSaveSize != 0) {
191202 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -(NumBytes - ArgRegsSaveSize),
192203 MachineInstr::FrameSetup);
282293 NumBytes += MFI->getObjectOffset(D8SpillFI);
283294 } else
284295 NumBytes = DPRCSOffset;
296
297 if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, NumBytes)) {
298 uint32_t NumWords = NumBytes >> 2;
299
300 if (NumWords < 65536)
301 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi16), ARM::R4)
302 .addImm(NumWords));
303 else
304 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R4)
305 .addImm(NumWords);
306
307 switch (TM.getCodeModel()) {
308 case CodeModel::Small:
309 case CodeModel::Medium:
310 case CodeModel::Default:
311 case CodeModel::Kernel:
312 BuildMI(MBB, MBBI, dl, TII.get(ARM::tBL))
313 .addImm((unsigned)ARMCC::AL).addReg(0)
314 .addExternalSymbol("__chkstk")
315 .addReg(ARM::R4, RegState::Implicit);
316 break;
317 case CodeModel::Large:
318 case CodeModel::JITDefault: {
319 LLVMContext &Ctx = MF.getMMI().getModule()->getContext();
320 const GlobalValue *F =
321 Function::Create(FunctionType::get(Type::getVoidTy(Ctx), false),
322 GlobalValue::AvailableExternallyLinkage, "__chkstk");
323
324 BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), ARM::R12)
325 .addGlobalAddress(F);
326 BuildMI(MBB, MBBI, dl, TII.get(ARM::BLX))
327 .addReg(ARM::R12, RegState::Kill)
328 .addReg(ARM::R4, RegState::Implicit);
329 break;
330 }
331 }
332
333 AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::t2SUBrr),
334 ARM::SP)
335 .addReg(ARM::SP, RegState::Define)
336 .addReg(ARM::R4, RegState::Kill)
337 .setMIFlags(MachineInstr::FrameSetup)));
338 NumBytes = 0;
339 }
285340
286341 unsigned adjustedGPRCS1Size = GPRCS1Size;
287342 if (NumBytes) {
0 ; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 %s -o - \
1 ; RUN: | FileCheck -check-prefix CHECK-DEFAULT-CODE-MODEL %s
2
3 ; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -code-model=large %s -o - \
4 ; RUN: | FileCheck -check-prefix CHECK-LARGE-CODE-MODEL %s
5
6 define arm_aapcs_vfpcc void @check_watermark() {
7 entry:
8 %buffer = alloca [4096 x i8], align 1
9 ret void
10 }
11
12 ; CHECK-DEFAULT-CODE-MODEL: check_watermark:
13 ; CHECK-DEFAULT-CODE-MODEL: movw r4, #1024
14 ; CHECK-DEFAULT-CODE-MODEL: bl __chkstk
15 ; CHECK-DEFAULT-CODE-MODEL: sub.w sp, sp, r4
16
17 ; CHECK-LARGE-CODE-MODEL: check_watermark:
18 ; CHECK-LARGE-CODE-MODEL: movw r4, #1024
19 ; CHECK-LARGE-CODE-MODEL: movw r12, :lower16:__chkstk
20 ; CHECK-LARGE-CODE-MODEL: movt r12, :upper16:__chkstk
21 ; CHECK-LARGE-CODE-MODEL: blx r12
22 ; CHECK-LARGE-CODE-MODEL: sub.w sp, sp, r4
23