mirror of
https://github.com/RPCSX/llvm.git
synced 2025-05-13 19:06:05 +00:00
Switch MIPS to new ELFTargetAsmInfo. Add few FIXMEs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53790 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cff2ea06af
commit
ae408e6f1e
@ -32,6 +32,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) {
|
|||||||
SectionFlags::Mergeable);
|
SectionFlags::Mergeable);
|
||||||
EightByteConstantSection_ = getUnnamedSection("\t.literal8\n",
|
EightByteConstantSection_ = getUnnamedSection("\t.literal8\n",
|
||||||
SectionFlags::Mergeable);
|
SectionFlags::Mergeable);
|
||||||
|
|
||||||
// Note: 16-byte constant section is subtarget specific and should be provided
|
// Note: 16-byte constant section is subtarget specific and should be provided
|
||||||
// there.
|
// there.
|
||||||
|
|
||||||
|
@ -58,12 +58,13 @@ namespace {
|
|||||||
return "Mips Assembly Printer";
|
return "Mips Assembly Printer";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string getSectionForFunction(const Function &F) const;
|
||||||
void printOperand(const MachineInstr *MI, int opNum);
|
void printOperand(const MachineInstr *MI, int opNum);
|
||||||
void printMemOperand(const MachineInstr *MI, int opNum,
|
void printMemOperand(const MachineInstr *MI, int opNum,
|
||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
void printFCCOperand(const MachineInstr *MI, int opNum,
|
void printFCCOperand(const MachineInstr *MI, int opNum,
|
||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
|
void printModuleLevelGV(const GlobalVariable* GVar);
|
||||||
unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
|
unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
|
||||||
void printHex32(unsigned int Value);
|
void printHex32(unsigned int Value);
|
||||||
|
|
||||||
@ -241,13 +242,18 @@ emitCurrentABIString(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Substitute old hook with new one temporary
|
||||||
|
std::string MipsAsmPrinter::getSectionForFunction(const Function &F) const {
|
||||||
|
return TAI->SectionForGlobal(&F);
|
||||||
|
}
|
||||||
|
|
||||||
/// Emit the directives used by GAS on the start of functions
|
/// Emit the directives used by GAS on the start of functions
|
||||||
void MipsAsmPrinter::
|
void MipsAsmPrinter::
|
||||||
emitFunctionStart(MachineFunction &MF)
|
emitFunctionStart(MachineFunction &MF)
|
||||||
{
|
{
|
||||||
// Print out the label for the function.
|
// Print out the label for the function.
|
||||||
const Function *F = MF.getFunction();
|
const Function *F = MF.getFunction();
|
||||||
SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
|
SwitchToTextSection(TAI->SectionForGlobal(F).c_str());
|
||||||
|
|
||||||
// 2 bits aligned
|
// 2 bits aligned
|
||||||
EmitAlignment(2, F);
|
EmitAlignment(2, F);
|
||||||
@ -467,26 +473,21 @@ doInitialization(Module &M)
|
|||||||
return false; // success
|
return false; // success
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MipsAsmPrinter::
|
void MipsAsmPrinter::
|
||||||
doFinalization(Module &M)
|
printModuleLevelGV(const GlobalVariable* GVar) {
|
||||||
{
|
|
||||||
const TargetData *TD = TM.getTargetData();
|
const TargetData *TD = TM.getTargetData();
|
||||||
|
|
||||||
// Print out module-level global variables here.
|
if (!GVar->hasInitializer())
|
||||||
for (Module::const_global_iterator I = M.global_begin(),
|
return; // External global require no code
|
||||||
E = M.global_end(); I != E; ++I)
|
|
||||||
|
|
||||||
// External global require no code
|
// Check to see if this is a special global used by LLVM, if so, emit it.
|
||||||
if (I->hasInitializer()) {
|
if (EmitSpecialLLVMGlobal(GVar))
|
||||||
|
return;
|
||||||
// Check to see if this is a special global
|
|
||||||
// used by LLVM, if so, emit it.
|
|
||||||
if (EmitSpecialLLVMGlobal(I))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
O << "\n\n";
|
O << "\n\n";
|
||||||
std::string name = Mang->getValueName(I);
|
std::string SectionName = TAI->SectionForGlobal(GVar);
|
||||||
Constant *C = I->getInitializer();
|
std::string name = Mang->getValueName(GVar);
|
||||||
|
Constant *C = GVar->getInitializer();
|
||||||
const Type *CTy = C->getType();
|
const Type *CTy = C->getType();
|
||||||
unsigned Size = TD->getABITypeSize(CTy);
|
unsigned Size = TD->getABITypeSize(CTy);
|
||||||
bool printSizeAndType = true;
|
bool printSizeAndType = true;
|
||||||
@ -505,82 +506,46 @@ doFinalization(Module &M)
|
|||||||
} else
|
} else
|
||||||
Align = TD->getPreferredTypeAlignmentShift(CTy);
|
Align = TD->getPreferredTypeAlignmentShift(CTy);
|
||||||
|
|
||||||
// Is this correct ?
|
// FIXME: ELF supports visibility
|
||||||
if (C->isNullValue() && (I->hasLinkOnceLinkage() ||
|
|
||||||
I->hasInternalLinkage() || I->hasWeakLinkage() ||
|
SwitchToDataSection(SectionName.c_str());
|
||||||
I->hasCommonLinkage()))
|
|
||||||
{
|
if (C->isNullValue() && !GVar->hasSection()) {
|
||||||
|
if (!GVar->isThreadLocal() &&
|
||||||
|
(GVar->hasInternalLinkage() || GVar->isWeakForLinker())) {
|
||||||
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
|
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
|
||||||
|
|
||||||
if (!NoZerosInBSS && TAI->getBSSSection())
|
if (GVar->hasInternalLinkage()) {
|
||||||
SwitchToDataSection(TAI->getBSSSection(), I);
|
|
||||||
else
|
|
||||||
SwitchToDataSection(TAI->getDataSection(), I);
|
|
||||||
|
|
||||||
if (I->hasInternalLinkage()) {
|
|
||||||
if (TAI->getLCOMMDirective())
|
if (TAI->getLCOMMDirective())
|
||||||
O << TAI->getLCOMMDirective() << name << "," << Size;
|
O << TAI->getLCOMMDirective() << name << ',' << Size;
|
||||||
else
|
else
|
||||||
O << "\t.local\t" << name << "\n";
|
O << "\t.local\t" << name << '\n';
|
||||||
} else {
|
} else {
|
||||||
O << TAI->getCOMMDirective() << name << "," << Size;
|
O << TAI->getCOMMDirective() << name << ',' << Size;
|
||||||
// The .comm alignment in bytes.
|
// The .comm alignment in bytes.
|
||||||
if (TAI->getCOMMDirectiveTakesAlignment())
|
if (TAI->getCOMMDirectiveTakesAlignment())
|
||||||
O << "," << (1 << Align);
|
O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
|
||||||
}
|
}
|
||||||
|
O << '\n';
|
||||||
} else {
|
return;
|
||||||
|
}
|
||||||
switch (I->getLinkage())
|
}
|
||||||
{
|
switch (GVar->getLinkage()) {
|
||||||
case GlobalValue::LinkOnceLinkage:
|
case GlobalValue::LinkOnceLinkage:
|
||||||
case GlobalValue::CommonLinkage:
|
case GlobalValue::CommonLinkage:
|
||||||
case GlobalValue::WeakLinkage:
|
case GlobalValue::WeakLinkage:
|
||||||
// FIXME: Verify correct for weak.
|
// FIXME: Verify correct for weak.
|
||||||
// Nonnull linkonce -> weak
|
// Nonnull linkonce -> weak
|
||||||
O << "\t.weak " << name << "\n";
|
O << "\t.weak " << name << "\n";
|
||||||
SwitchToDataSection("", I);
|
|
||||||
O << "\t.section\t\".llvm.linkonce.d." << name
|
|
||||||
<< "\",\"aw\",@progbits\n";
|
|
||||||
break;
|
break;
|
||||||
case GlobalValue::AppendingLinkage:
|
case GlobalValue::AppendingLinkage:
|
||||||
// FIXME: appending linkage variables
|
// FIXME: appending linkage variables should go into a section of their name
|
||||||
// should go into a section of their name or
|
// or something. For now, just emit them as external.
|
||||||
// something. For now, just emit them as external.
|
|
||||||
case GlobalValue::ExternalLinkage:
|
case GlobalValue::ExternalLinkage:
|
||||||
// If external or appending, declare as a global symbol
|
// If external or appending, declare as a global symbol
|
||||||
O << TAI->getGlobalDirective() << name << "\n";
|
O << TAI->getGlobalDirective() << name << "\n";
|
||||||
// Fall Through
|
// Fall Through
|
||||||
case GlobalValue::InternalLinkage:
|
case GlobalValue::InternalLinkage:
|
||||||
// FIXME: special handling for ".ctors" & ".dtors" sections
|
|
||||||
if (I->hasSection() && (I->getSection() == ".ctors" ||
|
|
||||||
I->getSection() == ".dtors")) {
|
|
||||||
std::string SectionName = ".section " + I->getSection();
|
|
||||||
SectionName += ",\"aw\",%progbits";
|
|
||||||
SwitchToDataSection(SectionName.c_str());
|
|
||||||
} else {
|
|
||||||
if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
|
|
||||||
SwitchToDataSection(TAI->getBSSSection(), I);
|
|
||||||
else if (!I->isConstant())
|
|
||||||
SwitchToDataSection(TAI->getDataSection(), I);
|
|
||||||
else {
|
|
||||||
// Read-only data. We have two possible scenary here
|
|
||||||
// 1) Readonly section for strings (char arrays).
|
|
||||||
// 2) for other types.
|
|
||||||
if (TAI->getReadOnlySection()) {
|
|
||||||
const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
|
|
||||||
if (CVA && CVA->isString()) {
|
|
||||||
std::string SectionName = "\t.section\t.rodata.str1.4,"
|
|
||||||
"\"aMS\",@progbits,1";
|
|
||||||
SwitchToDataSection(SectionName.c_str());
|
|
||||||
printSizeAndType = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SwitchToDataSection(TAI->getReadOnlySection(), I);
|
|
||||||
} else
|
|
||||||
SwitchToDataSection(TAI->getDataSection(), I);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GlobalValue::GhostLinkage:
|
case GlobalValue::GhostLinkage:
|
||||||
cerr << "Should not have any unmaterialized functions!\n";
|
cerr << "Should not have any unmaterialized functions!\n";
|
||||||
@ -602,10 +567,18 @@ doFinalization(Module &M)
|
|||||||
O << "\t.type " << name << ",@object\n";
|
O << "\t.type " << name << ",@object\n";
|
||||||
O << "\t.size " << name << "," << Size << "\n";
|
O << "\t.size " << name << "," << Size << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
O << name << ":\n";
|
O << name << ":\n";
|
||||||
EmitGlobalConstant(C);
|
EmitGlobalConstant(C);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
bool MipsAsmPrinter::
|
||||||
|
doFinalization(Module &M)
|
||||||
|
{
|
||||||
|
// Print out module-level global variables here.
|
||||||
|
for (Module::const_global_iterator I = M.global_begin(),
|
||||||
|
E = M.global_end(); I != E; ++I)
|
||||||
|
printModuleLevelGV(I);
|
||||||
|
|
||||||
O << "\n";
|
O << "\n";
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) {
|
MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM):
|
||||||
|
ELFTargetAsmInfo(TM) {
|
||||||
|
|
||||||
AlignmentIsInBytes = false;
|
AlignmentIsInBytes = false;
|
||||||
COMMDirectiveTakesAlignment = true;
|
COMMDirectiveTakesAlignment = true;
|
||||||
|
@ -15,13 +15,14 @@
|
|||||||
#define MIPSTARGETASMINFO_H
|
#define MIPSTARGETASMINFO_H
|
||||||
|
|
||||||
#include "llvm/Target/TargetAsmInfo.h"
|
#include "llvm/Target/TargetAsmInfo.h"
|
||||||
|
#include "llvm/Target/ELFTargetAsmInfo.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
// Forward declaration.
|
// Forward declaration.
|
||||||
class MipsTargetMachine;
|
class MipsTargetMachine;
|
||||||
|
|
||||||
struct MipsTargetAsmInfo : public TargetAsmInfo {
|
struct MipsTargetAsmInfo : public ELFTargetAsmInfo {
|
||||||
explicit MipsTargetAsmInfo(const MipsTargetMachine &TM);
|
explicit MipsTargetAsmInfo(const MipsTargetMachine &TM);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user