1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[VE][NFC] Clean stack frame description

Move stack frame description from VESubtarget.cpp to VEFrameLowering.cpp
and add detail.

Reviewed By: simoll

Differential Revision: https://reviews.llvm.org/D91946
This commit is contained in:
Kazushi (Jam) Marukawa 2020-11-22 19:49:45 +09:00
parent 1a23665577
commit 79162fb8e4
2 changed files with 101 additions and 44 deletions

View File

@ -8,6 +8,105 @@
// //
// This file contains the VE implementation of TargetFrameLowering class. // This file contains the VE implementation of TargetFrameLowering class.
// //
// On VE, stack frames are structured as follows:
//
// The stack grows downward.
//
// All of the individual frame areas on the frame below are optional, i.e. it's
// possible to create a function so that the particular area isn't present
// in the frame.
//
// At function entry, the "frame" looks as follows:
//
// | | Higher address
// |----------------------------------------------|
// | Parameter area for this function |
// |----------------------------------------------|
// | Register save area (RSA) for this function |
// |----------------------------------------------|
// | Return address for this function |
// |----------------------------------------------|
// | Frame pointer for this function |
// |----------------------------------------------| <- sp
// | | Lower address
//
// VE doesn't use on demand stack allocation, so user code generated by LLVM
// needs to call VEOS to allocate stack frame. VE's ABI want to reduce the
// number of VEOS calls, so ABI requires to allocate not only RSA (in general
// CSR, callee saved register) area but also call frame at the prologue of
// caller function.
//
// After the prologue has run, the frame has the following general structure.
// Note that technically the last frame area (VLAs) doesn't get created until
// in the main function body, after the prologue is run. However, it's depicted
// here for completeness.
//
// | | Higher address
// |----------------------------------------------|
// | Parameter area for this function |
// |----------------------------------------------|
// | Register save area (RSA) for this function |
// |----------------------------------------------|
// | Return address for this function |
// |----------------------------------------------|
// | Frame pointer for this function |
// |----------------------------------------------| <- fp(=old sp)
// |.empty.space.to.make.part.below.aligned.in....|
// |.case.it.needs.more.than.the.standard.16-byte.| (size of this area is
// |.alignment....................................| unknown at compile time)
// |----------------------------------------------|
// | Local variables of fixed size including spill|
// | slots |
// |----------------------------------------------| <- bp(not defined by ABI,
// |.variable-sized.local.variables.(VLAs)........| LLVM chooses SX17)
// |..............................................| (size of this area is
// |..............................................| unknown at compile time)
// |----------------------------------------------| <- stack top (returned by
// | Parameter area for callee | alloca)
// |----------------------------------------------|
// | Register save area (RSA) for callee |
// |----------------------------------------------|
// | Return address for callee |
// |----------------------------------------------|
// | Frame pointer for callee |
// |----------------------------------------------| <- sp
// | | Lower address
//
// To access the data in a frame, at-compile time, a constant offset must be
// computable from one of the pointers (fp, bp, sp) to access it. The size
// of the areas with a dotted background cannot be computed at compile-time
// if they are present, making it required to have all three of fp, bp and
// sp to be set up to be able to access all contents in the frame areas,
// assuming all of the frame areas are non-empty.
//
// For most functions, some of the frame areas are empty. For those functions,
// it may not be necessary to set up fp or bp:
// * A base pointer is definitely needed when there are both VLAs and local
// variables with more-than-default alignment requirements.
// * A frame pointer is definitely needed when there are local variables with
// more-than-default alignment requirements.
//
// In addition, VE ABI defines RSA frame, return address, and frame pointer
// as follows:
//
// |----------------------------------------------| <- sp+176
// | %s18...%s33 |
// |----------------------------------------------| <- sp+48
// | Linkage area register (%s17) |
// |----------------------------------------------| <- sp+40
// | Procedure linkage table register (%plt=%s16) |
// |----------------------------------------------| <- sp+32
// | Global offset table register (%got=%s15) |
// |----------------------------------------------| <- sp+24
// | Thread pointer register (%tp=%s14) |
// |----------------------------------------------| <- sp+16
// | Return address |
// |----------------------------------------------| <- sp+8
// | Frame pointer |
// |----------------------------------------------| <- sp+0
//
// NOTE: This description is based on VE ABI and description in
// AArch64FrameLowering.cpp. Thanks a lot.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "VEFrameLowering.h" #include "VEFrameLowering.h"

View File

@ -48,50 +48,8 @@ VESubtarget::VESubtarget(const Triple &TT, const std::string &CPU,
FrameLowering(*this) {} FrameLowering(*this) {}
uint64_t VESubtarget::getAdjustedFrameSize(uint64_t FrameSize) const { uint64_t VESubtarget::getAdjustedFrameSize(uint64_t FrameSize) const {
// Calculate adjusted frame size by adding the size of RSA frame,
// VE stack frame: // return address, and frame poitner as described in VEFrameLowering.cpp.
//
// +----------------------------------------+
// | Locals and temporaries |
// +----------------------------------------+
// | Parameter area for callee |
// 176(fp) | |
// +----------------------------------------+
// | Register save area (RSA) for callee |
// | |
// 16(fp) | 20 * 8 bytes |
// +----------------------------------------+
// 8(fp) | Return address |
// +----------------------------------------+
// 0(fp) | Frame pointer of caller |
// --------+----------------------------------------+--------
// | Locals and temporaries for callee |
// +----------------------------------------+
// | Parameter area for callee of callee |
// +----------------------------------------+
// 16(sp) | RSA for callee of callee |
// +----------------------------------------+
// 8(sp) | Return address |
// +----------------------------------------+
// 0(sp) | Frame pointer of callee |
// +----------------------------------------+
// RSA frame:
// +----------------------------------------------+
// 168(fp) | %s33 |
// +----------------------------------------------+
// | %s19...%s32 |
// +----------------------------------------------+
// 48(fp) | %s18 |
// +----------------------------------------------+
// 40(fp) | Linkage area register (%s17) |
// +----------------------------------------------+
// 32(fp) | Procedure linkage table register (%plt=%s16) |
// +----------------------------------------------+
// 24(fp) | Global offset table register (%got=%s15) |
// +----------------------------------------------+
// 16(fp) | Thread pointer register (%tp=%s14) |
// +----------------------------------------------+
FrameSize += 176; // For RSA, RA, and FP. FrameSize += 176; // For RSA, RA, and FP.
FrameSize = alignTo(FrameSize, 16); // Requires 16 bytes alignment. FrameSize = alignTo(FrameSize, 16); // Requires 16 bytes alignment.