//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "asm-printer"
#include "IA64.h"
#include "IA64TargetMachine.h"
#include "llvm/Module.h"
#include "llvm/Type.h"
-#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/ADT/Statistic.h"
-#include <iostream>
using namespace llvm;
+STATISTIC(EmittedInsts, "Number of machine instrs printed");
+
namespace {
- Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
-
- struct VISIBILITY_HIDDEN IA64TargetAsmInfo : public TargetAsmInfo {
- IA64TargetAsmInfo() {
- CommentString = "//";
- Data8bitsDirective = "\tdata1\t"; // FIXME: check that we are
- Data16bitsDirective = "\tdata2.ua\t"; // disabling auto-alignment
- Data32bitsDirective = "\tdata4.ua\t"; // properly
- Data64bitsDirective = "\tdata8.ua\t";
- ZeroDirective = "\t.skip\t";
- AsciiDirective = "\tstring\t";
-
- GlobalVarAddrPrefix="";
- GlobalVarAddrSuffix="";
- FunctionAddrPrefix="@fptr(";
- FunctionAddrSuffix=")";
-
- // FIXME: would be nice to have rodata (no 'w') when appropriate?
- ConstantPoolSection = "\n\t.section .data, \"aw\", \"progbits\"\n";
- }
- };
-
struct IA64AsmPrinter : public AsmPrinter {
std::set<std::string> ExternalFunctionNames, ExternalObjectNames;
- IA64AsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+ IA64AsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
: AsmPrinter(O, TM, T) {
}
printOp(MI->getOperand(OpNo), true); // this is a br.call instruction
}
+ std::string getSectionForFunction(const Function &F) const;
+
void printMachineInstruction(const MachineInstr *MI);
void printOp(const MachineOperand &MO, bool isBRCALLinsn= false);
bool runOnMachineFunction(MachineFunction &F);
#include "IA64GenAsmWriter.inc"
+std::string IA64AsmPrinter::getSectionForFunction(const Function &F) const {
+ // This means "Allocated instruXions in mem, initialized".
+ return "\n\t.section .text, \"ax\", \"progbits\"\n";
+}
+
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
// Print out constants referenced by the function
EmitConstantPool(MF.getConstantPool());
+ const Function *F = MF.getFunction();
+ SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+
// Print out labels for the function.
- SwitchToTextSection("\n\t.section .text, \"ax\", \"progbits\"\n",
- MF.getFunction());
- // ^^ means "Allocated instruXions in mem, initialized"
EmitAlignment(5);
O << "\t.global\t" << CurrentFnName << "\n";
O << "\t.type\t" << CurrentFnName << ", @function\n";
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block if there are any predecessors.
- if (I->pred_begin() != I->pred_end()) {
+ if (!I->pred_empty()) {
printBasicBlockLabel(I, true);
O << '\n';
}
bool Needfptr=false; // if we're computing an address @ltoff(X), do
// we need to decorate it so it becomes
// @ltoff(@fptr(X)) ?
- if (F && !isBRCALLinsn /*&& F->isExternal()*/)
+ if (F && !isBRCALLinsn /*&& F->isDeclaration()*/)
Needfptr=true;
// if this is the target of a call instruction, we should define
// the function somewhere (GNU gas has no problem without this, but
// Intel ias rightly complains of an 'undefined symbol')
- if (F /*&& isBRCALLinsn*/ && F->isExternal())
+ if (F /*&& isBRCALLinsn*/ && F->isDeclaration())
ExternalFunctionNames.insert(Mang->getValueName(MO.getGlobal()));
else
- if (GV->isExternal()) // e.g. stuff like 'stdin'
+ if (GV->isDeclaration()) // e.g. stuff like 'stdin'
ExternalObjectNames.insert(Mang->getValueName(MO.getGlobal()));
if (!isBRCALLinsn)
}
bool IA64AsmPrinter::doInitialization(Module &M) {
- AsmPrinter::doInitialization(M);
+ bool Result = AsmPrinter::doInitialization(M);
O << "\n.ident \"LLVM-ia64\"\n\n"
<< "\t.psr lsb\n" // should be "msb" on HP-UX, for starters
<< "\t.radix C\n"
<< "\t.psr abi64\n"; // we only support 64 bits for now
- return false;
+ return Result;
}
bool IA64AsmPrinter::doFinalization(Module &M) {
O << "\n\n";
std::string name = Mang->getValueName(I);
Constant *C = I->getInitializer();
- unsigned Size = TD->getTypeSize(C->getType());
- unsigned Align = TD->getTypeAlignmentShift(C->getType());
+ unsigned Size = TD->getABITypeSize(C->getType());
+ unsigned Align = TD->getPreferredTypeAlignmentShift(C->getType());
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchToDataSection(".data", I);
if (I->hasInternalLinkage()) {
- O << "\t.lcomm " << name << "#," << TD->getTypeSize(C->getType())
+ O << "\t.lcomm " << name << "#," << TD->getABITypeSize(C->getType())
<< "," << (1 << Align);
- O << "\t\t// ";
+ O << "\n";
} else {
- O << "\t.common " << name << "#," << TD->getTypeSize(C->getType())
+ O << "\t.common " << name << "#," << TD->getABITypeSize(C->getType())
<< "," << (1 << Align);
- O << "\t\t// ";
+ O << "\n";
}
- WriteAsOperand(O, I, true, true, &M);
- O << "\n";
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
SwitchToDataSection(C->isNullValue() ? ".bss" : ".data", I);
break;
case GlobalValue::GhostLinkage:
- std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
+ cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
+ abort();
+ case GlobalValue::DLLImportLinkage:
+ cerr << "DLLImport linkage is not supported by this target!\n";
+ abort();
+ case GlobalValue::DLLExportLinkage:
+ cerr << "DLLExport linkage is not supported by this target!\n";
abort();
+ default:
+ assert(0 && "Unknown linkage type!");
}
EmitAlignment(Align);
O << "\t.type " << name << ",@object\n";
O << "\t.size " << name << "," << Size << "\n";
- O << name << ":\t\t\t\t// ";
- WriteAsOperand(O, I, true, true, &M);
- O << " = ";
- WriteAsOperand(O, C, false, false, &M);
- O << "\n";
+ O << name << ":\t\t\t\t// " << *C << "\n";
EmitGlobalConstant(C);
}
}
}
O << "\n\n";
- AsmPrinter::doFinalization(M);
- return false; // success
+ return AsmPrinter::doFinalization(M);
}
/// createIA64CodePrinterPass - Returns a pass that prints the IA64
///
FunctionPass *llvm::createIA64CodePrinterPass(std::ostream &o,
IA64TargetMachine &tm) {
- IA64TargetAsmInfo *TAI = new IA64TargetAsmInfo();
- return new IA64AsmPrinter(o, tm, TAI);
+ return new IA64AsmPrinter(o, tm, tm.getTargetAsmInfo());
}