mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-08 23:55:03 +00:00
Foundation for call frame information.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27491 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
38ab6d887c
commit
4188699f80
@ -41,10 +41,13 @@ class DIE;
|
|||||||
class DIEAbbrev;
|
class DIEAbbrev;
|
||||||
class GlobalVariableDesc;
|
class GlobalVariableDesc;
|
||||||
class MachineDebugInfo;
|
class MachineDebugInfo;
|
||||||
class MachineLocation;
|
|
||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
|
class MachineLocation;
|
||||||
|
class MachineMove;
|
||||||
class Module;
|
class Module;
|
||||||
|
class MRegisterInfo;
|
||||||
class SubprogramDesc;
|
class SubprogramDesc;
|
||||||
|
class TargetData;
|
||||||
class Type;
|
class Type;
|
||||||
class TypeDesc;
|
class TypeDesc;
|
||||||
|
|
||||||
@ -81,6 +84,12 @@ protected:
|
|||||||
///
|
///
|
||||||
AsmPrinter *Asm;
|
AsmPrinter *Asm;
|
||||||
|
|
||||||
|
/// TD - Target data.
|
||||||
|
const TargetData &TD;
|
||||||
|
|
||||||
|
/// RI - Register Information.
|
||||||
|
const MRegisterInfo *RI;
|
||||||
|
|
||||||
/// M - Current module.
|
/// M - Current module.
|
||||||
///
|
///
|
||||||
Module *M;
|
Module *M;
|
||||||
@ -324,7 +333,8 @@ private:
|
|||||||
|
|
||||||
/// AddAddress - Add an address attribute to a die based on the location
|
/// AddAddress - Add an address attribute to a die based on the location
|
||||||
/// provided.
|
/// provided.
|
||||||
void AddAddress(DIE *Die, unsigned Attribute, MachineLocation &Location);
|
void AddAddress(DIE *Die, unsigned Attribute,
|
||||||
|
const MachineLocation &Location);
|
||||||
|
|
||||||
/// NewType - Create a new type DIE.
|
/// NewType - Create a new type DIE.
|
||||||
///
|
///
|
||||||
@ -375,6 +385,11 @@ private:
|
|||||||
///
|
///
|
||||||
void SizeAndOffsets();
|
void SizeAndOffsets();
|
||||||
|
|
||||||
|
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
|
||||||
|
/// frame.
|
||||||
|
void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
|
||||||
|
std::vector<MachineMove *> &Moves);
|
||||||
|
|
||||||
/// EmitDebugInfo - Emit the debug info section.
|
/// EmitDebugInfo - Emit the debug info section.
|
||||||
///
|
///
|
||||||
void EmitDebugInfo() const;
|
void EmitDebugInfo() const;
|
||||||
@ -387,9 +402,13 @@ private:
|
|||||||
///
|
///
|
||||||
void EmitDebugLines() const;
|
void EmitDebugLines() const;
|
||||||
|
|
||||||
/// EmitDebugFrame - Emit info into a debug frame section.
|
/// EmitInitialDebugFrame - Emit common frame info into a debug frame section.
|
||||||
///
|
///
|
||||||
void EmitDebugFrame();
|
void EmitInitialDebugFrame();
|
||||||
|
|
||||||
|
/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame
|
||||||
|
/// section.
|
||||||
|
void EmitFunctionDebugFrame();
|
||||||
|
|
||||||
/// EmitDebugPubNames - Emit info into a debug pubnames section.
|
/// EmitDebugPubNames - Emit info into a debug pubnames section.
|
||||||
///
|
///
|
||||||
@ -439,7 +458,7 @@ public:
|
|||||||
|
|
||||||
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
|
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
|
||||||
/// created it. Set by the target AsmPrinter.
|
/// created it. Set by the target AsmPrinter.
|
||||||
void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; }
|
void SetDebugInfo(MachineDebugInfo *DI);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Main entry points.
|
// Main entry points.
|
||||||
|
@ -47,6 +47,8 @@ namespace llvm {
|
|||||||
class Constant;
|
class Constant;
|
||||||
class DebugInfoDesc;
|
class DebugInfoDesc;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
|
class MachineFunction;
|
||||||
|
class MachineMove;
|
||||||
class Module;
|
class Module;
|
||||||
class PointerType;
|
class PointerType;
|
||||||
class StructType;
|
class StructType;
|
||||||
@ -574,7 +576,7 @@ public:
|
|||||||
void setName(const std::string &N) { Name = N; }
|
void setName(const std::string &N) { Name = N; }
|
||||||
void setFile(CompileUnitDesc *U) { File = U; }
|
void setFile(CompileUnitDesc *U) { File = U; }
|
||||||
void setLine(unsigned L) { Line = L; }
|
void setLine(unsigned L) { Line = L; }
|
||||||
void setTypeDesc(TypeDesc *T) { TyDesc = T; }
|
void setType(TypeDesc *T) { TyDesc = T; }
|
||||||
void setIsStatic(bool IS) { IsStatic = IS; }
|
void setIsStatic(bool IS) { IsStatic = IS; }
|
||||||
void setIsDefinition(bool ID) { IsDefinition = ID; }
|
void setIsDefinition(bool ID) { IsDefinition = ID; }
|
||||||
|
|
||||||
@ -941,6 +943,10 @@ private:
|
|||||||
//
|
//
|
||||||
DebugScope *RootScope;
|
DebugScope *RootScope;
|
||||||
|
|
||||||
|
// FrameMoves - List of moves done by a function's prolog. Used to construct
|
||||||
|
// frame maps by debug consumers.
|
||||||
|
std::vector<MachineMove *> FrameMoves;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MachineDebugInfo();
|
MachineDebugInfo();
|
||||||
~MachineDebugInfo();
|
~MachineDebugInfo();
|
||||||
@ -953,6 +959,14 @@ public:
|
|||||||
///
|
///
|
||||||
bool doFinalization();
|
bool doFinalization();
|
||||||
|
|
||||||
|
/// BeginFunction - Begin gathering function debug information.
|
||||||
|
///
|
||||||
|
void BeginFunction(MachineFunction *MF);
|
||||||
|
|
||||||
|
/// EndFunction - Discard function debug information.
|
||||||
|
///
|
||||||
|
void EndFunction();
|
||||||
|
|
||||||
/// getDescFor - Convert a Value to a debug information descriptor.
|
/// getDescFor - Convert a Value to a debug information descriptor.
|
||||||
///
|
///
|
||||||
// FIXME - use new Value type when available.
|
// FIXME - use new Value type when available.
|
||||||
@ -1061,9 +1075,9 @@ public:
|
|||||||
///
|
///
|
||||||
DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
|
DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
|
||||||
|
|
||||||
/// ClearScopes - Delete the scope and variable info after a function is
|
/// getFrameMoves - Returns a reference to a list of moves done in the current
|
||||||
/// completed.
|
/// function's prologue. Used to construct frame maps for debug comsumers.
|
||||||
void ClearScopes();
|
std::vector<MachineMove *> &getFrameMoves() { return FrameMoves; }
|
||||||
|
|
||||||
}; // End class MachineDebugInfo
|
}; // End class MachineDebugInfo
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ namespace llvm {
|
|||||||
class TargetData;
|
class TargetData;
|
||||||
class TargetRegisterClass;
|
class TargetRegisterClass;
|
||||||
class Type;
|
class Type;
|
||||||
|
class MachineDebugInfo;
|
||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
|
|
||||||
class MachineFrameInfo {
|
class MachineFrameInfo {
|
||||||
@ -106,12 +107,21 @@ class MachineFrameInfo {
|
|||||||
/// insertion.
|
/// insertion.
|
||||||
///
|
///
|
||||||
unsigned MaxCallFrameSize;
|
unsigned MaxCallFrameSize;
|
||||||
|
|
||||||
|
/// DebugInfo - This field is set (via setMachineDebugInfo) by a debug info
|
||||||
|
/// consumer (ex. DwarfWriter) to indicate that frame layout information
|
||||||
|
/// should be acquired. Typically, it's the responsibility of the target's
|
||||||
|
/// MRegisterInfo prologue/epilogue emitting code to inform MachineDebugInfo
|
||||||
|
/// of frame layouts.
|
||||||
|
MachineDebugInfo *DebugInfo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MachineFrameInfo() {
|
MachineFrameInfo() {
|
||||||
NumFixedObjects = StackSize = MaxAlignment = 0;
|
NumFixedObjects = StackSize = MaxAlignment = 0;
|
||||||
HasVarSizedObjects = false;
|
HasVarSizedObjects = false;
|
||||||
HasCalls = false;
|
HasCalls = false;
|
||||||
MaxCallFrameSize = 0;
|
MaxCallFrameSize = 0;
|
||||||
|
DebugInfo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// hasStackObjects - Return true if there are any stack objects in this
|
/// hasStackObjects - Return true if there are any stack objects in this
|
||||||
@ -230,6 +240,14 @@ public:
|
|||||||
return Objects.size()-NumFixedObjects-1;
|
return Objects.size()-NumFixedObjects-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getMachineDebugInfo - Used by a prologue/epilogue emitter (MRegisterInfo)
|
||||||
|
/// to provide frame layout information.
|
||||||
|
MachineDebugInfo *getMachineDebugInfo() const { return DebugInfo; }
|
||||||
|
|
||||||
|
/// setMachineDebugInfo - Used by a debug consumer (DwarfWriter) to indicate
|
||||||
|
/// that frame layout information should be gathered.
|
||||||
|
void setMachineDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; }
|
||||||
|
|
||||||
/// print - Used by the MachineFunction printer to print information about
|
/// print - Used by the MachineFunction printer to print information about
|
||||||
/// stack objects. Implemented in MachineFunction.cpp
|
/// stack objects. Implemented in MachineFunction.cpp
|
||||||
///
|
///
|
||||||
|
@ -8,7 +8,13 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// The MachineLocation class is used to represent a simple location in a machine
|
// The MachineLocation class is used to represent a simple location in a machine
|
||||||
// frame. Locations will be one of two forms; a register or an address formed
|
// frame. Locations will be one of two forms; a register or an address formed
|
||||||
// from a base address plus an offset.
|
// from a base address plus an offset. Register indirection can be specified by
|
||||||
|
// using an offset of zero.
|
||||||
|
//
|
||||||
|
// The MachineMove class is used to represent abstract move operations in the
|
||||||
|
// prolog/epilog of a compiled function. A collection of these objects can be
|
||||||
|
// used by a debug consumer to track the location of values when unwinding stack
|
||||||
|
// frames.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
|
||||||
@ -24,6 +30,11 @@ private:
|
|||||||
int Offset; // Displacement if not register.
|
int Offset; // Displacement if not register.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum {
|
||||||
|
// The target register number for an abstract frame pointer. The value is
|
||||||
|
// an arbitrary value greater than MRegisterInfo::FirstVirtualRegister.
|
||||||
|
VirtualFP = ~0U
|
||||||
|
};
|
||||||
MachineLocation()
|
MachineLocation()
|
||||||
: IsRegister(false)
|
: IsRegister(false)
|
||||||
, Register(0)
|
, Register(0)
|
||||||
@ -37,7 +48,7 @@ public:
|
|||||||
MachineLocation(unsigned R, int O)
|
MachineLocation(unsigned R, int O)
|
||||||
: IsRegister(false)
|
: IsRegister(false)
|
||||||
, Register(R)
|
, Register(R)
|
||||||
, Offset(0)
|
, Offset(O)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
@ -57,6 +68,31 @@ public:
|
|||||||
Register = R;
|
Register = R;
|
||||||
Offset = O;
|
Offset = O;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
void dump();
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class MachineMove {
|
||||||
|
private:
|
||||||
|
unsigned LabelID; // Label ID number for post-instruction
|
||||||
|
// address when result of move takes
|
||||||
|
// effect.
|
||||||
|
const MachineLocation Destination; // Move to location.
|
||||||
|
const MachineLocation Source; // Move from location.
|
||||||
|
|
||||||
|
public:
|
||||||
|
MachineMove(unsigned ID, MachineLocation &D, MachineLocation &S)
|
||||||
|
: LabelID(ID)
|
||||||
|
, Destination(D)
|
||||||
|
, Source(S)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
unsigned getLabelID() const { return LabelID; }
|
||||||
|
const MachineLocation &getDestination() const { return Destination; }
|
||||||
|
const MachineLocation &getSource() const { return Source; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -27,6 +27,7 @@ class Type;
|
|||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class MachineLocation;
|
class MachineLocation;
|
||||||
|
class MachineMove;
|
||||||
class TargetRegisterClass;
|
class TargetRegisterClass;
|
||||||
|
|
||||||
/// TargetRegisterDesc - This record contains all of the information known about
|
/// TargetRegisterDesc - This record contains all of the information known about
|
||||||
@ -346,17 +347,34 @@ public:
|
|||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
/// Debug information queries.
|
/// Debug information queries.
|
||||||
|
|
||||||
|
/// getDwarfRegNum - Map a target register to an equivalent dwarf register
|
||||||
|
/// number. Returns -1 if there is no equivalent value.
|
||||||
|
virtual int getDwarfRegNum(unsigned RegNum) const = 0;
|
||||||
|
|
||||||
/// getFrameRegister - This method should return the register used as a base
|
/// getFrameRegister - This method should return the register used as a base
|
||||||
/// for values allocated in the current stack frame. This value should be
|
/// for values allocated in the current stack frame.
|
||||||
/// returned as a dwarf register number (getDwarfRegNum.)
|
|
||||||
virtual unsigned getFrameRegister(MachineFunction &MF) const = 0;
|
virtual unsigned getFrameRegister(MachineFunction &MF) const = 0;
|
||||||
|
|
||||||
|
/// getRARegister - This method should return the register where the return
|
||||||
|
/// address can be found.
|
||||||
|
virtual unsigned getRARegister() const = 0;
|
||||||
|
|
||||||
|
/// getStackDirection - This method should return the factor by which stacks
|
||||||
|
/// grow. The tyical value is -4 which is the grows negatively in 4 byte
|
||||||
|
/// increments.
|
||||||
|
virtual int getStackDirection() const;
|
||||||
|
|
||||||
/// getLocation - This method should return the actual location of a frame
|
/// getLocation - This method should return the actual location of a frame
|
||||||
/// variable given the frame index. The location is returned in ML.
|
/// variable given the frame index. The location is returned in ML.
|
||||||
/// Subclasses should override this method for special handling of frame
|
/// Subclasses should override this method for special handling of frame
|
||||||
/// variables and call MRegisterInfo::getLocation for the default action.
|
/// variables and call MRegisterInfo::getLocation for the default action.
|
||||||
virtual void getLocation(MachineFunction &MF, unsigned Index,
|
virtual void getLocation(MachineFunction &MF, unsigned Index,
|
||||||
MachineLocation &ML) const;
|
MachineLocation &ML) const;
|
||||||
|
|
||||||
|
/// getInitialFrameState - Returns a list of machine moves that are assumed
|
||||||
|
/// on entry to all functions. Note that LabelID is ignored (assumed to be
|
||||||
|
/// the beginning of the function.)
|
||||||
|
virtual void getInitialFrameState(std::vector<MachineMove *> &Moves) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is useful when building DenseMaps keyed on virtual registers
|
// This is useful when building DenseMaps keyed on virtual registers
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include "llvm/CodeGen/AsmPrinter.h"
|
#include "llvm/CodeGen/AsmPrinter.h"
|
||||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineLocation.h"
|
#include "llvm/CodeGen/MachineLocation.h"
|
||||||
#include "llvm/Support/Dwarf.h"
|
#include "llvm/Support/Dwarf.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@ -1073,8 +1074,6 @@ void DwarfWriter::EmitInt64(uint64_t Value) const {
|
|||||||
if (Asm->Data64bitsDirective) {
|
if (Asm->Data64bitsDirective) {
|
||||||
O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
|
O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
|
||||||
} else {
|
} else {
|
||||||
const TargetData &TD = Asm->TM.getTargetData();
|
|
||||||
|
|
||||||
if (TD.isBigEndian()) {
|
if (TD.isBigEndian()) {
|
||||||
EmitInt32(unsigned(Value >> 32)); O << "\n";
|
EmitInt32(unsigned(Value >> 32)); O << "\n";
|
||||||
EmitInt32(unsigned(Value));
|
EmitInt32(unsigned(Value));
|
||||||
@ -1216,12 +1215,14 @@ void DwarfWriter::AddSourceLine(DIE *Die, CompileUnitDesc *File, unsigned Line)
|
|||||||
/// AddAddress - Add an address attribute to a die based on the location
|
/// AddAddress - Add an address attribute to a die based on the location
|
||||||
/// provided.
|
/// provided.
|
||||||
void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute,
|
void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute,
|
||||||
MachineLocation &Location) {
|
const MachineLocation &Location) {
|
||||||
DIEBlock *Block = new DIEBlock();
|
DIEBlock *Block = new DIEBlock();
|
||||||
if (Location.isRegister()) {
|
if (Location.isRegister()) {
|
||||||
Block->AddUInt(DW_FORM_data1, DW_OP_reg0 + Location.getRegister());
|
Block->AddUInt(DW_FORM_data1,
|
||||||
|
DW_OP_reg0 + RI->getDwarfRegNum(Location.getRegister()));
|
||||||
} else {
|
} else {
|
||||||
Block->AddUInt(DW_FORM_data1, DW_OP_breg0 + Location.getRegister());
|
Block->AddUInt(DW_FORM_data1,
|
||||||
|
DW_OP_breg0 + RI->getDwarfRegNum(Location.getRegister()));
|
||||||
Block->AddUInt(DW_FORM_sdata, Location.getOffset());
|
Block->AddUInt(DW_FORM_sdata, Location.getOffset());
|
||||||
}
|
}
|
||||||
Block->ComputeSize(*this);
|
Block->ComputeSize(*this);
|
||||||
@ -1358,8 +1359,7 @@ DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) {
|
|||||||
// Now normalize offset to the field.
|
// Now normalize offset to the field.
|
||||||
Offset -= FieldOffset;
|
Offset -= FieldOffset;
|
||||||
|
|
||||||
// Maybe we need to work from the other.
|
// Maybe we need to work from the other end.
|
||||||
const TargetData &TD = Asm->TM.getTargetData();
|
|
||||||
if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size);
|
if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size);
|
||||||
|
|
||||||
Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3);
|
Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3);
|
||||||
@ -1515,8 +1515,11 @@ DIE *DwarfWriter::NewSubprogram(SubprogramDesc *SPD) {
|
|||||||
|
|
||||||
DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
|
DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
|
||||||
SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name);
|
SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name);
|
||||||
|
if (Type) {
|
||||||
SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
|
SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
|
||||||
|
}
|
||||||
SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, IsExternal);
|
SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, IsExternal);
|
||||||
|
SubprogramDie->AddUInt (DW_AT_prototyped, DW_FORM_flag, 1);
|
||||||
|
|
||||||
// Add source line info if available.
|
// Add source line info if available.
|
||||||
AddSourceLine(SubprogramDie, UnitDesc, SPD->getLine());
|
AddSourceLine(SubprogramDie, UnitDesc, SPD->getLine());
|
||||||
@ -1561,7 +1564,7 @@ DIE *DwarfWriter::NewScopeVariable(DebugVariable *DV, CompileUnit *Unit) {
|
|||||||
|
|
||||||
// Add variable address.
|
// Add variable address.
|
||||||
MachineLocation Location;
|
MachineLocation Location;
|
||||||
Asm->TM.getRegisterInfo()->getLocation(*MF, DV->getFrameIndex(), Location);
|
RI->getLocation(*MF, DV->getFrameIndex(), Location);
|
||||||
AddAddress(VariableDie, DW_AT_location, Location);
|
AddAddress(VariableDie, DW_AT_location, Location);
|
||||||
|
|
||||||
return VariableDie;
|
return VariableDie;
|
||||||
@ -1623,16 +1626,18 @@ void DwarfWriter::ConstructRootScope(DebugScope *RootScope) {
|
|||||||
CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(SPD->getContext());
|
CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(SPD->getContext());
|
||||||
CompileUnit *Unit = FindCompileUnit(UnitDesc);
|
CompileUnit *Unit = FindCompileUnit(UnitDesc);
|
||||||
|
|
||||||
|
// Generate the mangled name.
|
||||||
|
std::string MangledName = Asm->Mang->getValueName(MF->getFunction());
|
||||||
|
|
||||||
// Get the subprogram die.
|
// Get the subprogram die.
|
||||||
DIE *SPDie = Unit->getDieMapSlotFor(SPD);
|
DIE *SPDie = Unit->getDieMapSlotFor(SPD);
|
||||||
assert(SPDie && "Missing subprogram descriptor");
|
assert(SPDie && "Missing subprogram descriptor");
|
||||||
|
|
||||||
// Add the function bounds.
|
// Add the function bounds.
|
||||||
SPDie->AddLabel(DW_AT_low_pc, DW_FORM_addr,
|
SPDie->AddObjectLabel(DW_AT_low_pc, DW_FORM_addr, MangledName);
|
||||||
DWLabel("func_begin", SubprogramCount));
|
|
||||||
SPDie->AddLabel(DW_AT_high_pc, DW_FORM_addr,
|
SPDie->AddLabel(DW_AT_high_pc, DW_FORM_addr,
|
||||||
DWLabel("func_end", SubprogramCount));
|
DWLabel("func_end", SubprogramCount));
|
||||||
MachineLocation Location(Asm->TM.getRegisterInfo()->getFrameRegister(*MF));
|
MachineLocation Location(RI->getFrameRegister(*MF));
|
||||||
AddAddress(SPDie, DW_AT_frame_base, Location);
|
AddAddress(SPDie, DW_AT_frame_base, Location);
|
||||||
|
|
||||||
ConstructScope(RootScope, SPDie, Unit);
|
ConstructScope(RootScope, SPDie, Unit);
|
||||||
@ -1792,6 +1797,50 @@ void DwarfWriter::SizeAndOffsets() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
|
||||||
|
/// frame.
|
||||||
|
void DwarfWriter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
|
||||||
|
std::vector<MachineMove *> &Moves) {
|
||||||
|
for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
|
||||||
|
MachineMove *Move = Moves[i];
|
||||||
|
unsigned LabelID = Move->getLabelID();
|
||||||
|
const MachineLocation &Dst = Move->getDestination();
|
||||||
|
const MachineLocation &Src = Move->getSource();
|
||||||
|
|
||||||
|
// Advance row if new location.
|
||||||
|
if (BaseLabel && LabelID && BaseLabelID != LabelID) {
|
||||||
|
EmitULEB128Bytes(DW_CFA_advance_loc4);
|
||||||
|
EOL("DW_CFA_advance_loc4");
|
||||||
|
EmitDifference("loc", LabelID, BaseLabel, BaseLabelID);
|
||||||
|
EOL("");
|
||||||
|
|
||||||
|
BaseLabelID = LabelID;
|
||||||
|
BaseLabel = "loc";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If advancing cfa.
|
||||||
|
if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
|
||||||
|
if (!Src.isRegister()) {
|
||||||
|
if (Src.getRegister() == MachineLocation::VirtualFP) {
|
||||||
|
EmitULEB128Bytes(DW_CFA_def_cfa_offset);
|
||||||
|
EOL("DW_CFA_def_cfa_offset");
|
||||||
|
} else {
|
||||||
|
EmitULEB128Bytes(DW_CFA_def_cfa);
|
||||||
|
EOL("DW_CFA_def_cfa");
|
||||||
|
|
||||||
|
EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister()));
|
||||||
|
EOL("Register");
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitULEB128Bytes(Src.getOffset() / RI->getStackDirection());
|
||||||
|
EOL("Offset");
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitDebugInfo - Emit the debug info section.
|
/// EmitDebugInfo - Emit the debug info section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugInfo() const {
|
void DwarfWriter::EmitDebugInfo() const {
|
||||||
@ -1999,10 +2048,10 @@ void DwarfWriter::EmitDebugLines() const {
|
|||||||
O << "\n";
|
O << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// EmitDebugFrame - Emit visible names into a debug frame section.
|
/// EmitInitialDebugFrame - Emit common frame info into a debug frame section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugFrame() {
|
void DwarfWriter::EmitInitialDebugFrame() {
|
||||||
// Start the dwarf pubnames section.
|
// Start the dwarf frame section.
|
||||||
Asm->SwitchSection(DwarfFrameSection, 0);
|
Asm->SwitchSection(DwarfFrameSection, 0);
|
||||||
|
|
||||||
EmitDifference("frame_common_end", 0,
|
EmitDifference("frame_common_end", 0,
|
||||||
@ -2014,20 +2063,49 @@ void DwarfWriter::EmitDebugFrame() {
|
|||||||
EmitInt8(DW_CIE_VERSION); EOL("CIE Version");
|
EmitInt8(DW_CIE_VERSION); EOL("CIE Version");
|
||||||
EmitString(""); EOL("CIE Augmentation");
|
EmitString(""); EOL("CIE Augmentation");
|
||||||
EmitULEB128Bytes(1); EOL("CIE Code Alignment Factor");
|
EmitULEB128Bytes(1); EOL("CIE Code Alignment Factor");
|
||||||
// FIXME - needs to change based on stack direction.
|
EmitSLEB128Bytes(RI->getStackDirection()); EOL("CIE Data Alignment Factor");
|
||||||
EmitSLEB128Bytes(-sizeof(int32_t)); EOL("CIE Data Alignment Factor");
|
EmitInt8(RI->getDwarfRegNum(RI->getRARegister())); EOL("CIE RA Column");
|
||||||
// FIXME - hard coded for PPC (LR).
|
|
||||||
EmitInt8(0x41); EOL("CIE RA Column Hardcoded (PPC LR)");
|
std::vector<MachineMove *> Moves;
|
||||||
// FIXME - hard coded for PPC 0(SP).
|
RI->getInitialFrameState(Moves);
|
||||||
EmitULEB128Bytes(DW_CFA_def_cfa); EOL("DW_CFA_def_cfa");
|
EmitFrameMoves(NULL, 0, Moves);
|
||||||
EmitULEB128Bytes(1); EOL("PPC Register SP");
|
for (unsigned i = 0, N = Moves.size(); i < N; ++i) delete Moves[i];
|
||||||
EmitULEB128Bytes(0); EOL("PPC offset 0 as in 0(SP)");
|
|
||||||
EmitAlign(2);
|
EmitAlign(2);
|
||||||
EmitLabel("frame_common_end", 0);
|
EmitLabel("frame_common_end", 0);
|
||||||
|
|
||||||
O << "\n";
|
O << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame
|
||||||
|
/// section.
|
||||||
|
void DwarfWriter::EmitFunctionDebugFrame() {
|
||||||
|
// Start the dwarf frame section.
|
||||||
|
Asm->SwitchSection(DwarfFrameSection, 0);
|
||||||
|
|
||||||
|
EmitDifference("frame_end", SubprogramCount,
|
||||||
|
"frame_begin", SubprogramCount);
|
||||||
|
EOL("Length of Frame Information Entry");
|
||||||
|
|
||||||
|
EmitLabel("frame_begin", SubprogramCount);
|
||||||
|
|
||||||
|
EmitReference("section_frame", 0); EOL("FDE CIE offset");
|
||||||
|
|
||||||
|
EmitReference("func_begin", SubprogramCount); EOL("FDE initial location");
|
||||||
|
EmitDifference("func_end", SubprogramCount,
|
||||||
|
"func_begin", SubprogramCount);
|
||||||
|
EOL("FDE address range");
|
||||||
|
|
||||||
|
std::vector<MachineMove *> &Moves = DebugInfo->getFrameMoves();
|
||||||
|
|
||||||
|
EmitFrameMoves("func_begin", SubprogramCount, Moves);
|
||||||
|
|
||||||
|
EmitAlign(2);
|
||||||
|
EmitLabel("frame_end", SubprogramCount);
|
||||||
|
|
||||||
|
O << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
/// EmitDebugPubNames - Emit visible names into a debug pubnames section.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EmitDebugPubNames() {
|
void DwarfWriter::EmitDebugPubNames() {
|
||||||
@ -2208,6 +2286,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
if (!didInitial) {
|
if (!didInitial) {
|
||||||
EmitInitial();
|
EmitInitial();
|
||||||
|
|
||||||
|
// Emit common frame information.
|
||||||
|
EmitInitialDebugFrame();
|
||||||
|
|
||||||
// Create all the compile unit DIEs.
|
// Create all the compile unit DIEs.
|
||||||
ConstructCompileUnitDIEs();
|
ConstructCompileUnitDIEs();
|
||||||
|
|
||||||
@ -2231,6 +2312,8 @@ bool DwarfWriter::ShouldEmitDwarf() {
|
|||||||
DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
|
DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
|
||||||
: O(OS)
|
: O(OS)
|
||||||
, Asm(A)
|
, Asm(A)
|
||||||
|
, TD(Asm->TM.getTargetData())
|
||||||
|
, RI(Asm->TM.getRegisterInfo())
|
||||||
, M(NULL)
|
, M(NULL)
|
||||||
, MF(NULL)
|
, MF(NULL)
|
||||||
, DebugInfo(NULL)
|
, DebugInfo(NULL)
|
||||||
@ -2267,6 +2350,12 @@ DwarfWriter::~DwarfWriter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
|
||||||
|
/// created it. Set by the target AsmPrinter.
|
||||||
|
void DwarfWriter::SetDebugInfo(MachineDebugInfo *DI) {
|
||||||
|
DebugInfo = DI;
|
||||||
|
}
|
||||||
|
|
||||||
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
/// BeginModule - Emit all Dwarf sections that should come prior to the content.
|
||||||
///
|
///
|
||||||
void DwarfWriter::BeginModule(Module *M) {
|
void DwarfWriter::BeginModule(Module *M) {
|
||||||
@ -2300,9 +2389,6 @@ void DwarfWriter::EndModule() {
|
|||||||
// Emit source line correspondence into a debug line section.
|
// Emit source line correspondence into a debug line section.
|
||||||
EmitDebugLines();
|
EmitDebugLines();
|
||||||
|
|
||||||
// Emit info into a debug frame section.
|
|
||||||
EmitDebugFrame();
|
|
||||||
|
|
||||||
// Emit info into a debug pubnames section.
|
// Emit info into a debug pubnames section.
|
||||||
EmitDebugPubNames();
|
EmitDebugPubNames();
|
||||||
|
|
||||||
@ -2327,6 +2413,9 @@ void DwarfWriter::EndModule() {
|
|||||||
void DwarfWriter::BeginFunction(MachineFunction *MF) {
|
void DwarfWriter::BeginFunction(MachineFunction *MF) {
|
||||||
this->MF = MF;
|
this->MF = MF;
|
||||||
|
|
||||||
|
// Begin accumulating function debug information.
|
||||||
|
DebugInfo->BeginFunction(MF);
|
||||||
|
|
||||||
if (!ShouldEmitDwarf()) return;
|
if (!ShouldEmitDwarf()) return;
|
||||||
EOL("Dwarf Begin Function");
|
EOL("Dwarf Begin Function");
|
||||||
|
|
||||||
@ -2335,7 +2424,6 @@ void DwarfWriter::BeginFunction(MachineFunction *MF) {
|
|||||||
EmitLabel("func_begin", ++SubprogramCount);
|
EmitLabel("func_begin", ++SubprogramCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// EndFunction - Gather and emit post-function debug information.
|
/// EndFunction - Gather and emit post-function debug information.
|
||||||
///
|
///
|
||||||
void DwarfWriter::EndFunction() {
|
void DwarfWriter::EndFunction() {
|
||||||
@ -2348,5 +2436,10 @@ void DwarfWriter::EndFunction() {
|
|||||||
|
|
||||||
// Construct scopes for subprogram.
|
// Construct scopes for subprogram.
|
||||||
ConstructRootScope(DebugInfo->getRootScope());
|
ConstructRootScope(DebugInfo->getRootScope());
|
||||||
DebugInfo->ClearScopes();
|
|
||||||
|
// Emit function frame information.
|
||||||
|
EmitFunctionDebugFrame();
|
||||||
|
|
||||||
|
// Clear function debug information.
|
||||||
|
DebugInfo->EndFunction();
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "llvm/CodeGen/MachineDebugInfo.h"
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
|
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/CodeGen/MachineLocation.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/GlobalVariable.h"
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/Intrinsics.h"
|
#include "llvm/Intrinsics.h"
|
||||||
@ -1424,9 +1425,8 @@ MachineDebugInfo::MachineDebugInfo()
|
|||||||
, LabelID(0)
|
, LabelID(0)
|
||||||
, ScopeMap()
|
, ScopeMap()
|
||||||
, RootScope(NULL)
|
, RootScope(NULL)
|
||||||
{
|
, FrameMoves()
|
||||||
|
{}
|
||||||
}
|
|
||||||
MachineDebugInfo::~MachineDebugInfo() {
|
MachineDebugInfo::~MachineDebugInfo() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1443,6 +1443,27 @@ bool MachineDebugInfo::doFinalization() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// BeginFunction - Begin gathering function debug information.
|
||||||
|
///
|
||||||
|
void MachineDebugInfo::BeginFunction(MachineFunction *MF) {
|
||||||
|
// Coming soon.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MachineDebugInfo::EndFunction - Discard function debug information.
|
||||||
|
///
|
||||||
|
void MachineDebugInfo::EndFunction() {
|
||||||
|
// Clean up scope information.
|
||||||
|
if (RootScope) {
|
||||||
|
delete RootScope;
|
||||||
|
ScopeMap.clear();
|
||||||
|
RootScope = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up frame info.
|
||||||
|
for (unsigned i = 0, N = FrameMoves.size(); i < N; ++i) delete FrameMoves[i];
|
||||||
|
FrameMoves.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// getDescFor - Convert a Value to a debug information descriptor.
|
/// getDescFor - Convert a Value to a debug information descriptor.
|
||||||
///
|
///
|
||||||
// FIXME - use new Value type when available.
|
// FIXME - use new Value type when available.
|
||||||
@ -1565,14 +1586,4 @@ DebugScope *MachineDebugInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
|
|||||||
return Slot;
|
return Slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ClearScopes - Delete the scope and variable info after a function is
|
|
||||||
/// completed.
|
|
||||||
void MachineDebugInfo::ClearScopes() {
|
|
||||||
if (RootScope) {
|
|
||||||
delete RootScope;
|
|
||||||
ScopeMap.clear();
|
|
||||||
RootScope = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,12 @@ namespace {
|
|||||||
/// frame indexes with appropriate references.
|
/// frame indexes with appropriate references.
|
||||||
///
|
///
|
||||||
bool runOnMachineFunction(MachineFunction &Fn) {
|
bool runOnMachineFunction(MachineFunction &Fn) {
|
||||||
|
// Get MachineDebugInfo so that we can track the construction of the
|
||||||
|
// frame.
|
||||||
|
if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
|
||||||
|
Fn.getFrameInfo()->setMachineDebugInfo(DI);
|
||||||
|
}
|
||||||
|
|
||||||
// Scan the function for modified caller saved registers and insert spill
|
// Scan the function for modified caller saved registers and insert spill
|
||||||
// code for any caller saved registers that are modified. Also calculate
|
// code for any caller saved registers that are modified. Also calculate
|
||||||
// the MaxCallFrameSize and HasCalls variables for the function's frame
|
// the MaxCallFrameSize and HasCalls variables for the function's frame
|
||||||
|
@ -354,8 +354,13 @@ void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned AlphaRegisterInfo::getRARegister() const {
|
||||||
|
assert(0 && "What is the return address register");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
return getDwarfRegNum(hasFP(MF) ? Alpha::R15 : Alpha::R30);
|
return hasFP(MF) ? Alpha::R15 : Alpha::R30;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "AlphaGenRegisterInfo.inc"
|
#include "AlphaGenRegisterInfo.inc"
|
||||||
|
@ -54,6 +54,7 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
|
|||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
|
|
||||||
static std::string getPrettyName(unsigned reg);
|
static std::string getPrettyName(unsigned reg);
|
||||||
|
@ -329,8 +329,13 @@ void IA64RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned IA64RegisterInfo::getRARegister() const {
|
||||||
|
assert(0 && "What is the return address register");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
return getDwarfRegNum(hasFP(MF) ? IA64::r5 : IA64::r12);
|
return hasFP(MF) ? IA64::r5 : IA64::r12;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "IA64GenRegisterInfo.inc"
|
#include "IA64GenRegisterInfo.inc"
|
||||||
|
@ -50,6 +50,7 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo {
|
|||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,6 +44,13 @@ std::vector<bool> MRegisterInfo::getAllocatableSet(MachineFunction &MF) const {
|
|||||||
return Allocatable;
|
return Allocatable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getStackDirection - This method should return the factor by which stacks
|
||||||
|
/// grow. The tyical value is -4 which is the grows negatively in 4 byte
|
||||||
|
/// increments.
|
||||||
|
int MRegisterInfo::getStackDirection() const {
|
||||||
|
return -sizeof(int32_t);
|
||||||
|
}
|
||||||
|
|
||||||
/// getLocation - This method should return the actual location of a frame
|
/// getLocation - This method should return the actual location of a frame
|
||||||
/// variable given the frame index. The location is returned in ML.
|
/// variable given the frame index. The location is returned in ML.
|
||||||
/// Subclasses should override this method for special handling of frame
|
/// Subclasses should override this method for special handling of frame
|
||||||
@ -54,3 +61,11 @@ void MRegisterInfo::getLocation(MachineFunction &MF, unsigned Index,
|
|||||||
ML.set(getFrameRegister(MF),
|
ML.set(getFrameRegister(MF),
|
||||||
MFI->getObjectOffset(Index) + MFI->getStackSize());
|
MFI->getObjectOffset(Index) + MFI->getStackSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getInitialFrameState - Returns a list of machine moves that are assumed
|
||||||
|
/// on entry to a function.
|
||||||
|
void
|
||||||
|
MRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves) const {
|
||||||
|
// Default is to do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,11 @@
|
|||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
#include "llvm/CodeGen/ValueTypes.h"
|
#include "llvm/CodeGen/ValueTypes.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
#include "llvm/CodeGen/MachineDebugInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineLocation.h"
|
#include "llvm/CodeGen/MachineLocation.h"
|
||||||
|
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||||
#include "llvm/Target/TargetFrameInfo.h"
|
#include "llvm/Target/TargetFrameInfo.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetOptions.h"
|
#include "llvm/Target/TargetOptions.h"
|
||||||
@ -339,6 +341,7 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MachineDebugInfo *DebugInfo = MFI->getMachineDebugInfo();
|
||||||
|
|
||||||
// Do we have a frame pointer for this function?
|
// Do we have a frame pointer for this function?
|
||||||
bool HasFP = hasFP(MF);
|
bool HasFP = hasFP(MF);
|
||||||
@ -390,13 +393,13 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
|
|
||||||
// Update frame info to pretend that this is part of the stack...
|
// Update frame info to pretend that this is part of the stack...
|
||||||
MFI->setStackSize(NumBytes);
|
MFI->setStackSize(NumBytes);
|
||||||
|
int NegNumbytes = -NumBytes;
|
||||||
|
|
||||||
// Adjust stack pointer: r1 -= numbytes.
|
// Adjust stack pointer: r1 -= numbytes.
|
||||||
if (NumBytes <= 32768) {
|
if (NumBytes <= 32768) {
|
||||||
BuildMI(MBB, MBBI, PPC::STWU, 3)
|
BuildMI(MBB, MBBI, PPC::STWU, 3)
|
||||||
.addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
|
.addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
|
||||||
} else {
|
} else {
|
||||||
int NegNumbytes = -NumBytes;
|
|
||||||
BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
|
BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
|
||||||
BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
|
BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
|
||||||
.addReg(PPC::R0).addImm(NegNumbytes & 0xFFFF);
|
.addReg(PPC::R0).addImm(NegNumbytes & 0xFFFF);
|
||||||
@ -404,6 +407,18 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
.addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
|
.addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DebugInfo) {
|
||||||
|
std::vector<MachineMove *> &Moves = DebugInfo->getFrameMoves();
|
||||||
|
unsigned LabelID = DebugInfo->NextLabelID();
|
||||||
|
|
||||||
|
// Show update of SP.
|
||||||
|
MachineLocation Dst(MachineLocation::VirtualFP);
|
||||||
|
MachineLocation Src(MachineLocation::VirtualFP, NegNumbytes);
|
||||||
|
Moves.push_back(new MachineMove(LabelID, Dst, Src));
|
||||||
|
|
||||||
|
BuildMI(MBB, MBBI, PPC::DWARF_LABEL, 1).addSImm(LabelID);
|
||||||
|
}
|
||||||
|
|
||||||
// If there is a preferred stack alignment, align R1 now
|
// If there is a preferred stack alignment, align R1 now
|
||||||
// FIXME: If this ever matters, this could be made more efficient by folding
|
// FIXME: If this ever matters, this could be made more efficient by folding
|
||||||
// this into the code above, so that we don't issue two store+update
|
// this into the code above, so that we don't issue two store+update
|
||||||
@ -458,8 +473,20 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PPCRegisterInfo::getRARegister() const {
|
||||||
|
return PPC::LR;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
return getDwarfRegNum(hasFP(MF) ? PPC::R31 : PPC::R1);
|
return hasFP(MF) ? PPC::R31 : PPC::R1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PPCRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves)
|
||||||
|
const {
|
||||||
|
// Initial state is the frame pointer is R1.
|
||||||
|
MachineLocation Dst(MachineLocation::VirtualFP);
|
||||||
|
MachineLocation Src(PPC::R1, 0);
|
||||||
|
Moves.push_back(new MachineMove(0, Dst, Src));
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "PPCGenRegisterInfo.inc"
|
#include "PPCGenRegisterInfo.inc"
|
||||||
|
@ -57,7 +57,9 @@ public:
|
|||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
|
void getInitialFrameState(std::vector<MachineMove *> &Moves) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -200,8 +200,14 @@ void SparcRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0);
|
BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned SparcRegisterInfo::getRARegister() const {
|
||||||
|
assert(0 && "What is the return address register");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
return getDwarfRegNum(SP::G1);
|
assert(0 && "What is the frame register");
|
||||||
|
return SP::G1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "SparcGenRegisterInfo.inc"
|
#include "SparcGenRegisterInfo.inc"
|
||||||
|
@ -58,6 +58,7 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
|
|||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -317,6 +317,15 @@ void SparcV9RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SparcV9RegisterInfo::getDwarfRegNum(unsigned RegNum) const {
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned SparcV9RegisterInfo::getRARegister() const {
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned SparcV9RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned SparcV9RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
abort ();
|
abort ();
|
||||||
|
@ -46,6 +46,8 @@ struct SparcV9RegisterInfo : public MRegisterInfo {
|
|||||||
void emitEpilogue (MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue (MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
int getDwarfRegNum(unsigned RegNum) const;
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -686,8 +686,12 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned X86RegisterInfo::getRARegister() const {
|
||||||
|
return X86::ST0; // use a non-register register
|
||||||
|
}
|
||||||
|
|
||||||
unsigned X86RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned X86RegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
return getDwarfRegNum(hasFP(MF) ? X86::EBP : X86::ESP);
|
return hasFP(MF) ? X86::EBP : X86::ESP;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "X86GenRegisterInfo.inc"
|
#include "X86GenRegisterInfo.inc"
|
||||||
|
@ -64,6 +64,7 @@ struct X86RegisterInfo : public X86GenRegisterInfo {
|
|||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user