This is a resubmittal. For some reason it broke the bots yesterday

but I cannot reproduce the problem and have scrubed my sources and
even tested with llvm-lit -v --vg.
Support for Mips register information sections.

Mips ELF object files have a section that is dedicated
to register use info. Some of this information such as
the assumed Global Pointer value is used by the linker
in relocation resolution.

The register info file is .reginfo in o32 and .MIPS.options
in 64 and n32 abi files.

This patch contains the changes needed to create the sections,
but leaves the actual register accounting for a future patch.


Contributer: Jack Carter
 


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172847 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jack Carter 2013-01-18 21:20:38 +00:00
parent 82d3d4524f
commit c91cbb9b0c
11 changed files with 184 additions and 2 deletions

View File

@ -909,6 +909,9 @@ enum {
// this section based on their sizes
SHT_X86_64_UNWIND = 0x70000001, // Unwind information
SHT_MIPS_REGINFO = 0x70000006, // Register usage information
SHT_MIPS_OPTIONS = 0x7000000d, // General options
SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
@ -975,8 +978,10 @@ enum {
// All sections with the GPREL flag are grouped into a global data area
// for faster accesses
SHF_HEX_GPREL = 0x10000000
SHF_HEX_GPREL = 0x10000000,
// Do not strip this section. FIXME: We need target specific SHF_ enums.
SHF_MIPS_NOSTRIP = 0x8000000
};
// Section Group Flags

View File

@ -1319,6 +1319,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
case ELF::SHT_FINI_ARRAY:
case ELF::SHT_PREINIT_ARRAY:
case ELF::SHT_X86_64_UNWIND:
case ELF::SHT_MIPS_REGINFO:
case ELF::SHT_MIPS_OPTIONS:
// Nothing to do.
break;

View File

@ -5,6 +5,7 @@ add_llvm_library(LLVMMipsDesc
MipsMCCodeEmitter.cpp
MipsMCTargetDesc.cpp
MipsELFObjectWriter.cpp
MipsReginfo.cpp
)
add_dependencies(LLVMMipsDesc MipsCommonTableGen)

View File

@ -0,0 +1,80 @@
//===-- MipsReginfo.cpp - Registerinfo handling --------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// .reginfo
// Elf32_Word ri_gprmask
// Elf32_Word ri_cprmask[4]
// Elf32_Word ri_gp_value
//
// .MIPS.options - N64
// Elf64_Byte kind (ODK_REGINFO)
// Elf64_Byte size (40 bytes)
// Elf64_Section section (0)
// Elf64_Word info (unused)
// Elf64_Word ri_gprmask ()
// Elf64_Word ri_pad ()
// Elf64_Word[4] ri_cprmask ()
// Elf64_Addr ri_gp_value ()
//
// .MIPS.options - N32
// Elf32_Byte kind (ODK_REGINFO)
// Elf32_Byte size (36 bytes)
// Elf32_Section section (0)
// Elf32_Word info (unused)
// Elf32_Word ri_gprmask ()
// Elf32_Word ri_pad ()
// Elf32_Word[4] ri_cprmask ()
// Elf32_Addr ri_gp_value ()
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/MipsReginfo.h"
#include "MipsSubtarget.h"
#include "MipsTargetObjectFile.h"
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
// Integrated assembler version
void
MipsReginfo::emitMipsReginfoSectionCG(MCStreamer &OS,
const TargetLoweringObjectFile &TLOF,
const MipsSubtarget &MST) const
{
if (OS.hasRawTextSupport())
return;
const MipsTargetObjectFile &TLOFELF =
static_cast<const MipsTargetObjectFile &>(TLOF);
OS.SwitchSection(TLOFELF.getReginfoSection());
// .reginfo
if (MST.isABI_O32()) {
OS.EmitIntValue(0, 4); // ri_gprmask
OS.EmitIntValue(0, 4); // ri_cpr[0]mask
OS.EmitIntValue(0, 4); // ri_cpr[1]mask
OS.EmitIntValue(0, 4); // ri_cpr[2]mask
OS.EmitIntValue(0, 4); // ri_cpr[3]mask
OS.EmitIntValue(0, 4); // ri_gp_value
}
// .MIPS.options
else if (MST.isABI_N64()) {
OS.EmitIntValue(1, 1); // kind
OS.EmitIntValue(40, 1); // size
OS.EmitIntValue(0, 2); // section
OS.EmitIntValue(0, 4); // info
OS.EmitIntValue(0, 4); // ri_gprmask
OS.EmitIntValue(0, 4); // pad
OS.EmitIntValue(0, 4); // ri_cpr[0]mask
OS.EmitIntValue(0, 4); // ri_cpr[1]mask
OS.EmitIntValue(0, 4); // ri_cpr[2]mask
OS.EmitIntValue(0, 4); // ri_cpr[3]mask
OS.EmitIntValue(0, 8); // ri_gp_value
}
else llvm_unreachable("Unsupported abi for reginfo");
}

View File

@ -0,0 +1,31 @@
//=== MipsReginfo.h - MipsReginfo -----------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENCE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MIPSREGINFO_H
#define MIPSREGINFO_H
namespace llvm {
class MCStreamer;
class TargetLoweringObjectFile;
class MipsSubtarget;
class MipsReginfo {
void anchor();
public:
MipsReginfo() {}
void emitMipsReginfoSectionCG(MCStreamer &OS,
const TargetLoweringObjectFile &TLOF,
const MipsSubtarget &MST) const;
};
} // namespace llvm
#endif

View File

@ -13,10 +13,10 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-asm-printer"
#include "MipsAsmPrinter.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "Mips.h"
#include "MipsAsmPrinter.h"
#include "MipsInstrInfo.h"
#include "MipsMCInstLower.h"
#include "llvm/ADT/SmallString.h"
@ -540,6 +540,14 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
// return to previous section
if (OutStreamer.hasRawTextSupport())
OutStreamer.EmitRawText(StringRef("\t.previous"));
}
void MipsAsmPrinter::EmitEndOfAsmFile(Module &M) {
// Emit Mips ELF register info
Subtarget->getMReginfo().emitMipsReginfoSectionCG(
OutStreamer, getObjFileLowering(), *Subtarget);
}
MachineLocation

View File

@ -80,6 +80,7 @@ public:
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
void EmitStartOfAsmFile(Module &M);
void EmitEndOfAsmFile(Module &M);
virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
};

View File

@ -14,6 +14,7 @@
#ifndef MIPSSUBTARGET_H
#define MIPSSUBTARGET_H
#include "MCTargetDesc/MipsReginfo.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>
@ -96,6 +97,9 @@ protected:
InstrItineraryData InstrItins;
// The instance to the register info section object
MipsReginfo MRI;
public:
virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
AntiDepBreakMode& Mode,
@ -145,6 +149,9 @@ public:
bool hasSwap() const { return HasSwap; }
bool hasBitCount() const { return HasBitCount; }
bool hasFPIdx() const { return HasFPIdx; }
// Grab MipsRegInfo object
const MipsReginfo &getMReginfo() const { return MRI; }
};
} // End llvm namespace

View File

@ -38,6 +38,20 @@ void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
ELF::SHF_WRITE |ELF::SHF_ALLOC,
SectionKind::getBSS());
// Register info information
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
if (Subtarget.isABI_N64() || Subtarget.isABI_N32())
ReginfoSection =
getContext().getELFSection(".MIPS.options",
ELF::SHT_MIPS_OPTIONS,
ELF::SHF_ALLOC |ELF::SHF_MIPS_NOSTRIP,
SectionKind::getMetadata());
else
ReginfoSection =
getContext().getELFSection(".reginfo",
ELF::SHT_MIPS_REGINFO,
ELF::SHF_ALLOC,
SectionKind::getMetadata());
}
// A address must be loaded from a small section if its size is less than the

View File

@ -17,6 +17,7 @@ namespace llvm {
class MipsTargetObjectFile : public TargetLoweringObjectFileELF {
const MCSection *SmallDataSection;
const MCSection *SmallBSSSection;
const MCSection *ReginfoSection;
public:
void Initialize(MCContext &Ctx, const TargetMachine &TM);
@ -35,6 +36,7 @@ namespace llvm {
const TargetMachine &TM) const;
// TODO: Classify globals as mips wishes.
const MCSection *getReginfoSection() const { return ReginfoSection; }
};
} // end namespace llvm

View File

@ -0,0 +1,31 @@
; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64 %s -o - \
; RUN: | elf-dump --dump-section-data | FileCheck --check-prefix=CHECK_64 %s
; RUN: llc -filetype=obj -march=mipsel -mcpu=mips32 %s -o - \
; RUN: | elf-dump --dump-section-data | FileCheck --check-prefix=CHECK_32 %s
; Check for register information sections.
;
@str = private unnamed_addr constant [12 x i8] c"hello world\00"
define i32 @main() nounwind {
entry:
; Check that the appropriate relocations were created.
; check for .MIPS.options
; CHECK_64: (('sh_name', 0x{{[0-9|a-f]+}}) # '.MIPS.options'
; CHECK_64-NEXT: ('sh_type', 0x7000000d)
; CHECK_64-NEXT: ('sh_flags', 0x0000000008000002)
; check for .reginfo
; CHECK_32: (('sh_name', 0x{{[0-9|a-f]+}}) # '.reginfo'
; CHECK_32-NEXT: ('sh_type', 0x70000006)
; CHECK_32-NEXT: ('sh_flags', 0x00000002)
%puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @str, i64 0, i64 0))
ret i32 0
}
declare i32 @puts(i8* nocapture) nounwind