//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
+// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
void printPredicateOperand(const MachineInstr *MI, int opNum);
+ void printSBitModifierOperand(const MachineInstr *MI, int opNum);
void printPCLabel(const MachineInstr *MI, int opNum);
void printRegisterList(const MachineInstr *MI, int opNum);
void printCPInstOperand(const MachineInstr *MI, int opNum,
Name += ACPV->getSymbol();
if (ACPV->isNonLazyPointer()) {
GVNonLazyPtrs.insert(Name);
- O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+ printSuffixedName(Name, "$non_lazy_ptr");
} else if (ACPV->isStub()) {
FnStubs.insert(Name);
- O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ printSuffixedName(Name, "$stub");
} else
O << Name;
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
}
void getAnalysisUsage(AnalysisUsage &AU) const {
+ AsmPrinter::getAnalysisUsage(AU);
AU.setPreservesAll();
AU.addRequired<MachineModuleInfo>();
}
// Emit pre-function debug information.
DW.BeginFunction(&MF);
+ if (Subtarget->isTargetDarwin()) {
+ // If the function is empty, then we need to emit *something*. Otherwise,
+ // the function's label might be associated with something that it wasn't
+ // meant to be associated with. We emit a noop in this situation.
+ MachineFunction::iterator I = MF.begin();
+
+ if (++I == MF.end() && MF.front().empty())
+ O << "\tnop\n";
+ }
+
// Print out code for the function.
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
I != E; ++I) {
// Print a label for the basic block.
if (I != MF.begin()) {
- printBasicBlockLabel(I, true);
+ printBasicBlockLabel(I, true, true);
O << '\n';
}
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
case MachineOperand::MO_Register:
- if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
- O << TM.getRegisterInfo()->get(MO.getReg()).Name;
+ if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
else
assert(0 && "not implemented");
break;
if (!Modifier || strcmp(Modifier, "no_hash") != 0)
O << "#";
- O << (int)MO.getImmedValue();
+ O << (int)MO.getImm();
break;
}
case MachineOperand::MO_MachineBasicBlock:
- printBasicBlockLabel(MO.getMachineBasicBlock());
+ printBasicBlockLabel(MO.getMBB());
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
GV->hasLinkOnceLinkage());
if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
- O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ printSuffixedName(Name, "$stub");
FnStubs.insert(Name);
} else
O << Name;
Name += MO.getSymbolName();
if (isCallOp && Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
- O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+ printSuffixedName(Name, "$stub");
FnStubs.insert(Name);
} else
O << Name;
}
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << MO.getConstantPoolIndex();
+ << '_' << MO.getIndex();
break;
case MachineOperand::MO_JumpTableIndex:
O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getJumpTableIndex();
+ << '_' << MO.getIndex();
break;
default:
O << "<unknown operand type>"; abort (); break;
void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImmediate() && "Not a valid so_imm value!");
- printSOImm(O, MO.getImmedValue(), TAI);
+ printSOImm(O, MO.getImm(), TAI);
}
/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
const MachineOperand &MO = MI->getOperand(OpNum);
assert(MO.isImmediate() && "Not a valid so_imm value!");
- unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue());
- unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue());
+ unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
+ unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
- O << "\n\torr ";
+ O << "\n\torr";
+ printPredicateOperand(MI, 2);
+ O << " ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 0);
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
- assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
- O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+ O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
// Print the shift opc.
O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue()))
+ << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
<< " ";
if (MO2.getReg()) {
- assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
- O << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+ assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
+ O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
} else {
O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
return;
}
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (!MO2.getReg()) {
if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
O << ", "
<< (char)ARM_AM::getAM2Op(MO3.getImm())
- << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+ << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue()))
+ << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
<< " #" << ShImm;
O << "]";
}
}
O << (char)ARM_AM::getAM2Op(MO2.getImm())
- << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue()))
+ << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
<< " #" << ShImm;
}
const MachineOperand &MO2 = MI->getOperand(Op+1);
const MachineOperand &MO3 = MI->getOperand(Op+2);
- assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (MO2.getReg()) {
O << ", "
<< (char)ARM_AM::getAM3Op(MO3.getImm())
- << TM.getRegisterInfo()->get(MO2.getReg()).Name
+ << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
<< "]";
return;
}
if (MO1.getReg()) {
O << (char)ARM_AM::getAM3Op(MO2.getImm())
- << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
return;
}
return;
}
- assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+ assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
if (Modifier && strcmp(Modifier, "submode") == 0) {
ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
return;
} else if (Modifier && strcmp(Modifier, "base") == 0) {
// Used for FSTM{D|S} and LSTM{D|S} operations.
- O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (ARM_AM::getAM5WBFlag(MO2.getImm()))
O << "!";
return;
}
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
O << ", #"
}
const MachineOperand &MO1 = MI->getOperand(Op);
- assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
- O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]";
+ assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+ O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
}
void
ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
- O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]";
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
+ O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
}
void
return;
}
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (MO3.getReg())
- O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).Name;
+ O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
else if (unsigned ImmOffs = MO2.getImm()) {
O << ", #" << ImmOffs;
if (Scale > 1)
void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
const MachineOperand &MO1 = MI->getOperand(Op);
const MachineOperand &MO2 = MI->getOperand(Op+1);
- O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
if (unsigned ImmOffs = MO2.getImm())
O << ", #" << ImmOffs << " * 4";
O << "]";
}
void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
- ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImmedValue();
+ ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
if (CC != ARMCC::AL)
O << ARMCondCodeToString(CC);
}
+void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
+ unsigned Reg = MI->getOperand(opNum).getReg();
+ if (Reg) {
+ assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
+ O << 's';
+ }
+}
+
void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
- int Id = (int)MI->getOperand(opNum).getImmedValue();
+ int Id = (int)MI->getOperand(opNum).getImm();
O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
}
<< '_' << ID << ":\n";
} else {
assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
- unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex();
+ unsigned CPI = MI->getOperand(OpNo).getIndex();
const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun?
MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
const MachineOperand &MO1 = MI->getOperand(OpNo);
const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
- unsigned JTI = MO1.getJumpTableIndex();
+ unsigned JTI = MO1.getIndex();
O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImmedValue() << ":\n";
+ << '_' << JTI << '_' << MO2.getImm() << ":\n";
const char *JTEntryDirective = TAI->getJumpTableDirective();
if (!JTEntryDirective)
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
MachineBasicBlock *MBB = JTBBs[i];
if (UseSet && JTSets.insert(MBB).second)
- printSetLabel(JTI, MO2.getImmedValue(), MBB);
+ printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
O << JTEntryDirective << ' ';
if (UseSet)
O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImmedValue()
+ << '_' << JTI << '_' << MO2.getImm()
<< "_set_" << MBB->getNumber();
else if (TM.getRelocationModel() == Reloc::PIC_) {
- printBasicBlockLabel(MBB, false, false);
+ printBasicBlockLabel(MBB, false, false, false);
// If the arch uses custom Jump Table directives, don't calc relative to JT
if (!TAI->getJumpTableDirective())
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
- << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
+ << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
} else
- printBasicBlockLabel(MBB, false, false);
+ printBasicBlockLabel(MBB, false, false, false);
if (i != e-1)
O << '\n';
}
case ARM::tPICADD:
break;
default:
- O << "\t";
break;
}
}}
// Emit initial debug information.
DW.BeginModule(&M);
- return AsmPrinter::doInitialization(M);
+ bool Result = AsmPrinter::doInitialization(M);
+
+ // Darwin wants symbols to be quoted if they have complex names.
+ if (Subtarget->isTargetDarwin())
+ Mang->setUseQuotes(true);
+
+ return Result;
+}
+
+/// PrintUnmangledNameSafely - Print out the printable characters in the name.
+/// Don't print things like \n or \0.
+static void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
+ for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
+ Name != E; ++Name)
+ if (isprint(*Name))
+ OS << *Name;
}
bool ARMAsmPrinter::doFinalization(Module &M) {
std::string name = Mang->getValueName(I);
Constant *C = I->getInitializer();
const Type *Type = C->getType();
- unsigned Size = TD->getTypeSize(Type);
+ unsigned Size = TD->getABITypeSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(I);
const char *VisibilityDirective = NULL;
if (Subtarget->isTargetELF())
O << "\t.type " << name << ",%object\n";
- if (C->isNullValue()) {
+ if (C->isNullValue() && !I->hasSection() && !I->isThreadLocal()) {
if (I->hasExternalLinkage()) {
if (const char *Directive = TAI->getZeroFillDirective()) {
O << "\t.globl\t" << name << "\n";
- O << Directive << "__DATA__, __common, " << name << ", "
+ O << Directive << "__DATA, __common, " << name << ", "
<< Size << ", " << Align << "\n";
continue;
}
}
- if (!I->hasSection() &&
- (I->hasInternalLinkage() || I->hasWeakLinkage() ||
- I->hasLinkOnceLinkage())) {
+ if (I->hasInternalLinkage() || I->hasWeakLinkage() ||
+ I->hasLinkOnceLinkage()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (!NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(TAI->getBSSSection(), I);
if (TAI->getCOMMDirectiveTakesAlignment())
O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
}
- O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
+ O << "\t\t" << TAI->getCommentString() << " ";
+ PrintUnmangledNameSafely(I, O);
+ O << "\n";
continue;
}
}
if (Subtarget->isTargetDarwin()) {
O << "\t.globl " << name << "\n"
<< "\t.weak_definition " << name << "\n";
- SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I);
+ SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
} else {
std::string SectionName("\t.section\t.llvm.linkonce.d." +
name +
std::string SectionName = ".section " + I->getSection();
SectionName += ",\"aw\",%progbits";
SwitchToDataSection(SectionName.c_str());
+ } else if (I->hasSection() && Subtarget->isTargetDarwin()) {
+ // Honor all section names on Darwin; ObjC uses this
+ std::string SectionName = ".section " + I->getSection();
+ SwitchToDataSection(SectionName.c_str());
} else {
if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
}
EmitAlignment(Align, I);
- O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
- << "\n";
+ O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
+ PrintUnmangledNameSafely(I, O);
+ O << "\n";
if (TAI->hasDotTypeDotSizeDirective())
O << "\t.size " << name << ", " << Size << "\n";
// If the initializer is a extern weak symbol, remember to emit the weak
EmitAlignment(2);
O << "\t.code\t32\n";
- O << "L" << *i << "$stub:\n";
+ std::string p = *i;
+ printSuffixedName(p, "$stub");
+ O << ":\n";
O << "\t.indirect_symbol " << *i << "\n";
- O << "\tldr ip, L" << *i << "$slp\n";
+ O << "\tldr ip, ";
+ printSuffixedName(p, "$slp");
+ O << "\n";
if (TM.getRelocationModel() == Reloc::PIC_) {
- O << "L" << *i << "$scv:\n";
+ printSuffixedName(p, "$scv");
+ O << ":\n";
O << "\tadd ip, pc, ip\n";
}
O << "\tldr pc, [ip, #0]\n";
- O << "L" << *i << "$slp:\n";
- if (TM.getRelocationModel() == Reloc::PIC_)
- O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n";
- else
- O << "\t.long\tL" << *i << "$lazy_ptr\n";
+ printSuffixedName(p, "$slp");
+ O << ":\n";
+ O << "\t.long\t";
+ printSuffixedName(p, "$lazy_ptr");
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ O << "-(";
+ printSuffixedName(p, "$scv");
+ O << "+8)\n";
+ } else
+ O << "\n";
SwitchToDataSection(".lazy_symbol_pointer", 0);
- O << "L" << *i << "$lazy_ptr:\n";
+ printSuffixedName(p, "$lazy_ptr");
+ O << ":\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long\tdyld_stub_binding_helper\n";
}
O << "\n";
// Output non-lazy-pointers for external and common global variables.
- if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end())
+ if (!GVNonLazyPtrs.empty())
SwitchToDataSection(".non_lazy_symbol_pointer", 0);
for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
e = GVNonLazyPtrs.end(); i != e; ++i) {
- O << "L" << *i << "$non_lazy_ptr:\n";
+ std::string p = *i;
+ printSuffixedName(p, "$non_lazy_ptr");
+ O << ":\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long\t0\n";
}
DW.EndModule();
}
- AsmPrinter::doFinalization(M);
- return false; // success
+ return AsmPrinter::doFinalization(M);
}