/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
- virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
- SmallString<128> Str;
- raw_svector_ostream OS(Str);
- EmitMachineConstantPoolValue(MCPV, OS);
- // FIXME: non-assembly streamer support.
- OutStreamer.EmitRawText(OS.str());
- }
-
- void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
- raw_ostream &O) {
- switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
- case 1: O << MAI->getData8bitsDirective(0); break;
- case 2: O << MAI->getData16bitsDirective(0); break;
- case 4: O << MAI->getData32bitsDirective(0); break;
- default: assert(0 && "Unknown CPV size");
- }
-
- ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
-
- if (ACPV->isLSDA()) {
- O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
- } else if (ACPV->isBlockAddress()) {
- O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
- } else if (ACPV->isGlobalValue()) {
- const GlobalValue *GV = ACPV->getGV();
- bool isIndirect = Subtarget->isTargetDarwin() &&
- Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
- if (!isIndirect)
- O << *Mang->getSymbol(GV);
- else {
- // FIXME: Remove this when Darwin transition to @GOT like syntax.
- MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
- O << *Sym;
-
- MachineModuleInfoMachO &MMIMachO =
- MMI->getObjFileInfo<MachineModuleInfoMachO>();
- MachineModuleInfoImpl::StubValueTy &StubSym =
- GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
- MMIMachO.getGVStubEntry(Sym);
- if (StubSym.getPointer() == 0)
- StubSym = MachineModuleInfoImpl::
- StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
- }
- } else {
- assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
- O << *GetExternalSymbolSymbol(ACPV->getSymbol());
- }
-
- if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
- if (ACPV->getPCAdjustment() != 0) {
- O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
- << getFunctionNumber() << "_" << ACPV->getLabelId()
- << "+" << (unsigned)ACPV->getPCAdjustment();
- if (ACPV->mustAddCurrentAddress())
- O << "-.";
- O << ')';
- }
- }
+ virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
};
} // end of anonymous namespace
void ARMAsmPrinter::EmitFunctionEntryLabel() {
if (AFI->isThumbFunction()) {
- OutStreamer.EmitRawText(StringRef("\t.code\t16"));
- if (!Subtarget->isTargetDarwin())
- OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
- else {
- // This needs to emit to a temporary string to get properly quoted
- // MCSymbols when they have spaces in them.
- SmallString<128> Tmp;
- raw_svector_ostream OS(Tmp);
- OS << "\t.thumb_func\t" << *CurrentFnSym;
- OutStreamer.EmitRawText(OS.str());
- }
+ OutStreamer.EmitAssemblerFlag(MCAF_Code16);
+ OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0);
}
OutStreamer.EmitLabel(CurrentFnSym);
return Label;
}
+static MCSymbolRefExpr::VariantKind
+getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
+ switch (Modifier) {
+ default: llvm_unreachable("Unknown modifier!");
+ case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
+ case ARMCP::TLSGD: return MCSymbolRefExpr::VK_ARM_TLSGD;
+ case ARMCP::TPOFF: return MCSymbolRefExpr::VK_ARM_TPOFF;
+ case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
+ case ARMCP::GOT: return MCSymbolRefExpr::VK_ARM_GOT;
+ case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_ARM_GOTOFF;
+ }
+ return MCSymbolRefExpr::VK_None;
+}
+
+void ARMAsmPrinter::
+EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
+ int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
+
+ ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
+
+ MCSymbol *MCSym;
+ if (ACPV->isLSDA()) {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
+ MCSym = OutContext.GetOrCreateSymbol(OS.str());
+ } else if (ACPV->isBlockAddress()) {
+ MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
+ } else if (ACPV->isGlobalValue()) {
+ const GlobalValue *GV = ACPV->getGV();
+ bool isIndirect = Subtarget->isTargetDarwin() &&
+ Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
+ if (!isIndirect)
+ MCSym = Mang->getSymbol(GV);
+ else {
+ // FIXME: Remove this when Darwin transition to @GOT like syntax.
+ MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
+
+ MachineModuleInfoMachO &MMIMachO =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
+ MachineModuleInfoImpl::StubValueTy &StubSym =
+ GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
+ MMIMachO.getGVStubEntry(MCSym);
+ if (StubSym.getPointer() == 0)
+ StubSym = MachineModuleInfoImpl::
+ StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
+ }
+ } else {
+ assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
+ MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
+ }
+
+ // Create an MCSymbol for the reference.
+ const MCExpr *Expr =
+ MCSymbolRefExpr::Create(MCSym, getModifierVariantKind(ACPV->getModifier()),
+ OutContext);
+
+ if (ACPV->getPCAdjustment()) {
+ MCSymbol *PCLabel = getPICLabel(MAI->getPrivateGlobalPrefix(),
+ getFunctionNumber(),
+ ACPV->getLabelId(),
+ OutContext);
+ const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, OutContext);
+ PCRelExpr =
+ MCBinaryExpr::CreateAdd(PCRelExpr,
+ MCConstantExpr::Create(ACPV->getPCAdjustment(),
+ OutContext),
+ OutContext);
+ if (ACPV->mustAddCurrentAddress()) {
+ // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
+ // label, so just emit a local label end reference that instead.
+ MCSymbol *DotSym = OutContext.CreateTempSymbol();
+ OutStreamer.EmitLabel(DotSym);
+ const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
+ PCRelExpr = MCBinaryExpr::CreateSub(PCRelExpr, DotExpr, OutContext);
+ }
+ Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, OutContext);
+ }
+ OutStreamer.EmitValue(Expr, Size);
+}
+
void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
int OpNum = 1;