From e59bf59ba55c6bdba82a7126e91f5bb53118e84c Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sat, 14 Aug 2004 22:09:10 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15741 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPC32AsmPrinter.cpp | 134 ++++++++++++++----------- lib/Target/PowerPC/PPCAsmPrinter.cpp | 134 ++++++++++++++----------- 2 files changed, 146 insertions(+), 122 deletions(-) diff --git a/lib/Target/PowerPC/PPC32AsmPrinter.cpp b/lib/Target/PowerPC/PPC32AsmPrinter.cpp index 4ec7b7daa97..afe7c35470b 100644 --- a/lib/Target/PowerPC/PPC32AsmPrinter.cpp +++ b/lib/Target/PowerPC/PPC32AsmPrinter.cpp @@ -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 FnStubs, GVStubs, LinkOnceStubs; std::set Strings; - Printer(std::ostream &o, TargetMachine &tm) : O(o), - TM(reinterpret_cast(tm)), LabelNumber(0) {} + PowerPCAsmPrinter(std::ostream &o, TargetMachine &tm) : O(o), + TM(reinterpret_cast(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(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(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(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 &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::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::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::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 } diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 4ec7b7daa97..afe7c35470b 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -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 FnStubs, GVStubs, LinkOnceStubs; std::set Strings; - Printer(std::ostream &o, TargetMachine &tm) : O(o), - TM(reinterpret_cast(tm)), LabelNumber(0) {} + PowerPCAsmPrinter(std::ostream &o, TargetMachine &tm) : O(o), + TM(reinterpret_cast(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(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(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(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 &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::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::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::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 }