forked from OSchip/llvm-project
Add initial support for using the generated asm writer. Also, fix FP constant printing to always print 8 byte intializers. Move printing of LinkOnce stubs.
llvm-svn: 15741
This commit is contained in:
parent
8536df7dbe
commit
0ad7f813d8
|
@ -19,7 +19,7 @@
|
|||
#define DEBUG_TYPE "asmprinter"
|
||||
#include "PowerPC.h"
|
||||
#include "PowerPCInstrInfo.h"
|
||||
#include "PPC32TargetMachine.h"
|
||||
#include "PowerPCTargetMachine.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
|
@ -40,7 +40,7 @@ namespace llvm {
|
|||
namespace {
|
||||
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
|
||||
|
||||
struct Printer : public MachineFunctionPass {
|
||||
struct PowerPCAsmPrinter : public MachineFunctionPass {
|
||||
/// Output stream on which we're printing assembly code.
|
||||
///
|
||||
std::ostream &O;
|
||||
|
@ -48,7 +48,7 @@ namespace {
|
|||
/// Target machine description which we query for reg. names, data
|
||||
/// layout, etc.
|
||||
///
|
||||
PPC32TargetMachine &TM;
|
||||
PowerPCTargetMachine &TM;
|
||||
|
||||
/// Name-mangler for global names.
|
||||
///
|
||||
|
@ -56,8 +56,8 @@ namespace {
|
|||
std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
|
||||
std::set<std::string> Strings;
|
||||
|
||||
Printer(std::ostream &o, TargetMachine &tm) : O(o),
|
||||
TM(reinterpret_cast<PPC32TargetMachine&>(tm)), LabelNumber(0) {}
|
||||
PowerPCAsmPrinter(std::ostream &o, TargetMachine &tm) : O(o),
|
||||
TM(reinterpret_cast<PowerPCTargetMachine&>(tm)), LabelNumber(0) {}
|
||||
|
||||
/// Cache of mangled name for current function. This is
|
||||
/// recalculated at the beginning of each call to
|
||||
|
@ -70,9 +70,15 @@ namespace {
|
|||
unsigned LabelNumber;
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "PPC32 Assembly Printer";
|
||||
return "PowerPC Assembly Printer";
|
||||
}
|
||||
|
||||
/// printInstruction - This method is automatically generated by tablegen
|
||||
/// from the instruction set description. This method returns true if the
|
||||
/// machine instruction was sufficiently described to print it, otherwise it
|
||||
/// returns false.
|
||||
bool printInstruction(const MachineInstr *MI);
|
||||
|
||||
void printMachineInstruction(const MachineInstr *MI);
|
||||
void printOp(const MachineOperand &MO, bool LoadAddrOp = false);
|
||||
void printImmOp(const MachineOperand &MO, unsigned ArgType);
|
||||
|
@ -90,10 +96,13 @@ namespace {
|
|||
/// using the given target machine description. This should work
|
||||
/// regardless of whether the function is in SSA form or not.
|
||||
///
|
||||
FunctionPass *createPPC32AsmPrinter(std::ostream &o,TargetMachine &tm) {
|
||||
return new Printer(o, tm);
|
||||
FunctionPass *createPPCAsmPrinter(std::ostream &o,TargetMachine &tm) {
|
||||
return new PowerPCAsmPrinter(o, tm);
|
||||
}
|
||||
|
||||
// Include the auto-generated portion of the assembly writer
|
||||
#include "PowerPCGenAsmWriter.inc"
|
||||
|
||||
/// isStringCompatible - Can we treat the specified array as a string?
|
||||
/// Only if it is an array of ubytes or non-negative sbytes.
|
||||
///
|
||||
|
@ -152,7 +161,7 @@ static void printAsCString(std::ostream &O, const ConstantArray *CVA) {
|
|||
|
||||
// Print out the specified constant, without a storage class. Only the
|
||||
// constants valid in constant expressions can occur here.
|
||||
void Printer::emitConstantValueOnly(const Constant *CV) {
|
||||
void PowerPCAsmPrinter::emitConstantValueOnly(const Constant *CV) {
|
||||
if (CV->isNullValue())
|
||||
O << "0";
|
||||
else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
|
||||
|
@ -222,7 +231,7 @@ void Printer::emitConstantValueOnly(const Constant *CV) {
|
|||
|
||||
// Print a constant value or values, with the appropriate storage class as a
|
||||
// prefix.
|
||||
void Printer::emitGlobalConstant(const Constant *CV) {
|
||||
void PowerPCAsmPrinter::emitGlobalConstant(const Constant *CV) {
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
|
||||
if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
|
||||
|
@ -263,35 +272,21 @@ void Printer::emitGlobalConstant(const Constant *CV) {
|
|||
// FP Constants are printed as integer constants to avoid losing
|
||||
// precision...
|
||||
double Val = CFP->getValue();
|
||||
switch (CFP->getType()->getTypeID()) {
|
||||
default: assert(0 && "Unknown floating point type!");
|
||||
case Type::FloatTyID: {
|
||||
union FU { // Abide by C TBAA rules
|
||||
float FVal;
|
||||
unsigned UVal;
|
||||
} U;
|
||||
U.FVal = Val;
|
||||
O << ".long\t" << U.UVal << "\t; float " << Val << "\n";
|
||||
return;
|
||||
}
|
||||
case Type::DoubleTyID: {
|
||||
union DU { // Abide by C TBAA rules
|
||||
double FVal;
|
||||
uint64_t UVal;
|
||||
struct {
|
||||
uint32_t MSWord;
|
||||
uint32_t LSWord;
|
||||
} T;
|
||||
} U;
|
||||
U.FVal = Val;
|
||||
|
||||
O << ".long\t" << U.T.MSWord << "\t; double most significant word "
|
||||
<< Val << "\n";
|
||||
O << ".long\t" << U.T.LSWord << "\t; double least significant word "
|
||||
<< Val << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
union DU { // Abide by C TBAA rules
|
||||
double FVal;
|
||||
uint64_t UVal;
|
||||
struct {
|
||||
uint32_t MSWord;
|
||||
uint32_t LSWord;
|
||||
} T;
|
||||
} U;
|
||||
U.FVal = Val;
|
||||
|
||||
O << ".long\t" << U.T.MSWord << "\t; double most significant word "
|
||||
<< Val << "\n";
|
||||
O << ".long\t" << U.T.LSWord << "\t; double least significant word "
|
||||
<< Val << "\n";
|
||||
return;
|
||||
} else if (CV->getType() == Type::ULongTy || CV->getType() == Type::LongTy) {
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
|
||||
union DU { // Abide by C TBAA rules
|
||||
|
@ -348,7 +343,7 @@ void Printer::emitGlobalConstant(const Constant *CV) {
|
|||
/// used to print out constants which have been "spilled to memory" by
|
||||
/// the code generator.
|
||||
///
|
||||
void Printer::printConstantPool(MachineConstantPool *MCP) {
|
||||
void PowerPCAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
|
||||
const std::vector<Constant*> &CP = MCP->getConstants();
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
|
||||
|
@ -367,7 +362,7 @@ void Printer::printConstantPool(MachineConstantPool *MCP) {
|
|||
/// runOnMachineFunction - This uses the printMachineInstruction()
|
||||
/// method to print assembly for each instruction.
|
||||
///
|
||||
bool Printer::runOnMachineFunction(MachineFunction &MF) {
|
||||
bool PowerPCAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
O << "\n\n";
|
||||
// What's my mangled name?
|
||||
CurrentFnName = Mang->getValueName(MF.getFunction());
|
||||
|
@ -400,7 +395,7 @@ bool Printer::runOnMachineFunction(MachineFunction &MF) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Printer::printOp(const MachineOperand &MO,
|
||||
void PowerPCAsmPrinter::printOp(const MachineOperand &MO,
|
||||
bool LoadAddrOp /* = false */) {
|
||||
const MRegisterInfo &RI = *TM.getRegisterInfo();
|
||||
int new_symbol;
|
||||
|
@ -458,14 +453,19 @@ void Printer::printOp(const MachineOperand &MO,
|
|||
O << "L" << Name << "$stub";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// External global variables need a non-lazily-resolved stub
|
||||
if (!GV->hasInternalLinkage() &&
|
||||
TM.AddressTaken.find(GV) != TM.AddressTaken.end()) {
|
||||
if (GV->isExternal() && TM.AddressTaken.find(GV) != TM.AddressTaken.end()) {
|
||||
GVStubs.insert(Name);
|
||||
O << "L" << Name << "$non_lazy_ptr";
|
||||
return;
|
||||
}
|
||||
|
||||
if (F && LoadAddrOp && TM.AddressTaken.find(GV) != TM.AddressTaken.end()) {
|
||||
LinkOnceStubs.insert(Name);
|
||||
O << "L" << Name << "$non_lazy_ptr";
|
||||
return;
|
||||
}
|
||||
|
||||
O << Mang->getValueName(GV);
|
||||
return;
|
||||
|
@ -477,7 +477,7 @@ void Printer::printOp(const MachineOperand &MO,
|
|||
}
|
||||
}
|
||||
|
||||
void Printer::printImmOp(const MachineOperand &MO, unsigned ArgType) {
|
||||
void PowerPCAsmPrinter::printImmOp(const MachineOperand &MO, unsigned ArgType) {
|
||||
int Imm = MO.getImmedValue();
|
||||
if (ArgType == PPCII::Simm16 || ArgType == PPCII::Disimm16) {
|
||||
O << (short)Imm;
|
||||
|
@ -488,10 +488,14 @@ void Printer::printImmOp(const MachineOperand &MO, unsigned ArgType) {
|
|||
}
|
||||
}
|
||||
|
||||
/// printMachineInstruction -- Print out a single PPC LLVM instruction
|
||||
/// MI in Darwin syntax to the current output stream.
|
||||
/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
|
||||
/// the current output stream.
|
||||
///
|
||||
void Printer::printMachineInstruction(const MachineInstr *MI) {
|
||||
void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
|
||||
++EmittedInsts;
|
||||
if (printInstruction(MI))
|
||||
return; // Printer was automatically generated
|
||||
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
const TargetInstrInfo &TII = *TM.getInstrInfo();
|
||||
const TargetInstrDescriptor &Desc = TII.get(Opcode);
|
||||
|
@ -509,7 +513,6 @@ void Printer::printMachineInstruction(const MachineInstr *MI) {
|
|||
"Instruction requires VMX support");
|
||||
assert(((Desc.TSFlags & PPCII::PPC64) == 0) &&
|
||||
"Instruction requires 64 bit support");
|
||||
++EmittedInsts;
|
||||
|
||||
// CALLpcrel and CALLindirect are handled specially here to print only the
|
||||
// appropriate number of args that the assembler expects. This is because
|
||||
|
@ -603,9 +606,18 @@ void Printer::printMachineInstruction(const MachineInstr *MI) {
|
|||
O << ", ";
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
// Call the autogenerated instruction printer routines.
|
||||
bool Handled = printInstruction(MI);
|
||||
if (!Handled) {
|
||||
MI->dump();
|
||||
assert(0 && "Do not know how to print this instruction!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
bool Printer::doInitialization(Module &M) {
|
||||
bool PowerPCAsmPrinter::doInitialization(Module &M) {
|
||||
Mang = new Mangler(M, true);
|
||||
return false; // success
|
||||
}
|
||||
|
@ -622,7 +634,7 @@ static void SwitchSection(std::ostream &OS, std::string &CurSection,
|
|||
}
|
||||
}
|
||||
|
||||
bool Printer::doFinalization(Module &M) {
|
||||
bool PowerPCAsmPrinter::doFinalization(Module &M) {
|
||||
const TargetData &TD = TM.getTargetData();
|
||||
std::string CurSection;
|
||||
|
||||
|
@ -683,15 +695,6 @@ bool Printer::doFinalization(Module &M) {
|
|||
}
|
||||
}
|
||||
|
||||
// Output stubs for link-once variables
|
||||
if (LinkOnceStubs.begin() != LinkOnceStubs.end())
|
||||
O << ".data\n.align 2\n";
|
||||
for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
|
||||
e = LinkOnceStubs.end(); i != e; ++i) {
|
||||
O << *i << "$non_lazy_ptr:\n"
|
||||
<< "\t.long\t" << *i << '\n';
|
||||
}
|
||||
|
||||
// Output stubs for dynamically-linked functions
|
||||
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
|
||||
i != e; ++i)
|
||||
|
@ -729,6 +732,15 @@ bool Printer::doFinalization(Module &M) {
|
|||
O << "\t.long\t0\n";
|
||||
}
|
||||
|
||||
// Output stubs for link-once variables
|
||||
if (LinkOnceStubs.begin() != LinkOnceStubs.end())
|
||||
O << ".data\n.align 2\n";
|
||||
for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
|
||||
e = LinkOnceStubs.end(); i != e; ++i) {
|
||||
O << "L" << *i << "$non_lazy_ptr:\n"
|
||||
<< "\t.long\t" << *i << '\n';
|
||||
}
|
||||
|
||||
delete Mang;
|
||||
return false; // success
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue