xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric // WebAssemblyFrameLowering.h - TargetFrameLowering for WebAssembly -*- C++ -*-/
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// This class implements WebAssembly-specific bits of
110b57cec5SDimitry Andric /// TargetFrameLowering class.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYFRAMELOWERING_H
160b57cec5SDimitry Andric #define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYFRAMELOWERING_H
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric class WebAssemblyFrameLowering final : public TargetFrameLowering {
230b57cec5SDimitry Andric public:
240b57cec5SDimitry Andric   /// Size of the red zone for the user stack (leaf functions can use this much
250b57cec5SDimitry Andric   /// space below the stack pointer without writing it back to __stack_pointer
260b57cec5SDimitry Andric   /// global).
270b57cec5SDimitry Andric   // TODO: (ABI) Revisit and decide how large it should be.
280b57cec5SDimitry Andric   static const size_t RedZoneSize = 128;
290b57cec5SDimitry Andric 
WebAssemblyFrameLowering()300b57cec5SDimitry Andric   WebAssemblyFrameLowering()
318bcb0991SDimitry Andric       : TargetFrameLowering(StackGrowsDown, /*StackAlignment=*/Align(16),
320b57cec5SDimitry Andric                             /*LocalAreaOffset=*/0,
338bcb0991SDimitry Andric                             /*TransientStackAlignment=*/Align(16),
340b57cec5SDimitry Andric                             /*StackRealignable=*/true) {}
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   MachineBasicBlock::iterator
370b57cec5SDimitry Andric   eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
380b57cec5SDimitry Andric                                 MachineBasicBlock::iterator I) const override;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   /// These methods insert prolog and epilog code into the function.
410b57cec5SDimitry Andric   void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
420b57cec5SDimitry Andric   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric   bool hasFP(const MachineFunction &MF) const override;
450b57cec5SDimitry Andric   bool hasReservedCallFrame(const MachineFunction &MF) const override;
46fe6060f1SDimitry Andric   bool isSupportedStackID(TargetStackID::Value ID) const override;
475ffd83dbSDimitry Andric   DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   bool needsPrologForEH(const MachineFunction &MF) const;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   /// Write SP back to __stack_pointer global.
520b57cec5SDimitry Andric   void writeSPToGlobal(unsigned SrcReg, MachineFunction &MF,
530b57cec5SDimitry Andric                        MachineBasicBlock &MBB,
540b57cec5SDimitry Andric                        MachineBasicBlock::iterator &InsertStore,
550b57cec5SDimitry Andric                        const DebugLoc &DL) const;
560b57cec5SDimitry Andric 
57fe6060f1SDimitry Andric   // Returns the index of the WebAssembly local to which the stack object
58*bdd1243dSDimitry Andric   // FrameIndex in MF should be allocated, or std::nullopt.
59*bdd1243dSDimitry Andric   static std::optional<unsigned> getLocalForStackObject(MachineFunction &MF,
60fe6060f1SDimitry Andric                                                         int FrameIndex);
61fe6060f1SDimitry Andric 
625ffd83dbSDimitry Andric   static unsigned getSPReg(const MachineFunction &MF);
635ffd83dbSDimitry Andric   static unsigned getFPReg(const MachineFunction &MF);
645ffd83dbSDimitry Andric   static unsigned getOpcConst(const MachineFunction &MF);
655ffd83dbSDimitry Andric   static unsigned getOpcAdd(const MachineFunction &MF);
665ffd83dbSDimitry Andric   static unsigned getOpcSub(const MachineFunction &MF);
675ffd83dbSDimitry Andric   static unsigned getOpcAnd(const MachineFunction &MF);
685ffd83dbSDimitry Andric   static unsigned getOpcGlobGet(const MachineFunction &MF);
695ffd83dbSDimitry Andric   static unsigned getOpcGlobSet(const MachineFunction &MF);
705ffd83dbSDimitry Andric 
710b57cec5SDimitry Andric private:
720b57cec5SDimitry Andric   bool hasBP(const MachineFunction &MF) const;
730b57cec5SDimitry Andric   bool needsSPForLocalFrame(const MachineFunction &MF) const;
740b57cec5SDimitry Andric   bool needsSP(const MachineFunction &MF) const;
750b57cec5SDimitry Andric   bool needsSPWriteback(const MachineFunction &MF) const;
760b57cec5SDimitry Andric };
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric } // end namespace llvm
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric #endif
81