-//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===//
+//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
//
// The LLVM Compiler Infrastructure
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asmprinter"
-#include "PowerPC.h"
-#include "PowerPCTargetMachine.h"
-#include "PowerPCSubtarget.h"
+#include "PPC.h"
+#include "PPCTargetMachine.h"
+#include "PPCSubtarget.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
- struct PowerPCAsmPrinter : public AsmPrinter {
+ struct PPCAsmPrinter : public AsmPrinter {
std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
- PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM)
+ PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
: AsmPrinter(O, TM), LabelNumber(0) {}
/// Unique incrementer for label values for referencing Global values.
return "PowerPC Assembly Printer";
}
- PowerPCTargetMachine &getTM() {
- return static_cast<PowerPCTargetMachine&>(TM);
+ PPCTargetMachine &getTM() {
+ return static_cast<PPCTargetMachine&>(TM);
}
unsigned enumRegToMachineReg(unsigned enumReg) {
MVT::ValueType VT) {
O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
}
+ void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
+ MVT::ValueType VT) {
+ O << (short)MI->getOperand(OpNo).getImmedValue()*4;
+ }
void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
MVT::ValueType VT) {
// Branches can take an immediate operand. This is used by the branch
/// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
/// X
///
- struct DarwinAsmPrinter : public PowerPCAsmPrinter {
+ struct DarwinAsmPrinter : public PPCAsmPrinter {
DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
- : PowerPCAsmPrinter(O, TM) {
+ : PPCAsmPrinter(O, TM) {
CommentString = ";";
GlobalPrefix = "_";
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
/// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
///
- struct AIXAsmPrinter : public PowerPCAsmPrinter {
+ struct AIXAsmPrinter : public PPCAsmPrinter {
/// Map for labels corresponding to global variables
///
std::map<const GlobalVariable*,std::string> GVToLabelMap;
AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
- : PowerPCAsmPrinter(O, TM) {
+ : PPCAsmPrinter(O, TM) {
CommentString = "#";
- GlobalPrefix = "_";
+ GlobalPrefix = ".";
ZeroDirective = "\t.space\t"; // ".space N" emits N zeros.
Data64bitsDirective = 0; // we can't emit a 64-bit unit
AlignmentIsInBytes = false; // Alignment is by power of 2.
}
// Include the auto-generated portion of the assembly writer
-#include "PowerPCGenAsmWriter.inc"
+#include "PPCGenAsmWriter.inc"
-void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
+void PPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
int new_symbol;
}
case MachineOperand::MO_ConstantPoolIndex:
- O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
+ O << "LCPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
return;
case MachineOperand::MO_ExternalSymbol:
/// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
/// the current output stream.
///
-void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
+
// Check for slwi/srwi mnemonics.
if (MI->getOpcode() == PPC::RLWINM) {
bool FoundMnemonic = false;
// Print out labels for the function.
O << "\t.text\n";
- emitAlignment(2);
- O << "\t.globl\t" << CurrentFnName << "\n";
+ emitAlignment(4);
+ if (!MF.getFunction()->hasInternalLinkage())
+ O << "\t.globl\t" << CurrentFnName << "\n";
O << CurrentFnName << ":\n";
// Print out code for the function.
emitAlignment(3);
else
emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
- O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
+ O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
<< *CP[i] << "\n";
emitGlobalConstant(CP[i]);
}
O << ".lcomm " << name << "," << Size << "," << Align;
else
O << ".comm " << name << "," << Size;
- O << "\t\t; ";
- WriteAsOperand(O, I, true, true, &M);
- O << '\n';
+ O << "\t\t; '" << I->getName() << "'\n";
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
}
emitAlignment(Align);
- 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; '" << I->getName() << "'\n";
emitGlobalConstant(C);
}
}
<< "\t.long\t" << *i << '\n';
}
+ // Funny Darwin hack: This flag tells the linker that no global symbols
+ // contain code that falls through to other global symbols (e.g. the obvious
+ // implementation of multiple entry points). If this doesn't occur, the
+ // linker can safely perform dead code stripping. Since LLVM never generates
+ // code that does this, it is always safe to set.
+ O << "\t.subsections_via_symbols\n";
+
AsmPrinter::doFinalization(M);
return false; // success
}
O << "\t.const\n";
O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
<< "\n";
- O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
+ O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
<< *CP[i] << "\n";
emitGlobalConstant(CP[i]);
}
O << '\n';
}
- Mang = new Mangler(M, ".");
+ AsmPrinter::doInitialization(M);
return false; // success
}
<< "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
}
O << "\t\t# ";
- WriteAsOperand(O, I, true, true, &M);
+ WriteAsOperand(O, I, false, true, &M);
O << "\n";
}
O << "_section_.text:\n"
<< "\t.csect .data[RW],3\n"
<< "\t.llong _section_.text\n";
-
- delete Mang;
+ AsmPrinter::doFinalization(M);
return false; // success
}