//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/Statistic.h"
///
void printRegister(const MachineOperand &MO, bool R0AsZero) {
unsigned RegNo = MO.getReg();
- assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
+ assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
// If we should use 0 for R0.
if (R0AsZero && RegNo == PPC::R0) {
if (MO.isRegister()) {
printRegister(MO, false);
} else if (MO.isImmediate()) {
- O << MO.getImmedValue();
+ O << MO.getImm();
} else {
printOp(MO);
}
void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
- char value = MI->getOperand(OpNo).getImmedValue();
+ char value = MI->getOperand(OpNo).getImm();
value = (value << (32-5)) >> (32-5);
O << (int)value;
}
void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
- unsigned char value = MI->getOperand(OpNo).getImmedValue();
+ unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 31 && "Invalid u5imm argument!");
O << (unsigned int)value;
}
void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
- unsigned char value = MI->getOperand(OpNo).getImmedValue();
+ unsigned char value = MI->getOperand(OpNo).getImm();
assert(value <= 63 && "Invalid u6imm argument!");
O << (unsigned int)value;
}
void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
- O << (short)MI->getOperand(OpNo).getImmedValue();
+ O << (short)MI->getOperand(OpNo).getImm();
}
void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
- O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
+ O << (unsigned short)MI->getOperand(OpNo).getImm();
}
void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
if (MI->getOperand(OpNo).isImmediate()) {
- O << (short)(MI->getOperand(OpNo).getImmedValue()*4);
+ O << (short)(MI->getOperand(OpNo).getImm()*4);
} else {
O << "lo16(";
printOp(MI->getOperand(OpNo));
// Branches can take an immediate operand. This is used by the branch
// selection pass to print $+8, an eight byte displacement from the PC.
if (MI->getOperand(OpNo).isImmediate()) {
- O << "$+" << MI->getOperand(OpNo).getImmedValue()*4;
+ O << "$+" << MI->getOperand(OpNo).getImm()*4;
} else {
printOp(MI->getOperand(OpNo));
}
printOp(MI->getOperand(OpNo));
}
void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
- O << (int)MI->getOperand(OpNo).getImmedValue()*4;
+ O << (int)MI->getOperand(OpNo).getImm()*4;
}
void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
O << "\"L" << getFunctionNumber() << "$pb\"\n";
return;
case MachineOperand::MO_MachineBasicBlock:
- printBasicBlockLabel(MO.getMachineBasicBlock());
+ printBasicBlockLabel(MO.getMBB());
return;
case MachineOperand::MO_JumpTableIndex:
O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << MO.getJumpTableIndex();
+ << '_' << MO.getIndex();
// FIXME: PIC relocation model
return;
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
- << '_' << MO.getConstantPoolIndex();
+ << '_' << MO.getIndex();
return;
case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
// Check for slwi/srwi mnemonics.
if (MI->getOpcode() == PPC::RLWINM) {
bool FoundMnemonic = false;
- unsigned char SH = MI->getOperand(2).getImmedValue();
- unsigned char MB = MI->getOperand(3).getImmedValue();
- unsigned char ME = MI->getOperand(4).getImmedValue();
+ unsigned char SH = MI->getOperand(2).getImm();
+ unsigned char MB = MI->getOperand(3).getImm();
+ unsigned char ME = MI->getOperand(4).getImm();
if (SH <= 31 && MB == 0 && ME == (31-SH)) {
- O << "slwi "; FoundMnemonic = true;
+ O << "\tslwi "; FoundMnemonic = true;
}
if (SH <= 31 && MB == (32-SH) && ME == 31) {
- O << "srwi "; FoundMnemonic = true;
+ O << "\tsrwi "; FoundMnemonic = true;
SH = 32-SH;
}
if (FoundMnemonic) {
}
} else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
- O << "mr ";
+ O << "\tmr ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
return;
}
} else if (MI->getOpcode() == PPC::RLDICR) {
- unsigned char SH = MI->getOperand(2).getImmedValue();
- unsigned char ME = MI->getOperand(3).getImmedValue();
+ unsigned char SH = MI->getOperand(2).getImm();
+ unsigned char ME = MI->getOperand(3).getImm();
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
- O << "sldi ";
+ O << "\tsldi ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
II != E; ++II) {
// Print the assembly for the instruction.
- O << "\t";
printMachineInstruction(II);
}
}
case Function::InternalLinkage: return TAI->getTextSection();
case Function::WeakLinkage:
case Function::LinkOnceLinkage:
- return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
+ return "\t.section __TEXT,__textcoal_nt,coalesced,pure_instructions";
}
}
// Emit pre-function debug information.
DW.BeginFunction(&MF);
+ // 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) {
printBasicBlockLabel(I, true);
O << '\n';
}
- for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
- II != E; ++II) {
+ for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+ II != IE; ++II) {
// Print the assembly for the instruction.
- O << "\t";
printMachineInstruction(II);
}
}
bool DarwinAsmPrinter::doInitialization(Module &M) {
static const char *CPUDirectives[] = {
+ "",
"ppc",
"ppc601",
"ppc602",
// Prime text sections so they are adjacent. This reduces the likelihood a
// large data or debug section causes a branch to exceed 16M limit.
- SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced,"
+ SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced,"
"pure_instructions");
if (TM.getRelocationModel() == Reloc::PIC_) {
- SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+ SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
"pure_instructions,32");
} else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
- SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+ SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
"pure_instructions,16");
}
SwitchToTextSection(TAI->getTextSection());
} else {
SwitchToDataSection("\t.data", I);
O << ".comm " << name << "," << Size;
+ // Darwin 9 and above support aligned common data.
+ if (Subtarget.isDarwin9())
+ O << "," << Align;
}
O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n";
} else {
case GlobalValue::WeakLinkage:
O << "\t.globl " << name << '\n'
<< "\t.weak_definition " << name << '\n';
- SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
+ SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
break;
}
}
-
- if (!I->isConstant())
+ if (I->hasSection()) {
+ // Honor all section names on Darwin; ObjC uses this
+ std::string SectionName = ".section " + I->getSection();
+ SwitchToDataSection(SectionName.c_str());
+ } else if (!I->isConstant())
SwitchToDataSection(TAI->getDataSection(), I);
else {
// Read-only data.
if (TM.getRelocationModel() == Reloc::PIC_) {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) {
- SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+ SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
"pure_instructions,32");
EmitAlignment(4);
O << "L" << *i << "$stub:\n";
} else {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) {
- SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+ SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
"pure_instructions,16");
EmitAlignment(4);
O << "L" << *i << "$stub:\n";